From f7a68503711c173abe8b9ca3b52d9511715f508f Mon Sep 17 00:00:00 2001 From: WaitheraMbugua Date: Thu, 16 Aug 2018 00:27:46 +0300 Subject: [PATCH 1/7] [Chore #159751938] Virtual Environment setup --- Include/Python-ast.h | 637 ++ Include/Python.h | 140 + Include/abstract.h | 1109 +++ Include/accu.h | 37 + Include/asdl.h | 46 + Include/ast.h | 29 + Include/bitset.h | 32 + Include/bltinmodule.h | 14 + Include/boolobject.h | 34 + Include/bytearrayobject.h | 62 + Include/bytes_methods.h | 69 + Include/bytesobject.h | 224 + Include/cellobject.h | 29 + Include/ceval.h | 237 + Include/classobject.h | 58 + Include/code.h | 157 + Include/codecs.h | 240 + Include/compile.h | 93 + Include/complexobject.h | 69 + Include/context.h | 86 + Include/datetime.h | 273 + Include/descrobject.h | 110 + Include/dictobject.h | 179 + Include/dtoa.h | 19 + Include/dynamic_annotations.h | 499 + Include/enumobject.h | 17 + Include/errcode.h | 38 + Include/eval.h | 37 + Include/fileobject.h | 55 + Include/fileutils.h | 177 + Include/floatobject.h | 130 + Include/frameobject.h | 93 + Include/funcobject.h | 103 + Include/genobject.h | 105 + Include/graminit.h | 89 + Include/grammar.h | 94 + Include/import.h | 154 + Include/intrcheck.h | 33 + Include/iterobject.h | 25 + Include/listobject.h | 81 + Include/longintrepr.h | 99 + Include/longobject.h | 220 + Include/marshal.h | 28 + Include/memoryobject.h | 72 + Include/metagrammar.h | 18 + Include/methodobject.h | 135 + Include/modsupport.h | 229 + Include/moduleobject.h | 89 + Include/namespaceobject.h | 19 + Include/node.h | 44 + Include/object.h | 1104 +++ Include/objimpl.h | 370 + Include/odictobject.h | 43 + Include/opcode.h | 147 + Include/osdefs.h | 47 + Include/osmodule.h | 17 + Include/parsetok.h | 108 + Include/patchlevel.h | 35 + Include/pgen.h | 18 + Include/pgenheaders.h | 43 + Include/py_curses.h | 159 + Include/pyarena.h | 64 + Include/pyatomic.h | 535 ++ Include/pycapsule.h | 59 + Include/pyconfig.h | 693 ++ Include/pyctype.h | 33 + Include/pydebug.h | 40 + Include/pydtrace.h | 57 + Include/pyerrors.h | 504 + Include/pyexpat.h | 53 + Include/pyfpe.h | 12 + Include/pyhash.h | 145 + Include/pylifecycle.h | 214 + Include/pymacconfig.h | 102 + Include/pymacro.h | 100 + Include/pymath.h | 230 + Include/pymem.h | 244 + Include/pyport.h | 793 ++ Include/pystate.h | 452 + Include/pystrcmp.h | 23 + Include/pystrhex.h | 19 + Include/pystrtod.h | 45 + Include/pythonrun.h | 181 + Include/pythread.h | 155 + Include/pytime.h | 246 + Include/rangeobject.h | 27 + Include/setobject.h | 108 + Include/sliceobject.h | 63 + Include/structmember.h | 74 + Include/structseq.h | 49 + Include/symtable.h | 118 + Include/sysmodule.h | 48 + Include/token.h | 92 + Include/traceback.h | 119 + Include/tupleobject.h | 73 + Include/typeslots.h | 85 + Include/ucnhash.h | 36 + Include/unicodeobject.h | 2334 +++++ Include/warnings.h | 67 + Include/weakrefobject.h | 86 + Lib/__future__.py | 146 + Lib/__pycache__/__future__.cpython-37.pyc | Bin 0 -> 4146 bytes Lib/__pycache__/_bootlocale.cpython-37.pyc | Bin 0 -> 1263 bytes .../_collections_abc.cpython-37.pyc | Bin 0 -> 28956 bytes Lib/__pycache__/_weakrefset.cpython-37.pyc | Bin 0 -> 7476 bytes Lib/__pycache__/abc.cpython-37.pyc | Bin 0 -> 6465 bytes Lib/__pycache__/base64.cpython-37.pyc | Bin 0 -> 17073 bytes Lib/__pycache__/bisect.cpython-37.pyc | Bin 0 -> 2712 bytes Lib/__pycache__/codecs.cpython-37.pyc | Bin 0 -> 33912 bytes Lib/__pycache__/copy.cpython-37.pyc | Bin 0 -> 7115 bytes Lib/__pycache__/copyreg.cpython-37.pyc | Bin 0 -> 4258 bytes Lib/__pycache__/enum.cpython-37.pyc | Bin 0 -> 23761 bytes Lib/__pycache__/fnmatch.cpython-37.pyc | Bin 0 -> 3351 bytes Lib/__pycache__/functools.cpython-37.pyc | Bin 0 -> 23828 bytes Lib/__pycache__/genericpath.cpython-37.pyc | Bin 0 -> 3762 bytes Lib/__pycache__/hashlib.cpython-37.pyc | Bin 0 -> 6549 bytes Lib/__pycache__/heapq.cpython-37.pyc | Bin 0 -> 14376 bytes Lib/__pycache__/hmac.cpython-37.pyc | Bin 0 -> 6127 bytes Lib/__pycache__/imp.cpython-37.pyc | Bin 0 -> 9720 bytes Lib/__pycache__/io.cpython-37.pyc | Bin 0 -> 3423 bytes Lib/__pycache__/keyword.cpython-37.pyc | Bin 0 -> 1823 bytes Lib/__pycache__/linecache.cpython-37.pyc | Bin 0 -> 3803 bytes Lib/__pycache__/locale.cpython-37.pyc | Bin 0 -> 34569 bytes Lib/__pycache__/ntpath.cpython-37.pyc | Bin 0 -> 12933 bytes Lib/__pycache__/operator.cpython-37.pyc | Bin 0 -> 13914 bytes Lib/__pycache__/os.cpython-37.pyc | Bin 0 -> 29707 bytes Lib/__pycache__/posixpath.cpython-37.pyc | Bin 0 -> 10410 bytes Lib/__pycache__/random.cpython-37.pyc | Bin 0 -> 19370 bytes Lib/__pycache__/re.cpython-37.pyc | Bin 0 -> 13818 bytes Lib/__pycache__/reprlib.cpython-37.pyc | Bin 0 -> 5364 bytes Lib/__pycache__/shutil.cpython-37.pyc | Bin 0 -> 30559 bytes Lib/__pycache__/site.cpython-37.pyc | Bin 0 -> 20642 bytes Lib/__pycache__/sre_compile.cpython-37.pyc | Bin 0 -> 15217 bytes Lib/__pycache__/sre_constants.cpython-37.pyc | Bin 0 -> 6305 bytes Lib/__pycache__/sre_parse.cpython-37.pyc | Bin 0 -> 21371 bytes Lib/__pycache__/stat.cpython-37.pyc | Bin 0 -> 3887 bytes Lib/__pycache__/struct.cpython-37.pyc | Bin 0 -> 348 bytes Lib/__pycache__/tarfile.cpython-37.pyc | Bin 0 -> 61799 bytes Lib/__pycache__/tempfile.cpython-37.pyc | Bin 0 -> 22159 bytes Lib/__pycache__/token.cpython-37.pyc | Bin 0 -> 3613 bytes Lib/__pycache__/tokenize.cpython-37.pyc | Bin 0 -> 17744 bytes Lib/__pycache__/types.cpython-37.pyc | Bin 0 -> 8988 bytes Lib/__pycache__/warnings.cpython-37.pyc | Bin 0 -> 13780 bytes Lib/__pycache__/weakref.cpython-37.pyc | Bin 0 -> 19124 bytes Lib/_bootlocale.py | 46 + Lib/_collections_abc.py | 1011 ++ Lib/_dummy_thread.py | 163 + Lib/_weakrefset.py | 196 + Lib/abc.py | 170 + Lib/base64.py | 602 ++ Lib/bisect.py | 92 + Lib/codecs.py | 1114 +++ Lib/collections/__init__.py | 1279 +++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 46633 bytes .../__pycache__/abc.cpython-37.pyc | Bin 0 -> 228 bytes Lib/collections/abc.py | 2 + Lib/copy.py | 313 + Lib/copyreg.py | 206 + Lib/distutils/__init__.py | 101 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2845 bytes Lib/distutils/distutils.cfg | 6 + Lib/encodings/__init__.py | 170 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3970 bytes .../__pycache__/aliases.cpython-37.pyc | Bin 0 -> 6319 bytes .../__pycache__/cp1252.cpython-37.pyc | Bin 0 -> 2479 bytes .../__pycache__/cp437.cpython-37.pyc | Bin 0 -> 7866 bytes Lib/encodings/__pycache__/idna.cpython-37.pyc | Bin 0 -> 5747 bytes .../__pycache__/latin_1.cpython-37.pyc | Bin 0 -> 1919 bytes .../__pycache__/utf_16_be.cpython-37.pyc | Bin 0 -> 1657 bytes .../__pycache__/utf_16_le.cpython-37.pyc | Bin 0 -> 1657 bytes .../__pycache__/utf_8.cpython-37.pyc | Bin 0 -> 1637 bytes Lib/encodings/aliases.py | 550 ++ Lib/encodings/ascii.py | 50 + Lib/encodings/base64_codec.py | 55 + Lib/encodings/big5.py | 39 + Lib/encodings/big5hkscs.py | 39 + Lib/encodings/bz2_codec.py | 78 + Lib/encodings/charmap.py | 69 + Lib/encodings/cp037.py | 307 + Lib/encodings/cp1006.py | 307 + Lib/encodings/cp1026.py | 307 + Lib/encodings/cp1125.py | 698 ++ Lib/encodings/cp1140.py | 307 + Lib/encodings/cp1250.py | 307 + Lib/encodings/cp1251.py | 307 + Lib/encodings/cp1252.py | 307 + Lib/encodings/cp1253.py | 307 + Lib/encodings/cp1254.py | 307 + Lib/encodings/cp1255.py | 307 + Lib/encodings/cp1256.py | 307 + Lib/encodings/cp1257.py | 307 + Lib/encodings/cp1258.py | 307 + Lib/encodings/cp273.py | 307 + Lib/encodings/cp424.py | 307 + Lib/encodings/cp437.py | 698 ++ Lib/encodings/cp500.py | 307 + Lib/encodings/cp65001.py | 43 + Lib/encodings/cp720.py | 309 + Lib/encodings/cp737.py | 698 ++ Lib/encodings/cp775.py | 697 ++ Lib/encodings/cp850.py | 698 ++ Lib/encodings/cp852.py | 698 ++ Lib/encodings/cp855.py | 698 ++ Lib/encodings/cp856.py | 307 + Lib/encodings/cp857.py | 694 ++ Lib/encodings/cp858.py | 698 ++ Lib/encodings/cp860.py | 698 ++ Lib/encodings/cp861.py | 698 ++ Lib/encodings/cp862.py | 698 ++ Lib/encodings/cp863.py | 698 ++ Lib/encodings/cp864.py | 690 ++ Lib/encodings/cp865.py | 698 ++ Lib/encodings/cp866.py | 698 ++ Lib/encodings/cp869.py | 689 ++ Lib/encodings/cp874.py | 307 + Lib/encodings/cp875.py | 307 + Lib/encodings/cp932.py | 39 + Lib/encodings/cp949.py | 39 + Lib/encodings/cp950.py | 39 + Lib/encodings/euc_jis_2004.py | 39 + Lib/encodings/euc_jisx0213.py | 39 + Lib/encodings/euc_jp.py | 39 + Lib/encodings/euc_kr.py | 39 + Lib/encodings/gb18030.py | 39 + Lib/encodings/gb2312.py | 39 + Lib/encodings/gbk.py | 39 + Lib/encodings/hex_codec.py | 55 + Lib/encodings/hp_roman8.py | 314 + Lib/encodings/hz.py | 39 + Lib/encodings/idna.py | 309 + Lib/encodings/iso2022_jp.py | 39 + Lib/encodings/iso2022_jp_1.py | 39 + Lib/encodings/iso2022_jp_2.py | 39 + Lib/encodings/iso2022_jp_2004.py | 39 + Lib/encodings/iso2022_jp_3.py | 39 + Lib/encodings/iso2022_jp_ext.py | 39 + Lib/encodings/iso2022_kr.py | 39 + Lib/encodings/iso8859_1.py | 307 + Lib/encodings/iso8859_10.py | 307 + Lib/encodings/iso8859_11.py | 307 + Lib/encodings/iso8859_13.py | 307 + Lib/encodings/iso8859_14.py | 307 + Lib/encodings/iso8859_15.py | 307 + Lib/encodings/iso8859_16.py | 307 + Lib/encodings/iso8859_2.py | 307 + Lib/encodings/iso8859_3.py | 307 + Lib/encodings/iso8859_4.py | 307 + Lib/encodings/iso8859_5.py | 307 + Lib/encodings/iso8859_6.py | 307 + Lib/encodings/iso8859_7.py | 307 + Lib/encodings/iso8859_8.py | 307 + Lib/encodings/iso8859_9.py | 307 + Lib/encodings/johab.py | 39 + Lib/encodings/koi8_r.py | 307 + Lib/encodings/koi8_t.py | 308 + Lib/encodings/koi8_u.py | 307 + Lib/encodings/kz1048.py | 307 + Lib/encodings/latin_1.py | 50 + Lib/encodings/mac_arabic.py | 698 ++ Lib/encodings/mac_centeuro.py | 307 + Lib/encodings/mac_croatian.py | 307 + Lib/encodings/mac_cyrillic.py | 307 + Lib/encodings/mac_farsi.py | 307 + Lib/encodings/mac_greek.py | 307 + Lib/encodings/mac_iceland.py | 307 + Lib/encodings/mac_latin2.py | 312 + Lib/encodings/mac_roman.py | 307 + Lib/encodings/mac_romanian.py | 307 + Lib/encodings/mac_turkish.py | 307 + Lib/encodings/mbcs.py | 47 + Lib/encodings/oem.py | 41 + Lib/encodings/palmos.py | 308 + Lib/encodings/ptcp154.py | 312 + Lib/encodings/punycode.py | 237 + Lib/encodings/quopri_codec.py | 56 + Lib/encodings/raw_unicode_escape.py | 45 + Lib/encodings/rot_13.py | 113 + Lib/encodings/shift_jis.py | 39 + Lib/encodings/shift_jis_2004.py | 39 + Lib/encodings/shift_jisx0213.py | 39 + Lib/encodings/tis_620.py | 307 + Lib/encodings/undefined.py | 49 + Lib/encodings/unicode_escape.py | 45 + Lib/encodings/unicode_internal.py | 45 + Lib/encodings/utf_16.py | 155 + Lib/encodings/utf_16_be.py | 42 + Lib/encodings/utf_16_le.py | 42 + Lib/encodings/utf_32.py | 150 + Lib/encodings/utf_32_be.py | 37 + Lib/encodings/utf_32_le.py | 37 + Lib/encodings/utf_7.py | 38 + Lib/encodings/utf_8.py | 42 + Lib/encodings/utf_8_sig.py | 130 + Lib/encodings/uu_codec.py | 99 + Lib/encodings/zlib_codec.py | 77 + Lib/enum.py | 901 ++ Lib/fnmatch.py | 128 + Lib/functools.py | 828 ++ Lib/genericpath.py | 151 + Lib/hashlib.py | 251 + Lib/heapq.py | 607 ++ Lib/hmac.py | 188 + Lib/imp.py | 346 + Lib/importlib/__init__.py | 176 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3755 bytes Lib/importlib/__pycache__/abc.cpython-37.pyc | Bin 0 -> 13509 bytes .../__pycache__/machinery.cpython-37.pyc | Bin 0 -> 995 bytes Lib/importlib/__pycache__/util.cpython-37.pyc | Bin 0 -> 9379 bytes Lib/importlib/_bootstrap.py | 1164 +++ Lib/importlib/_bootstrap_external.py | 1562 ++++ Lib/importlib/abc.py | 388 + Lib/importlib/machinery.py | 21 + Lib/importlib/resources.py | 343 + Lib/importlib/util.py | 300 + Lib/io.py | 99 + Lib/keyword.py | 96 + Lib/linecache.py | 177 + Lib/locale.py | 1749 ++++ Lib/no-global-site-packages.txt | 0 Lib/ntpath.py | 671 ++ Lib/operator.py | 464 + Lib/orig-prefix.txt | 1 + Lib/os.py | 1078 +++ Lib/posixpath.py | 522 ++ Lib/random.py | 775 ++ Lib/re.py | 366 + Lib/reprlib.py | 161 + Lib/rlcompleter.py | 205 + Lib/shutil.py | 1169 +++ .../Flask-1.0.2.dist-info/INSTALLER | 1 + .../Flask-1.0.2.dist-info/LICENSE.txt | 31 + .../Flask-1.0.2.dist-info/METADATA | 130 + .../Flask-1.0.2.dist-info/RECORD | 48 + Lib/site-packages/Flask-1.0.2.dist-info/WHEEL | 6 + .../Flask-1.0.2.dist-info/entry_points.txt | 3 + .../Flask-1.0.2.dist-info/top_level.txt | 1 + .../DESCRIPTION.rst | 21 + .../Flask_WTF-0.14.2.dist-info/INSTALLER | 1 + .../Flask_WTF-0.14.2.dist-info/LICENSE.txt | 32 + .../Flask_WTF-0.14.2.dist-info/METADATA | 52 + .../Flask_WTF-0.14.2.dist-info/RECORD | 30 + .../Flask_WTF-0.14.2.dist-info/WHEEL | 6 + .../Flask_WTF-0.14.2.dist-info/metadata.json | 1 + .../Flask_WTF-0.14.2.dist-info/top_level.txt | 1 + .../Jinja2-2.10.dist-info/DESCRIPTION.rst | 37 + .../Jinja2-2.10.dist-info/INSTALLER | 1 + .../Jinja2-2.10.dist-info/LICENSE.txt | 31 + .../Jinja2-2.10.dist-info/METADATA | 68 + .../Jinja2-2.10.dist-info/RECORD | 63 + Lib/site-packages/Jinja2-2.10.dist-info/WHEEL | 6 + .../Jinja2-2.10.dist-info/entry_points.txt | 4 + .../Jinja2-2.10.dist-info/metadata.json | 1 + .../Jinja2-2.10.dist-info/top_level.txt | 1 + .../MarkupSafe-1.0.dist-info/INSTALLER | 1 + .../MarkupSafe-1.0.dist-info/LICENSE.txt | 33 + .../MarkupSafe-1.0.dist-info/METADATA | 135 + .../MarkupSafe-1.0.dist-info/RECORD | 15 + .../MarkupSafe-1.0.dist-info/WHEEL | 5 + .../MarkupSafe-1.0.dist-info/top_level.txt | 1 + .../WTForms-2.2.1.dist-info/INSTALLER | 1 + .../WTForms-2.2.1.dist-info/METADATA | 101 + .../WTForms-2.2.1.dist-info/RECORD | 147 + .../WTForms-2.2.1.dist-info/WHEEL | 6 + .../WTForms-2.2.1.dist-info/top_level.txt | 1 + .../Werkzeug-0.14.1.dist-info/DESCRIPTION.rst | 80 + .../Werkzeug-0.14.1.dist-info/INSTALLER | 1 + .../Werkzeug-0.14.1.dist-info/LICENSE.txt | 31 + .../Werkzeug-0.14.1.dist-info/METADATA | 116 + .../Werkzeug-0.14.1.dist-info/RECORD | 97 + .../Werkzeug-0.14.1.dist-info/WHEEL | 6 + .../Werkzeug-0.14.1.dist-info/metadata.json | 1 + .../Werkzeug-0.14.1.dist-info/top_level.txt | 1 + .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 312 bytes .../__pycache__/itsdangerous.cpython-37.pyc | Bin 0 -> 29327 bytes .../__pycache__/pytest.cpython-37.pyc | Bin 0 -> 1758 bytes .../__pycache__/six.cpython-37.pyc | Bin 0 -> 24970 bytes Lib/site-packages/_pytest/__init__.py | 8 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 303 bytes .../__pycache__/_argcomplete.cpython-37.pyc | Bin 0 -> 3932 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 187 bytes .../__pycache__/cacheprovider.cpython-37.pyc | Bin 0 -> 12268 bytes .../__pycache__/capture.cpython-37.pyc | Bin 0 -> 24636 bytes .../_pytest/__pycache__/compat.cpython-37.pyc | Bin 0 -> 11195 bytes .../__pycache__/debugging.cpython-37.pyc | Bin 0 -> 6125 bytes .../__pycache__/deprecated.cpython-37.pyc | Bin 0 -> 3101 bytes .../__pycache__/doctest.cpython-37.pyc | Bin 0 -> 15213 bytes .../__pycache__/experiments.cpython-37.pyc | Bin 0 -> 729 bytes .../__pycache__/fixtures.cpython-37.pyc | Bin 0 -> 38369 bytes .../__pycache__/freeze_support.cpython-37.pyc | Bin 0 -> 1392 bytes .../__pycache__/helpconfig.cpython-37.pyc | Bin 0 -> 6259 bytes .../__pycache__/hookspec.cpython-37.pyc | Bin 0 -> 20135 bytes .../__pycache__/junitxml.cpython-37.pyc | Bin 0 -> 16429 bytes .../__pycache__/logging.cpython-37.pyc | Bin 0 -> 17575 bytes .../_pytest/__pycache__/main.cpython-37.pyc | Bin 0 -> 17380 bytes .../__pycache__/monkeypatch.cpython-37.pyc | Bin 0 -> 9209 bytes .../_pytest/__pycache__/nodes.cpython-37.pyc | Bin 0 -> 13407 bytes .../_pytest/__pycache__/nose.cpython-37.pyc | Bin 0 -> 2437 bytes .../__pycache__/outcomes.cpython-37.pyc | Bin 0 -> 5011 bytes .../__pycache__/pastebin.cpython-37.pyc | Bin 0 -> 3295 bytes .../_pytest/__pycache__/paths.cpython-37.pyc | Bin 0 -> 558 bytes .../__pycache__/pytester.cpython-37.pyc | Bin 0 -> 45935 bytes .../_pytest/__pycache__/python.cpython-37.pyc | Bin 0 -> 42062 bytes .../__pycache__/python_api.cpython-37.pyc | Bin 0 -> 23764 bytes .../__pycache__/recwarn.cpython-37.pyc | Bin 0 -> 8973 bytes .../__pycache__/reports.cpython-37.pyc | Bin 0 -> 5933 bytes .../__pycache__/resultlog.cpython-37.pyc | Bin 0 -> 3671 bytes .../_pytest/__pycache__/runner.cpython-37.pyc | Bin 0 -> 11084 bytes .../__pycache__/setuponly.cpython-37.pyc | Bin 0 -> 2416 bytes .../__pycache__/setupplan.cpython-37.pyc | Bin 0 -> 1018 bytes .../__pycache__/skipping.cpython-37.pyc | Bin 0 -> 7689 bytes .../__pycache__/terminal.cpython-37.pyc | Bin 0 -> 24517 bytes .../_pytest/__pycache__/tmpdir.cpython-37.pyc | Bin 0 -> 4346 bytes .../__pycache__/unittest.cpython-37.pyc | Bin 0 -> 7859 bytes .../__pycache__/warnings.cpython-37.pyc | Bin 0 -> 3107 bytes Lib/site-packages/_pytest/_argcomplete.py | 107 + Lib/site-packages/_pytest/_code/__init__.py | 10 + .../_code/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 604 bytes .../__pycache__/_py2traceback.cpython-37.pyc | Bin 0 -> 2301 bytes .../_code/__pycache__/code.cpython-37.pyc | Bin 0 -> 29740 bytes .../_code/__pycache__/source.cpython-37.pyc | Bin 0 -> 10561 bytes .../_pytest/_code/_py2traceback.py | 89 + Lib/site-packages/_pytest/_code/code.py | 978 ++ Lib/site-packages/_pytest/_code/source.py | 373 + Lib/site-packages/_pytest/_version.py | 4 + .../_pytest/assertion/__init__.py | 151 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 5530 bytes .../__pycache__/rewrite.cpython-37.pyc | Bin 0 -> 27324 bytes .../__pycache__/truncate.cpython-37.pyc | Bin 0 -> 2709 bytes .../assertion/__pycache__/util.cpython-37.pyc | Bin 0 -> 10008 bytes .../_pytest/assertion/rewrite.py | 962 ++ .../_pytest/assertion/truncate.py | 99 + Lib/site-packages/_pytest/assertion/util.py | 338 + Lib/site-packages/_pytest/cacheprovider.py | 358 + Lib/site-packages/_pytest/capture.py | 722 ++ Lib/site-packages/_pytest/compat.py | 383 + Lib/site-packages/_pytest/config/__init__.py | 984 ++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 28643 bytes .../__pycache__/argparsing.cpython-37.pyc | Bin 0 -> 13119 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 639 bytes .../__pycache__/findpaths.cpython-37.pyc | Bin 0 -> 4007 bytes .../_pytest/config/argparsing.py | 392 + .../_pytest/config/exceptions.py | 9 + Lib/site-packages/_pytest/config/findpaths.py | 139 + Lib/site-packages/_pytest/debugging.py | 197 + Lib/site-packages/_pytest/deprecated.py | 77 + Lib/site-packages/_pytest/doctest.py | 511 + Lib/site-packages/_pytest/experiments.py | 13 + Lib/site-packages/_pytest/fixtures.py | 1350 +++ Lib/site-packages/_pytest/freeze_support.py | 45 + Lib/site-packages/_pytest/helpconfig.py | 212 + Lib/site-packages/_pytest/hookspec.py | 577 ++ Lib/site-packages/_pytest/junitxml.py | 564 ++ Lib/site-packages/_pytest/logging.py | 591 ++ Lib/site-packages/_pytest/main.py | 662 ++ Lib/site-packages/_pytest/mark/__init__.py | 174 + .../mark/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4953 bytes .../mark/__pycache__/evaluate.cpython-37.pyc | Bin 0 -> 3524 bytes .../mark/__pycache__/legacy.cpython-37.pyc | Bin 0 -> 3316 bytes .../__pycache__/structures.cpython-37.pyc | Bin 0 -> 15056 bytes Lib/site-packages/_pytest/mark/evaluate.py | 120 + Lib/site-packages/_pytest/mark/legacy.py | 97 + Lib/site-packages/_pytest/mark/structures.py | 454 + Lib/site-packages/_pytest/monkeypatch.py | 282 + Lib/site-packages/_pytest/nodes.py | 431 + Lib/site-packages/_pytest/nose.py | 72 + Lib/site-packages/_pytest/outcomes.py | 158 + Lib/site-packages/_pytest/pastebin.py | 109 + Lib/site-packages/_pytest/paths.py | 13 + Lib/site-packages/_pytest/pytester.py | 1306 +++ Lib/site-packages/_pytest/python.py | 1447 +++ Lib/site-packages/_pytest/python_api.py | 721 ++ Lib/site-packages/_pytest/recwarn.py | 240 + Lib/site-packages/_pytest/reports.py | 196 + Lib/site-packages/_pytest/resultlog.py | 119 + Lib/site-packages/_pytest/runner.py | 383 + Lib/site-packages/_pytest/setuponly.py | 84 + Lib/site-packages/_pytest/setupplan.py | 29 + Lib/site-packages/_pytest/skipping.py | 294 + Lib/site-packages/_pytest/terminal.py | 832 ++ Lib/site-packages/_pytest/tmpdir.py | 131 + Lib/site-packages/_pytest/unittest.py | 251 + Lib/site-packages/_pytest/warnings.py | 111 + .../DESCRIPTION.rst | 104 + .../atomicwrites-1.1.5.dist-info/INSTALLER | 1 + .../atomicwrites-1.1.5.dist-info/METADATA | 114 + .../atomicwrites-1.1.5.dist-info/RECORD | 9 + .../atomicwrites-1.1.5.dist-info/WHEEL | 6 + .../metadata.json | 1 + .../top_level.txt | 1 + Lib/site-packages/atomicwrites/__init__.py | 201 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6099 bytes Lib/site-packages/attr/__init__.py | 57 + .../attr/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1396 bytes .../attr/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 4414 bytes .../attr/__pycache__/_config.cpython-37.pyc | Bin 0 -> 731 bytes .../attr/__pycache__/_funcs.cpython-37.pyc | Bin 0 -> 6799 bytes .../attr/__pycache__/_make.cpython-37.pyc | Bin 0 -> 45852 bytes .../__pycache__/converters.cpython-37.pyc | Bin 0 -> 836 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 1868 bytes .../attr/__pycache__/filters.cpython-37.pyc | Bin 0 -> 1803 bytes .../__pycache__/validators.cpython-37.pyc | Bin 0 -> 5662 bytes Lib/site-packages/attr/_compat.py | 146 + Lib/site-packages/attr/_config.py | 23 + Lib/site-packages/attr/_funcs.py | 212 + Lib/site-packages/attr/_make.py | 1689 ++++ Lib/site-packages/attr/converters.py | 24 + Lib/site-packages/attr/exceptions.py | 48 + Lib/site-packages/attr/filters.py | 52 + Lib/site-packages/attr/validators.py | 166 + .../attrs-18.1.0.dist-info/INSTALLER | 1 + .../attrs-18.1.0.dist-info/LICENSE.txt | 21 + .../attrs-18.1.0.dist-info/METADATA | 261 + .../attrs-18.1.0.dist-info/RECORD | 24 + .../attrs-18.1.0.dist-info/WHEEL | 6 + .../attrs-18.1.0.dist-info/top_level.txt | 1 + .../click-6.7.dist-info/DESCRIPTION.rst | 3 + .../click-6.7.dist-info/INSTALLER | 1 + .../click-6.7.dist-info/METADATA | 16 + Lib/site-packages/click-6.7.dist-info/RECORD | 41 + Lib/site-packages/click-6.7.dist-info/WHEEL | 6 + .../click-6.7.dist-info/metadata.json | 1 + .../click-6.7.dist-info/top_level.txt | 1 + Lib/site-packages/click/__init__.py | 98 + .../click/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2720 bytes .../__pycache__/_bashcomplete.cpython-37.pyc | Bin 0 -> 2370 bytes .../click/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 15429 bytes .../__pycache__/_termui_impl.cpython-37.pyc | Bin 0 -> 12902 bytes .../__pycache__/_textwrap.cpython-37.pyc | Bin 0 -> 1329 bytes .../__pycache__/_unicodefun.cpython-37.pyc | Bin 0 -> 3205 bytes .../__pycache__/_winconsole.cpython-37.pyc | Bin 0 -> 7435 bytes .../click/__pycache__/core.cpython-37.pyc | Bin 0 -> 56558 bytes .../__pycache__/decorators.cpython-37.pyc | Bin 0 -> 11475 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 7731 bytes .../__pycache__/formatting.cpython-37.pyc | Bin 0 -> 8545 bytes .../click/__pycache__/globals.cpython-37.pyc | Bin 0 -> 1877 bytes .../click/__pycache__/parser.cpython-37.pyc | Bin 0 -> 11464 bytes .../click/__pycache__/termui.cpython-37.pyc | Bin 0 -> 18842 bytes .../click/__pycache__/testing.cpython-37.pyc | Bin 0 -> 10236 bytes .../click/__pycache__/types.cpython-37.pyc | Bin 0 -> 17485 bytes .../click/__pycache__/utils.cpython-37.pyc | Bin 0 -> 14098 bytes Lib/site-packages/click/_bashcomplete.py | 83 + Lib/site-packages/click/_compat.py | 648 ++ Lib/site-packages/click/_termui_impl.py | 547 ++ Lib/site-packages/click/_textwrap.py | 38 + Lib/site-packages/click/_unicodefun.py | 118 + Lib/site-packages/click/_winconsole.py | 273 + Lib/site-packages/click/core.py | 1744 ++++ Lib/site-packages/click/decorators.py | 304 + Lib/site-packages/click/exceptions.py | 201 + Lib/site-packages/click/formatting.py | 256 + Lib/site-packages/click/globals.py | 48 + Lib/site-packages/click/parser.py | 426 + Lib/site-packages/click/termui.py | 539 ++ Lib/site-packages/click/testing.py | 322 + Lib/site-packages/click/types.py | 550 ++ Lib/site-packages/click/utils.py | 415 + .../colorama-0.3.9.dist-info/DESCRIPTION.rst | 348 + .../colorama-0.3.9.dist-info/INSTALLER | 1 + .../colorama-0.3.9.dist-info/METADATA | 375 + .../colorama-0.3.9.dist-info/RECORD | 20 + .../colorama-0.3.9.dist-info/WHEEL | 6 + .../colorama-0.3.9.dist-info/metadata.json | 1 + .../colorama-0.3.9.dist-info/pbr.json | 1 + .../colorama-0.3.9.dist-info/top_level.txt | 1 + Lib/site-packages/colorama/__init__.py | 7 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 424 bytes .../colorama/__pycache__/ansi.cpython-37.pyc | Bin 0 -> 3322 bytes .../__pycache__/ansitowin32.cpython-37.pyc | Bin 0 -> 7035 bytes .../__pycache__/initialise.cpython-37.pyc | Bin 0 -> 1643 bytes .../colorama/__pycache__/win32.cpython-37.pyc | Bin 0 -> 3858 bytes .../__pycache__/winterm.cpython-37.pyc | Bin 0 -> 4547 bytes Lib/site-packages/colorama/ansi.py | 102 + Lib/site-packages/colorama/ansitowin32.py | 236 + Lib/site-packages/colorama/initialise.py | 82 + Lib/site-packages/colorama/win32.py | 156 + Lib/site-packages/colorama/winterm.py | 162 + Lib/site-packages/easy_install.py | 5 + Lib/site-packages/flask/__init__.py | 49 + Lib/site-packages/flask/__main__.py | 14 + .../flask/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1829 bytes .../flask/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 456 bytes .../flask/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 3233 bytes .../flask/__pycache__/app.cpython-37.pyc | Bin 0 -> 70879 bytes .../__pycache__/blueprints.cpython-37.pyc | Bin 0 -> 20497 bytes .../flask/__pycache__/cli.cpython-37.pyc | Bin 0 -> 24785 bytes .../flask/__pycache__/config.cpython-37.pyc | Bin 0 -> 9995 bytes .../flask/__pycache__/ctx.cpython-37.pyc | Bin 0 -> 13965 bytes .../__pycache__/debughelpers.cpython-37.pyc | Bin 0 -> 6604 bytes .../flask/__pycache__/globals.cpython-37.pyc | Bin 0 -> 1756 bytes .../flask/__pycache__/helpers.cpython-37.pyc | Bin 0 -> 33019 bytes .../flask/__pycache__/logging.cpython-37.pyc | Bin 0 -> 2385 bytes .../flask/__pycache__/sessions.cpython-37.pyc | Bin 0 -> 12230 bytes .../flask/__pycache__/signals.cpython-37.pyc | Bin 0 -> 2417 bytes .../__pycache__/templating.cpython-37.pyc | Bin 0 -> 4966 bytes .../flask/__pycache__/testing.cpython-37.pyc | Bin 0 -> 7865 bytes .../flask/__pycache__/views.cpython-37.pyc | Bin 0 -> 4779 bytes .../flask/__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 6773 bytes Lib/site-packages/flask/_compat.py | 99 + Lib/site-packages/flask/app.py | 2315 +++++ Lib/site-packages/flask/blueprints.py | 448 + Lib/site-packages/flask/cli.py | 898 ++ Lib/site-packages/flask/config.py | 265 + Lib/site-packages/flask/ctx.py | 457 + Lib/site-packages/flask/debughelpers.py | 168 + Lib/site-packages/flask/globals.py | 61 + Lib/site-packages/flask/helpers.py | 1044 +++ Lib/site-packages/flask/json/__init__.py | 327 + .../json/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 10255 bytes .../flask/json/__pycache__/tag.cpython-37.pyc | Bin 0 -> 11085 bytes Lib/site-packages/flask/json/tag.py | 300 + Lib/site-packages/flask/logging.py | 78 + Lib/site-packages/flask/sessions.py | 385 + Lib/site-packages/flask/signals.py | 57 + Lib/site-packages/flask/templating.py | 150 + Lib/site-packages/flask/testing.py | 250 + Lib/site-packages/flask/views.py | 158 + Lib/site-packages/flask/wrappers.py | 216 + Lib/site-packages/flask_wtf/__init__.py | 19 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 609 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1090 bytes .../flask_wtf/__pycache__/csrf.cpython-37.pyc | Bin 0 -> 11070 bytes .../flask_wtf/__pycache__/file.cpython-37.pyc | Bin 0 -> 3578 bytes .../flask_wtf/__pycache__/form.cpython-37.pyc | Bin 0 -> 5712 bytes .../__pycache__/html5.cpython-37.pyc | Bin 0 -> 496 bytes .../flask_wtf/__pycache__/i18n.cpython-37.pyc | Bin 0 -> 1767 bytes Lib/site-packages/flask_wtf/_compat.py | 35 + Lib/site-packages/flask_wtf/csrf.py | 364 + Lib/site-packages/flask_wtf/file.py | 94 + Lib/site-packages/flask_wtf/form.py | 158 + Lib/site-packages/flask_wtf/html5.py | 13 + Lib/site-packages/flask_wtf/i18n.py | 69 + .../flask_wtf/recaptcha/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 249 bytes .../__pycache__/fields.cpython-37.pyc | Bin 0 -> 790 bytes .../__pycache__/validators.cpython-37.pyc | Bin 0 -> 2362 bytes .../__pycache__/widgets.cpython-37.pyc | Bin 0 -> 1637 bytes .../flask_wtf/recaptcha/fields.py | 17 + .../flask_wtf/recaptcha/validators.py | 77 + .../flask_wtf/recaptcha/widgets.py | 42 + .../itsdangerous-0.24.dist-info/INSTALLER | 1 + .../itsdangerous-0.24.dist-info/METADATA | 16 + .../itsdangerous-0.24.dist-info/RECORD | 7 + .../itsdangerous-0.24.dist-info/WHEEL | 5 + .../itsdangerous-0.24.dist-info/top_level.txt | 1 + Lib/site-packages/itsdangerous.py | 872 ++ Lib/site-packages/jinja2/__init__.py | 83 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2533 bytes .../jinja2/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 3348 bytes .../__pycache__/_identifier.cpython-37.pyc | Bin 0 -> 1846 bytes .../__pycache__/asyncfilters.cpython-37.pyc | Bin 0 -> 4778 bytes .../__pycache__/asyncsupport.cpython-37.pyc | Bin 0 -> 8126 bytes .../jinja2/__pycache__/bccache.cpython-37.pyc | Bin 0 -> 12715 bytes .../__pycache__/compiler.cpython-37.pyc | Bin 0 -> 46844 bytes .../__pycache__/constants.cpython-37.pyc | Bin 0 -> 1709 bytes .../jinja2/__pycache__/debug.cpython-37.pyc | Bin 0 -> 9325 bytes .../__pycache__/defaults.cpython-37.pyc | Bin 0 -> 1459 bytes .../__pycache__/environment.cpython-37.pyc | Bin 0 -> 43254 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 5023 bytes .../jinja2/__pycache__/ext.cpython-37.pyc | Bin 0 -> 20044 bytes .../jinja2/__pycache__/filters.cpython-37.pyc | Bin 0 -> 34389 bytes .../__pycache__/idtracking.cpython-37.pyc | Bin 0 -> 9959 bytes .../jinja2/__pycache__/lexer.cpython-37.pyc | Bin 0 -> 18516 bytes .../jinja2/__pycache__/loaders.cpython-37.pyc | Bin 0 -> 16579 bytes .../jinja2/__pycache__/meta.cpython-37.pyc | Bin 0 -> 3672 bytes .../__pycache__/nativetypes.cpython-37.pyc | Bin 0 -> 5128 bytes .../jinja2/__pycache__/nodes.cpython-37.pyc | Bin 0 -> 36088 bytes .../__pycache__/optimizer.cpython-37.pyc | Bin 0 -> 2039 bytes .../jinja2/__pycache__/parser.cpython-37.pyc | Bin 0 -> 25183 bytes .../jinja2/__pycache__/runtime.cpython-37.pyc | Bin 0 -> 24591 bytes .../jinja2/__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 13994 bytes .../jinja2/__pycache__/tests.cpython-37.pyc | Bin 0 -> 4415 bytes .../jinja2/__pycache__/utils.cpython-37.pyc | Bin 0 -> 20792 bytes .../jinja2/__pycache__/visitor.cpython-37.pyc | Bin 0 -> 3355 bytes Lib/site-packages/jinja2/_compat.py | 99 + Lib/site-packages/jinja2/_identifier.py | 2 + Lib/site-packages/jinja2/asyncfilters.py | 146 + Lib/site-packages/jinja2/asyncsupport.py | 256 + Lib/site-packages/jinja2/bccache.py | 362 + Lib/site-packages/jinja2/compiler.py | 1721 ++++ Lib/site-packages/jinja2/constants.py | 32 + Lib/site-packages/jinja2/debug.py | 372 + Lib/site-packages/jinja2/defaults.py | 56 + Lib/site-packages/jinja2/environment.py | 1276 +++ Lib/site-packages/jinja2/exceptions.py | 146 + Lib/site-packages/jinja2/ext.py | 627 ++ Lib/site-packages/jinja2/filters.py | 1190 +++ Lib/site-packages/jinja2/idtracking.py | 286 + Lib/site-packages/jinja2/lexer.py | 739 ++ Lib/site-packages/jinja2/loaders.py | 481 + Lib/site-packages/jinja2/meta.py | 106 + Lib/site-packages/jinja2/nativetypes.py | 220 + Lib/site-packages/jinja2/nodes.py | 999 ++ Lib/site-packages/jinja2/optimizer.py | 49 + Lib/site-packages/jinja2/parser.py | 903 ++ Lib/site-packages/jinja2/runtime.py | 813 ++ Lib/site-packages/jinja2/sandbox.py | 475 + Lib/site-packages/jinja2/tests.py | 175 + Lib/site-packages/jinja2/utils.py | 647 ++ Lib/site-packages/jinja2/visitor.py | 87 + Lib/site-packages/markupsafe/__init__.py | 305 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 11314 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 799 bytes .../__pycache__/_constants.cpython-37.pyc | Bin 0 -> 4367 bytes .../__pycache__/_native.cpython-37.pyc | Bin 0 -> 1432 bytes Lib/site-packages/markupsafe/_compat.py | 26 + Lib/site-packages/markupsafe/_constants.py | 267 + Lib/site-packages/markupsafe/_native.py | 46 + Lib/site-packages/markupsafe/_speedups.c | 239 + .../more_itertools-4.3.0.dist-info/INSTALLER | 1 + .../more_itertools-4.3.0.dist-info/METADATA | 433 + .../more_itertools-4.3.0.dist-info/RECORD | 17 + .../more_itertools-4.3.0.dist-info/WHEEL | 5 + .../top_level.txt | 1 + Lib/site-packages/more_itertools/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 255 bytes .../__pycache__/more.cpython-37.pyc | Bin 0 -> 67461 bytes .../__pycache__/recipes.cpython-37.pyc | Bin 0 -> 16079 bytes Lib/site-packages/more_itertools/more.py | 2211 +++++ Lib/site-packages/more_itertools/recipes.py | 565 ++ .../more_itertools/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 191 bytes .../__pycache__/test_more.cpython-37.pyc | Bin 0 -> 96300 bytes .../__pycache__/test_recipes.cpython-37.pyc | Bin 0 -> 32307 bytes .../more_itertools/tests/test_more.py | 2074 +++++ .../more_itertools/tests/test_recipes.py | 616 ++ .../pip-18.0.dist-info/INSTALLER | 1 + .../pip-18.0.dist-info/LICENSE.txt | 20 + Lib/site-packages/pip-18.0.dist-info/METADATA | 69 + Lib/site-packages/pip-18.0.dist-info/RECORD | 582 ++ Lib/site-packages/pip-18.0.dist-info/WHEEL | 6 + .../pip-18.0.dist-info/entry_points.txt | 5 + .../pip-18.0.dist-info/top_level.txt | 1 + Lib/site-packages/pip/__init__.py | 1 + Lib/site-packages/pip/__main__.py | 19 + .../pip/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 183 bytes .../pip/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 437 bytes Lib/site-packages/pip/_internal/__init__.py | 310 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 8265 bytes .../__pycache__/basecommand.cpython-37.pyc | Bin 0 -> 6257 bytes .../__pycache__/baseparser.cpython-37.pyc | Bin 0 -> 8284 bytes .../__pycache__/build_env.cpython-37.pyc | Bin 0 -> 4487 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 6817 bytes .../__pycache__/cmdoptions.cpython-37.pyc | Bin 0 -> 12936 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 5479 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 9758 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 20890 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 10727 bytes .../__pycache__/index.cpython-37.pyc | Bin 0 -> 31005 bytes .../__pycache__/locations.cpython-37.pyc | Bin 0 -> 4213 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7244 bytes .../__pycache__/resolve.cpython-37.pyc | Bin 0 -> 8478 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 385 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 20705 bytes .../pip/_internal/basecommand.py | 274 + Lib/site-packages/pip/_internal/baseparser.py | 240 + Lib/site-packages/pip/_internal/build_env.py | 126 + Lib/site-packages/pip/_internal/cache.py | 202 + Lib/site-packages/pip/_internal/cmdoptions.py | 619 ++ .../pip/_internal/commands/__init__.py | 79 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2483 bytes .../commands/__pycache__/check.cpython-37.pyc | Bin 0 -> 1285 bytes .../__pycache__/completion.cpython-37.pyc | Bin 0 -> 3057 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 6405 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 6146 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 2834 bytes .../commands/__pycache__/hash.cpython-37.pyc | Bin 0 -> 2043 bytes .../commands/__pycache__/help.cpython-37.pyc | Bin 0 -> 1179 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 11485 bytes .../commands/__pycache__/list.cpython-37.pyc | Bin 0 -> 8899 bytes .../__pycache__/search.cpython-37.pyc | Bin 0 -> 4279 bytes .../commands/__pycache__/show.cpython-37.pyc | Bin 0 -> 5866 bytes .../__pycache__/uninstall.cpython-37.pyc | Bin 0 -> 2645 bytes .../commands/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 4896 bytes .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 236 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 36 + .../pip/_internal/commands/install.py | 516 ++ .../pip/_internal/commands/list.py | 304 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 77 + .../pip/_internal/commands/wheel.py | 183 + Lib/site-packages/pip/_internal/compat.py | 235 + .../pip/_internal/configuration.py | 380 + Lib/site-packages/pip/_internal/download.py | 921 ++ Lib/site-packages/pip/_internal/exceptions.py | 249 + Lib/site-packages/pip/_internal/index.py | 1127 +++ Lib/site-packages/pip/_internal/locations.py | 194 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 248 bytes .../models/__pycache__/index.cpython-37.pyc | Bin 0 -> 824 bytes .../pip/_internal/models/index.py | 15 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 184 bytes .../__pycache__/check.cpython-37.pyc | Bin 0 -> 3361 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 5881 bytes .../__pycache__/prepare.cpython-37.pyc | Bin 0 -> 9268 bytes .../pip/_internal/operations/check.py | 148 + .../pip/_internal/operations/freeze.py | 253 + .../pip/_internal/operations/prepare.py | 355 + Lib/site-packages/pip/_internal/pep425tags.py | 317 + .../pip/_internal/req/__init__.py | 69 + .../req/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1552 bytes .../req/__pycache__/req_file.cpython-37.pyc | Bin 0 -> 8632 bytes .../__pycache__/req_install.cpython-37.pyc | Bin 0 -> 29450 bytes .../req/__pycache__/req_set.cpython-37.pyc | Bin 0 -> 5666 bytes .../__pycache__/req_tracker.cpython-37.pyc | Bin 0 -> 2876 bytes .../__pycache__/req_uninstall.cpython-37.pyc | Bin 0 -> 12797 bytes .../pip/_internal/req/req_file.py | 338 + .../pip/_internal/req/req_install.py | 1142 +++ .../pip/_internal/req/req_set.py | 161 + .../pip/_internal/req/req_tracker.py | 76 + .../pip/_internal/req/req_uninstall.py | 457 + Lib/site-packages/pip/_internal/resolve.py | 353 + .../pip/_internal/status_codes.py | 8 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 179 bytes .../utils/__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 7894 bytes .../__pycache__/deprecation.cpython-37.pyc | Bin 0 -> 2553 bytes .../utils/__pycache__/encoding.cpython-37.pyc | Bin 0 -> 1115 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 640 bytes .../utils/__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1537 bytes .../utils/__pycache__/hashes.cpython-37.pyc | Bin 0 -> 3314 bytes .../utils/__pycache__/logging.cpython-37.pyc | Bin 0 -> 5341 bytes .../utils/__pycache__/misc.cpython-37.pyc | Bin 0 -> 23102 bytes .../utils/__pycache__/outdated.cpython-37.pyc | Bin 0 -> 3864 bytes .../__pycache__/packaging.cpython-37.pyc | Bin 0 -> 2237 bytes .../setuptools_build.cpython-37.pyc | Bin 0 -> 374 bytes .../utils/__pycache__/temp_dir.cpython-37.pyc | Bin 0 -> 2791 bytes .../utils/__pycache__/typing.cpython-37.pyc | Bin 0 -> 1323 bytes .../utils/__pycache__/ui.cpython-37.pyc | Bin 0 -> 11842 bytes .../pip/_internal/utils/appdirs.py | 258 + .../pip/_internal/utils/deprecation.py | 89 + .../pip/_internal/utils/encoding.py | 33 + .../pip/_internal/utils/filesystem.py | 28 + .../pip/_internal/utils/glibc.py | 84 + .../pip/_internal/utils/hashes.py | 94 + .../pip/_internal/utils/logging.py | 225 + Lib/site-packages/pip/_internal/utils/misc.py | 899 ++ .../pip/_internal/utils/outdated.py | 145 + .../pip/_internal/utils/packaging.py | 70 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 82 + .../pip/_internal/utils/typing.py | 29 + Lib/site-packages/pip/_internal/utils/ui.py | 421 + .../pip/_internal/vcs/__init__.py | 503 + .../vcs/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 15213 bytes .../vcs/__pycache__/bazaar.cpython-37.pyc | Bin 0 -> 3746 bytes .../vcs/__pycache__/git.cpython-37.pyc | Bin 0 -> 8394 bytes .../vcs/__pycache__/mercurial.cpython-37.pyc | Bin 0 -> 3762 bytes .../vcs/__pycache__/subversion.cpython-37.pyc | Bin 0 -> 7200 bytes Lib/site-packages/pip/_internal/vcs/bazaar.py | 110 + Lib/site-packages/pip/_internal/vcs/git.py | 309 + .../pip/_internal/vcs/mercurial.py | 102 + .../pip/_internal/vcs/subversion.py | 254 + Lib/site-packages/pip/_internal/wheel.py | 827 ++ Lib/site-packages/pip/_vendor/__init__.py | 110 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2849 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20596 bytes .../_vendor/__pycache__/distro.cpython-37.pyc | Bin 0 -> 36129 bytes .../__pycache__/ipaddress.cpython-37.pyc | Bin 0 -> 66439 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 202081 bytes .../__pycache__/retrying.cpython-37.pyc | Bin 0 -> 8077 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24982 bytes Lib/site-packages/pip/_vendor/appdirs.py | 604 ++ .../pip/_vendor/cachecontrol/__init__.py | 11 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 537 bytes .../__pycache__/_cmd.cpython-37.pyc | Bin 0 -> 1540 bytes .../__pycache__/adapter.cpython-37.pyc | Bin 0 -> 3023 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 1753 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 744 bytes .../__pycache__/controller.cpython-37.pyc | Bin 0 -> 7623 bytes .../__pycache__/filewrapper.cpython-37.pyc | Bin 0 -> 2141 bytes .../__pycache__/heuristics.cpython-37.pyc | Bin 0 -> 4661 bytes .../__pycache__/serialize.cpython-37.pyc | Bin 0 -> 4225 bytes .../__pycache__/wrapper.cpython-37.pyc | Bin 0 -> 645 bytes .../pip/_vendor/cachecontrol/_cmd.py | 57 + .../pip/_vendor/cachecontrol/adapter.py | 133 + .../pip/_vendor/cachecontrol/cache.py | 39 + .../_vendor/cachecontrol/caches/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 281 bytes .../__pycache__/file_cache.cpython-37.pyc | Bin 0 -> 3215 bytes .../__pycache__/redis_cache.cpython-37.pyc | Bin 0 -> 1537 bytes .../_vendor/cachecontrol/caches/file_cache.py | 146 + .../cachecontrol/caches/redis_cache.py | 33 + .../pip/_vendor/cachecontrol/compat.py | 29 + .../pip/_vendor/cachecontrol/controller.py | 367 + .../pip/_vendor/cachecontrol/filewrapper.py | 80 + .../pip/_vendor/cachecontrol/heuristics.py | 135 + .../pip/_vendor/cachecontrol/serialize.py | 186 + .../pip/_vendor/cachecontrol/wrapper.py | 29 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 264 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 0 -> 235 bytes .../certifi/__pycache__/core.cpython-37.pyc | Bin 0 -> 1199 bytes .../pip/_vendor/certifi/cacert.pem | 4400 +++++++++ Lib/site-packages/pip/_vendor/certifi/core.py | 37 + .../pip/_vendor/chardet/__init__.py | 39 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 831 bytes .../__pycache__/big5freq.cpython-37.pyc | Bin 0 -> 27166 bytes .../__pycache__/big5prober.cpython-37.pyc | Bin 0 -> 1107 bytes .../chardistribution.cpython-37.pyc | Bin 0 -> 6293 bytes .../charsetgroupprober.cpython-37.pyc | Bin 0 -> 2214 bytes .../__pycache__/charsetprober.cpython-37.pyc | Bin 0 -> 3424 bytes .../codingstatemachine.cpython-37.pyc | Bin 0 -> 2871 bytes .../chardet/__pycache__/compat.cpython-37.pyc | Bin 0 -> 342 bytes .../__pycache__/cp949prober.cpython-37.pyc | Bin 0 -> 1114 bytes .../chardet/__pycache__/enums.cpython-37.pyc | Bin 0 -> 2605 bytes .../__pycache__/escprober.cpython-37.pyc | Bin 0 -> 2592 bytes .../chardet/__pycache__/escsm.cpython-37.pyc | Bin 0 -> 7053 bytes .../__pycache__/eucjpprober.cpython-37.pyc | Bin 0 -> 2400 bytes .../__pycache__/euckrfreq.cpython-37.pyc | Bin 0 -> 12050 bytes .../__pycache__/euckrprober.cpython-37.pyc | Bin 0 -> 1115 bytes .../__pycache__/euctwfreq.cpython-37.pyc | Bin 0 -> 27170 bytes .../__pycache__/euctwprober.cpython-37.pyc | Bin 0 -> 1115 bytes .../__pycache__/gb2312freq.cpython-37.pyc | Bin 0 -> 19094 bytes .../__pycache__/gb2312prober.cpython-37.pyc | Bin 0 -> 1123 bytes .../__pycache__/hebrewprober.cpython-37.pyc | Bin 0 -> 2957 bytes .../__pycache__/jisfreq.cpython-37.pyc | Bin 0 -> 22122 bytes .../chardet/__pycache__/jpcntx.cpython-37.pyc | Bin 0 -> 38001 bytes .../langbulgarianmodel.cpython-37.pyc | Bin 0 -> 23615 bytes .../langcyrillicmodel.cpython-37.pyc | Bin 0 -> 29071 bytes .../__pycache__/langgreekmodel.cpython-37.pyc | Bin 0 -> 23573 bytes .../langhebrewmodel.cpython-37.pyc | Bin 0 -> 22202 bytes .../langhungarianmodel.cpython-37.pyc | Bin 0 -> 23604 bytes .../__pycache__/langthaimodel.cpython-37.pyc | Bin 0 -> 22181 bytes .../langturkishmodel.cpython-37.pyc | Bin 0 -> 22204 bytes .../__pycache__/latin1prober.cpython-37.pyc | Bin 0 -> 2914 bytes .../mbcharsetprober.cpython-37.pyc | Bin 0 -> 2219 bytes .../mbcsgroupprober.cpython-37.pyc | Bin 0 -> 1110 bytes .../chardet/__pycache__/mbcssm.cpython-37.pyc | Bin 0 -> 15665 bytes .../sbcharsetprober.cpython-37.pyc | Bin 0 -> 2972 bytes .../sbcsgroupprober.cpython-37.pyc | Bin 0 -> 1600 bytes .../__pycache__/sjisprober.cpython-37.pyc | Bin 0 -> 2426 bytes .../universaldetector.cpython-37.pyc | Bin 0 -> 5816 bytes .../__pycache__/utf8prober.cpython-37.pyc | Bin 0 -> 1957 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 426 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 183 bytes .../cli/__pycache__/chardetect.cpython-37.pyc | Bin 0 -> 2672 bytes .../pip/_vendor/chardet/cli/chardetect.py | 85 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 34 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 228 + .../pip/_vendor/chardet/langcyrillicmodel.py | 333 + .../pip/_vendor/chardet/langgreekmodel.py | 225 + .../pip/_vendor/chardet/langhebrewmodel.py | 200 + .../pip/_vendor/chardet/langhungarianmodel.py | 225 + .../pip/_vendor/chardet/langthaimodel.py | 199 + .../pip/_vendor/chardet/langturkishmodel.py | 193 + .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/sbcharsetprober.py | 132 + .../pip/_vendor/chardet/sbcsgroupprober.py | 73 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 7 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 431 bytes .../colorama/__pycache__/ansi.cpython-37.pyc | Bin 0 -> 3329 bytes .../__pycache__/ansitowin32.cpython-37.pyc | Bin 0 -> 7042 bytes .../__pycache__/initialise.cpython-37.pyc | Bin 0 -> 1650 bytes .../colorama/__pycache__/win32.cpython-37.pyc | Bin 0 -> 3865 bytes .../__pycache__/winterm.cpython-37.pyc | Bin 0 -> 4554 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 236 + .../pip/_vendor/colorama/initialise.py | 82 + .../pip/_vendor/colorama/win32.py | 156 + .../pip/_vendor/colorama/winterm.py | 162 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1029 bytes .../distlib/__pycache__/compat.cpython-37.pyc | Bin 0 -> 32039 bytes .../__pycache__/database.cpython-37.pyc | Bin 0 -> 42512 bytes .../distlib/__pycache__/index.cpython-37.pyc | Bin 0 -> 17325 bytes .../__pycache__/locators.cpython-37.pyc | Bin 0 -> 38632 bytes .../__pycache__/manifest.cpython-37.pyc | Bin 0 -> 10277 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 4463 bytes .../__pycache__/metadata.cpython-37.pyc | Bin 0 -> 27672 bytes .../__pycache__/resources.cpython-37.pyc | Bin 0 -> 10873 bytes .../__pycache__/scripts.cpython-37.pyc | Bin 0 -> 11049 bytes .../distlib/__pycache__/util.cpython-37.pyc | Bin 0 -> 47870 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 20413 bytes .../distlib/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 25063 bytes .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 471 bytes .../_backport/__pycache__/misc.cpython-37.pyc | Bin 0 -> 1068 bytes .../__pycache__/shutil.cpython-37.pyc | Bin 0 -> 21384 bytes .../__pycache__/sysconfig.cpython-37.pyc | Bin 0 -> 15849 bytes .../__pycache__/tarfile.cpython-37.pyc | Bin 0 -> 62714 bytes .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 761 ++ .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 788 ++ .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ++++++ .../pip/_vendor/distlib/compat.py | 1120 +++ .../pip/_vendor/distlib/database.py | 1336 +++ .../pip/_vendor/distlib/index.py | 516 ++ .../pip/_vendor/distlib/locators.py | 1292 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1091 +++ .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 415 + Lib/site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 92672 bytes Lib/site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 102400 bytes Lib/site-packages/pip/_vendor/distlib/util.py | 1755 ++++ .../pip/_vendor/distlib/version.py | 736 ++ Lib/site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 89088 bytes Lib/site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 99328 bytes .../pip/_vendor/distlib/wheel.py | 984 ++ Lib/site-packages/pip/_vendor/distro.py | 1197 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1300 bytes .../__pycache__/_ihatexml.cpython-37.pyc | Bin 0 -> 13747 bytes .../__pycache__/_inputstream.cpython-37.pyc | Bin 0 -> 22638 bytes .../__pycache__/_tokenizer.cpython-37.pyc | Bin 0 -> 41539 bytes .../__pycache__/_utils.cpython-37.pyc | Bin 0 -> 3292 bytes .../__pycache__/constants.cpython-37.pyc | Bin 0 -> 66204 bytes .../__pycache__/html5parser.cpython-37.pyc | Bin 0 -> 97801 bytes .../__pycache__/serializer.cpython-37.pyc | Bin 0 -> 10817 bytes .../pip/_vendor/html5lib/_ihatexml.py | 288 + .../pip/_vendor/html5lib/_inputstream.py | 923 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1721 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 14 + .../_trie/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 413 bytes .../_trie/__pycache__/_base.cpython-37.pyc | Bin 0 -> 1496 bytes .../_trie/__pycache__/datrie.cpython-37.pyc | Bin 0 -> 2015 bytes .../_trie/__pycache__/py.cpython-37.pyc | Bin 0 -> 2218 bytes .../pip/_vendor/html5lib/_trie/_base.py | 37 + .../pip/_vendor/html5lib/_trie/datrie.py | 44 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 124 + .../pip/_vendor/html5lib/constants.py | 2947 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 188 bytes .../alphabeticalattributes.cpython-37.pyc | Bin 0 -> 1304 bytes .../filters/__pycache__/base.cpython-37.pyc | Bin 0 -> 838 bytes .../inject_meta_charset.cpython-37.pyc | Bin 0 -> 1858 bytes .../filters/__pycache__/lint.cpython-37.pyc | Bin 0 -> 2622 bytes .../__pycache__/optionaltags.cpython-37.pyc | Bin 0 -> 2749 bytes .../__pycache__/sanitizer.cpython-37.pyc | Bin 0 -> 16424 bytes .../__pycache__/whitespace.cpython-37.pyc | Bin 0 -> 1342 bytes .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 896 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2791 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 927 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1524 bytes .../__pycache__/sax.cpython-37.pyc | Bin 0 -> 1474 bytes .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3308 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 11231 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 9261 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 11840 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 11780 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 236 + .../_vendor/html5lib/treebuilders/etree.py | 340 + .../html5lib/treebuilders/etree_lxml.py | 366 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3985 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 6981 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 1710 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 3517 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 6626 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1884 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 130 + .../html5lib/treewalkers/etree_lxml.py | 213 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 2 + .../idna/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 245 bytes .../idna/__pycache__/codec.cpython-37.pyc | Bin 0 -> 3052 bytes .../idna/__pycache__/compat.cpython-37.pyc | Bin 0 -> 605 bytes .../idna/__pycache__/core.cpython-37.pyc | Bin 0 -> 9137 bytes .../idna/__pycache__/idnadata.cpython-37.pyc | Bin 0 -> 20569 bytes .../idna/__pycache__/intranges.cpython-37.pyc | Bin 0 -> 1785 bytes .../__pycache__/package_data.cpython-37.pyc | Bin 0 -> 199 bytes .../idna/__pycache__/uts46data.cpython-37.pyc | Bin 0 -> 175641 bytes Lib/site-packages/pip/_vendor/idna/codec.py | 118 + Lib/site-packages/pip/_vendor/idna/compat.py | 12 + Lib/site-packages/pip/_vendor/idna/core.py | 399 + .../pip/_vendor/idna/idnadata.py | 1893 ++++ .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8179 +++++++++++++++++ Lib/site-packages/pip/_vendor/ipaddress.py | 2419 +++++ .../pip/_vendor/lockfile/__init__.py | 347 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9895 bytes .../__pycache__/linklockfile.cpython-37.pyc | Bin 0 -> 2276 bytes .../__pycache__/mkdirlockfile.cpython-37.pyc | Bin 0 -> 2638 bytes .../__pycache__/pidlockfile.cpython-37.pyc | Bin 0 -> 4838 bytes .../__pycache__/sqlitelockfile.cpython-37.pyc | Bin 0 -> 3737 bytes .../symlinklockfile.cpython-37.pyc | Bin 0 -> 2161 bytes .../pip/_vendor/lockfile/linklockfile.py | 73 + .../pip/_vendor/lockfile/mkdirlockfile.py | 84 + .../pip/_vendor/lockfile/pidlockfile.py | 190 + .../pip/_vendor/lockfile/sqlitelockfile.py | 156 + .../pip/_vendor/lockfile/symlinklockfile.py | 70 + .../pip/_vendor/msgpack/__init__.py | 66 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2057 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 206 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 2162 bytes .../__pycache__/fallback.cpython-37.pyc | Bin 0 -> 24534 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 41 + .../pip/_vendor/msgpack/fallback.py | 977 ++ .../pip/_vendor/packaging/__about__.py | 21 + .../pip/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 707 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 545 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 997 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2849 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8848 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3866 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19775 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 1443 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 11961 bytes .../pip/_vendor/packaging/_compat.py | 30 + .../pip/_vendor/packaging/_structures.py | 70 + .../pip/_vendor/packaging/markers.py | 301 + .../pip/_vendor/packaging/requirements.py | 130 + .../pip/_vendor/packaging/specifiers.py | 774 ++ .../pip/_vendor/packaging/utils.py | 63 + .../pip/_vendor/packaging/version.py | 441 + .../pip/_vendor/pkg_resources/__init__.py | 3132 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 95673 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 664 bytes .../pip/_vendor/pkg_resources/py31compat.py | 22 + .../pip/_vendor/progress/__init__.py | 127 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3898 bytes .../progress/__pycache__/bar.cpython-37.pyc | Bin 0 -> 2720 bytes .../__pycache__/counter.cpython-37.pyc | Bin 0 -> 1562 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 0 -> 3004 bytes .../__pycache__/spinner.cpython-37.pyc | Bin 0 -> 1479 bytes Lib/site-packages/pip/_vendor/progress/bar.py | 94 + .../pip/_vendor/progress/counter.py | 48 + .../pip/_vendor/progress/helpers.py | 91 + .../pip/_vendor/progress/spinner.py | 44 + Lib/site-packages/pip/_vendor/pyparsing.py | 5720 ++++++++++++ .../pip/_vendor/pytoml/__init__.py | 3 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 318 bytes .../pytoml/__pycache__/core.cpython-37.pyc | Bin 0 -> 927 bytes .../pytoml/__pycache__/parser.cpython-37.pyc | Bin 0 -> 11122 bytes .../pytoml/__pycache__/writer.cpython-37.pyc | Bin 0 -> 3829 bytes Lib/site-packages/pip/_vendor/pytoml/core.py | 13 + .../pip/_vendor/pytoml/parser.py | 374 + .../pip/_vendor/pytoml/writer.py | 127 + .../pip/_vendor/requests/__init__.py | 138 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3769 bytes .../__pycache__/__version__.cpython-37.pyc | Bin 0 -> 538 bytes .../_internal_utils.cpython-37.pyc | Bin 0 -> 1296 bytes .../__pycache__/adapters.cpython-37.pyc | Bin 0 -> 16761 bytes .../requests/__pycache__/api.cpython-37.pyc | Bin 0 -> 6487 bytes .../requests/__pycache__/auth.cpython-37.pyc | Bin 0 -> 8332 bytes .../requests/__pycache__/certs.cpython-37.pyc | Bin 0 -> 621 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 1631 bytes .../__pycache__/cookies.cpython-37.pyc | Bin 0 -> 18740 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 5493 bytes .../requests/__pycache__/help.cpython-37.pyc | Bin 0 -> 2685 bytes .../requests/__pycache__/hooks.cpython-37.pyc | Bin 0 -> 985 bytes .../__pycache__/models.cpython-37.pyc | Bin 0 -> 23952 bytes .../__pycache__/packages.cpython-37.pyc | Bin 0 -> 498 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 0 -> 18557 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 4154 bytes .../__pycache__/structures.cpython-37.pyc | Bin 0 -> 4367 bytes .../requests/__pycache__/utils.cpython-37.pyc | Bin 0 -> 21937 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 530 ++ Lib/site-packages/pip/_vendor/requests/api.py | 152 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 75 + .../pip/_vendor/requests/cookies.py | 546 ++ .../pip/_vendor/requests/exceptions.py | 126 + .../pip/_vendor/requests/help.py | 120 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 952 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 741 ++ .../pip/_vendor/requests/status_codes.py | 120 + .../pip/_vendor/requests/structures.py | 103 + .../pip/_vendor/requests/utils.py | 976 ++ Lib/site-packages/pip/_vendor/retrying.py | 267 + Lib/site-packages/pip/_vendor/six.py | 891 ++ .../pip/_vendor/urllib3/__init__.py | 97 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2410 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 0 -> 10734 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 10255 bytes .../__pycache__/connectionpool.cpython-37.pyc | Bin 0 -> 23789 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 10388 bytes .../urllib3/__pycache__/fields.cpython-37.pyc | Bin 0 -> 5856 bytes .../__pycache__/filepost.cpython-37.pyc | Bin 0 -> 2748 bytes .../__pycache__/poolmanager.cpython-37.pyc | Bin 0 -> 12687 bytes .../__pycache__/request.cpython-37.pyc | Bin 0 -> 5579 bytes .../__pycache__/response.cpython-37.pyc | Bin 0 -> 17405 bytes .../pip/_vendor/urllib3/_collections.py | 332 + .../pip/_vendor/urllib3/connection.py | 403 + .../pip/_vendor/urllib3/connectionpool.py | 906 ++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 187 bytes .../__pycache__/appengine.cpython-37.pyc | Bin 0 -> 8935 bytes .../__pycache__/ntlmpool.cpython-37.pyc | Bin 0 -> 3235 bytes .../__pycache__/pyopenssl.cpython-37.pyc | Bin 0 -> 14262 bytes .../securetransport.cpython-37.pyc | Bin 0 -> 17884 bytes .../contrib/__pycache__/socks.cpython-37.pyc | Bin 0 -> 4893 bytes .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 204 bytes .../__pycache__/bindings.cpython-37.pyc | Bin 0 -> 10299 bytes .../__pycache__/low_level.cpython-37.pyc | Bin 0 -> 7480 bytes .../contrib/_securetransport/bindings.py | 593 ++ .../contrib/_securetransport/low_level.py | 346 + .../pip/_vendor/urllib3/contrib/appengine.py | 305 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 112 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 457 + .../urllib3/contrib/securetransport.py | 804 ++ .../pip/_vendor/urllib3/contrib/socks.py | 192 + .../pip/_vendor/urllib3/exceptions.py | 246 + .../pip/_vendor/urllib3/fields.py | 178 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 5 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 301 bytes .../__pycache__/ordered_dict.cpython-37.pyc | Bin 0 -> 8395 bytes .../packages/__pycache__/six.cpython-37.pyc | Bin 0 -> 24389 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 198 bytes .../__pycache__/makefile.cpython-37.pyc | Bin 0 -> 1296 bytes .../urllib3/packages/backports/makefile.py | 53 + .../_vendor/urllib3/packages/ordered_dict.py | 259 + .../pip/_vendor/urllib3/packages/six.py | 868 ++ .../packages/ssl_match_hostname/__init__.py | 19 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 542 bytes .../_implementation.cpython-37.pyc | Bin 0 -> 3301 bytes .../ssl_match_hostname/_implementation.py | 157 + .../pip/_vendor/urllib3/poolmanager.py | 449 + .../pip/_vendor/urllib3/request.py | 150 + .../pip/_vendor/urllib3/response.py | 676 ++ .../pip/_vendor/urllib3/util/__init__.py | 54 + .../util/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 979 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 3056 bytes .../util/__pycache__/queue.cpython-37.pyc | Bin 0 -> 1028 bytes .../util/__pycache__/request.cpython-37.pyc | Bin 0 -> 3209 bytes .../util/__pycache__/response.cpython-37.pyc | Bin 0 -> 1890 bytes .../util/__pycache__/retry.cpython-37.pyc | Bin 0 -> 12642 bytes .../util/__pycache__/ssl_.cpython-37.pyc | Bin 0 -> 9980 bytes .../util/__pycache__/timeout.cpython-37.pyc | Bin 0 -> 8758 bytes .../util/__pycache__/url.cpython-37.pyc | Bin 0 -> 5168 bytes .../util/__pycache__/wait.cpython-37.pyc | Bin 0 -> 3141 bytes .../pip/_vendor/urllib3/util/connection.py | 126 + .../pip/_vendor/urllib3/util/queue.py | 21 + .../pip/_vendor/urllib3/util/request.py | 118 + .../pip/_vendor/urllib3/util/response.py | 81 + .../pip/_vendor/urllib3/util/retry.py | 411 + .../pip/_vendor/urllib3/util/ssl_.py | 396 + .../pip/_vendor/urllib3/util/timeout.py | 242 + .../pip/_vendor/urllib3/util/url.py | 230 + .../pip/_vendor/urllib3/util/wait.py | 153 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9663 bytes .../__pycache__/labels.cpython-37.pyc | Bin 0 -> 4077 bytes .../__pycache__/mklabels.cpython-37.pyc | Bin 0 -> 1899 bytes .../__pycache__/tests.cpython-37.pyc | Bin 0 -> 5040 bytes .../__pycache__/x_user_defined.cpython-37.pyc | Bin 0 -> 2652 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + Lib/site-packages/pkg_resources/__init__.py | 3135 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 95740 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 599 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 188 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 18582 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 200939 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24389 bytes .../pkg_resources/_vendor/appdirs.py | 552 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 724 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 562 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1014 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2866 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8874 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3879 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19792 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 493 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10559 bytes .../_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../pkg_resources/_vendor/packaging/utils.py | 14 + .../_vendor/packaging/version.py | 393 + .../pkg_resources/_vendor/pyparsing.py | 5696 ++++++++++++ .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2407 bytes Lib/site-packages/pkg_resources/py31compat.py | 21 + .../pluggy-0.7.1.dist-info/INSTALLER | 1 + .../pluggy-0.7.1.dist-info/LICENSE.txt | 22 + .../pluggy-0.7.1.dist-info/METADATA | 113 + .../pluggy-0.7.1.dist-info/RECORD | 18 + .../pluggy-0.7.1.dist-info/WHEEL | 6 + .../pluggy-0.7.1.dist-info/top_level.txt | 1 + Lib/site-packages/pluggy/__init__.py | 13 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 523 bytes .../__pycache__/_tracing.cpython-37.pyc | Bin 0 -> 3484 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 186 bytes .../pluggy/__pycache__/callers.cpython-37.pyc | Bin 0 -> 5909 bytes .../pluggy/__pycache__/hooks.cpython-37.pyc | Bin 0 -> 11053 bytes .../pluggy/__pycache__/manager.cpython-37.pyc | Bin 0 -> 12597 bytes Lib/site-packages/pluggy/_tracing.py | 85 + Lib/site-packages/pluggy/_version.py | 4 + Lib/site-packages/pluggy/callers.py | 201 + Lib/site-packages/pluggy/hooks.py | 323 + Lib/site-packages/pluggy/manager.py | 338 + .../py-1.5.4.dist-info/INSTALLER | 1 + .../py-1.5.4.dist-info/LICENSE.txt | 19 + Lib/site-packages/py-1.5.4.dist-info/METADATA | 69 + Lib/site-packages/py-1.5.4.dist-info/RECORD | 76 + Lib/site-packages/py-1.5.4.dist-info/WHEEL | 6 + .../py-1.5.4.dist-info/top_level.txt | 1 + Lib/site-packages/py/__init__.py | 156 + Lib/site-packages/py/__metainfo.py | 2 + .../py/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4102 bytes .../py/__pycache__/__metainfo.cpython-37.pyc | Bin 0 -> 236 bytes .../py/__pycache__/_builtin.cpython-37.pyc | Bin 0 -> 7024 bytes .../py/__pycache__/_error.cpython-37.pyc | Bin 0 -> 2679 bytes .../py/__pycache__/_std.cpython-37.pyc | Bin 0 -> 1131 bytes .../py/__pycache__/_version.cpython-37.pyc | Bin 0 -> 178 bytes .../py/__pycache__/_xmlgen.cpython-37.pyc | Bin 0 -> 10241 bytes .../py/__pycache__/test.cpython-37.pyc | Bin 0 -> 298 bytes Lib/site-packages/py/_builtin.py | 248 + Lib/site-packages/py/_code/__init__.py | 1 + .../_code/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 218 bytes .../__pycache__/_assertionnew.cpython-37.pyc | Bin 0 -> 9384 bytes .../__pycache__/_assertionold.cpython-37.pyc | Bin 0 -> 16305 bytes .../__pycache__/_py2traceback.cpython-37.pyc | Bin 0 -> 2102 bytes .../__pycache__/assertion.cpython-37.pyc | Bin 0 -> 2546 bytes .../py/_code/__pycache__/code.cpython-37.pyc | Bin 0 -> 26152 bytes .../_code/__pycache__/source.cpython-37.pyc | Bin 0 -> 11861 bytes Lib/site-packages/py/_code/_assertionnew.py | 322 + Lib/site-packages/py/_code/_assertionold.py | 556 ++ Lib/site-packages/py/_code/_py2traceback.py | 79 + Lib/site-packages/py/_code/assertion.py | 90 + Lib/site-packages/py/_code/code.py | 796 ++ Lib/site-packages/py/_code/source.py | 410 + Lib/site-packages/py/_error.py | 91 + Lib/site-packages/py/_io/__init__.py | 1 + .../_io/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 199 bytes .../py/_io/__pycache__/capture.cpython-37.pyc | Bin 0 -> 11584 bytes .../_io/__pycache__/saferepr.cpython-37.pyc | Bin 0 -> 2642 bytes .../__pycache__/terminalwriter.cpython-37.pyc | Bin 0 -> 10043 bytes Lib/site-packages/py/_io/capture.py | 371 + Lib/site-packages/py/_io/saferepr.py | 71 + Lib/site-packages/py/_io/terminalwriter.py | 384 + Lib/site-packages/py/_log/__init__.py | 2 + .../_log/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 244 bytes .../py/_log/__pycache__/log.cpython-37.pyc | Bin 0 -> 7416 bytes .../_log/__pycache__/warning.cpython-37.pyc | Bin 0 -> 2249 bytes Lib/site-packages/py/_log/log.py | 206 + Lib/site-packages/py/_log/warning.py | 79 + Lib/site-packages/py/_path/__init__.py | 1 + .../_path/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 204 bytes .../__pycache__/cacheutil.cpython-37.pyc | Bin 0 -> 4645 bytes .../_path/__pycache__/common.cpython-37.pyc | Bin 0 -> 14775 bytes .../py/_path/__pycache__/local.cpython-37.pyc | Bin 0 -> 29939 bytes .../_path/__pycache__/svnurl.cpython-37.pyc | Bin 0 -> 13351 bytes .../py/_path/__pycache__/svnwc.cpython-37.pyc | Bin 0 -> 36154 bytes Lib/site-packages/py/_path/cacheutil.py | 114 + Lib/site-packages/py/_path/common.py | 453 + Lib/site-packages/py/_path/local.py | 992 ++ Lib/site-packages/py/_path/svnurl.py | 380 + Lib/site-packages/py/_path/svnwc.py | 1240 +++ Lib/site-packages/py/_process/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 215 bytes .../__pycache__/cmdexec.cpython-37.pyc | Bin 0 -> 1875 bytes .../__pycache__/forkedfunc.cpython-37.pyc | Bin 0 -> 3613 bytes .../__pycache__/killproc.cpython-37.pyc | Bin 0 -> 987 bytes Lib/site-packages/py/_process/cmdexec.py | 49 + Lib/site-packages/py/_process/forkedfunc.py | 120 + Lib/site-packages/py/_process/killproc.py | 23 + Lib/site-packages/py/_std.py | 26 + .../py/_vendored_packages/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 180 bytes .../__pycache__/apipkg.cpython-37.pyc | Bin 0 -> 5964 bytes .../__pycache__/iniconfig.cpython-37.pyc | Bin 0 -> 5187 bytes .../py/_vendored_packages/apipkg.py | 205 + .../py/_vendored_packages/iniconfig.py | 165 + Lib/site-packages/py/_version.py | 4 + Lib/site-packages/py/_xmlgen.py | 255 + Lib/site-packages/py/test.py | 10 + .../pytest-3.7.1.dist-info/INSTALLER | 1 + .../pytest-3.7.1.dist-info/LICENSE.txt | 21 + .../pytest-3.7.1.dist-info/METADATA | 162 + .../pytest-3.7.1.dist-info/RECORD | 117 + .../pytest-3.7.1.dist-info/WHEEL | 6 + .../pytest-3.7.1.dist-info/entry_points.txt | 4 + .../pytest-3.7.1.dist-info/top_level.txt | 2 + Lib/site-packages/pytest.py | 73 + .../setuptools-40.0.0.dist-info/INSTALLER | 1 + .../setuptools-40.0.0.dist-info/LICENSE.txt | 19 + .../setuptools-40.0.0.dist-info/METADATA | 75 + .../setuptools-40.0.0.dist-info/RECORD | 186 + .../setuptools-40.0.0.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 65 + .../setuptools-40.0.0.dist-info/top_level.txt | 3 + .../setuptools-40.0.0.dist-info/zip-safe | 1 + Lib/site-packages/setuptools/__init__.py | 182 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6297 bytes .../__pycache__/archive_util.cpython-37.pyc | Bin 0 -> 5124 bytes .../__pycache__/build_meta.cpython-37.pyc | Bin 0 -> 5904 bytes .../__pycache__/config.cpython-37.pyc | Bin 0 -> 15053 bytes .../__pycache__/dep_util.cpython-37.pyc | Bin 0 -> 850 bytes .../__pycache__/depends.cpython-37.pyc | Bin 0 -> 5259 bytes .../__pycache__/dist.cpython-37.pyc | Bin 0 -> 36769 bytes .../__pycache__/extension.cpython-37.pyc | Bin 0 -> 1970 bytes .../__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1535 bytes .../__pycache__/glob.cpython-37.pyc | Bin 0 -> 3836 bytes .../__pycache__/launch.cpython-37.pyc | Bin 0 -> 849 bytes .../__pycache__/lib2to3_ex.cpython-37.pyc | Bin 0 -> 2428 bytes .../__pycache__/monkey.cpython-37.pyc | Bin 0 -> 4551 bytes .../__pycache__/msvc.cpython-37.pyc | Bin 0 -> 34438 bytes .../__pycache__/namespaces.cpython-37.pyc | Bin 0 -> 3607 bytes .../__pycache__/package_index.cpython-37.pyc | Bin 0 -> 32371 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7181 bytes .../__pycache__/py27compat.cpython-37.pyc | Bin 0 -> 806 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 1192 bytes .../__pycache__/py33compat.cpython-37.pyc | Bin 0 -> 1415 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 2187 bytes .../__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 15531 bytes .../__pycache__/site-patch.cpython-37.pyc | Bin 0 -> 1497 bytes .../__pycache__/ssl_support.cpython-37.pyc | Bin 0 -> 6786 bytes .../__pycache__/unicode_utils.cpython-37.pyc | Bin 0 -> 1164 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 323 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 7011 bytes .../windows_support.cpython-37.pyc | Bin 0 -> 1006 bytes .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 185 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 200936 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24386 bytes .../setuptools/_vendor/packaging/__about__.py | 21 + .../setuptools/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 721 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 559 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1011 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2863 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8868 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3870 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19789 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 490 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10556 bytes .../setuptools/_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../setuptools/_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../setuptools/_vendor/packaging/utils.py | 14 + .../setuptools/_vendor/packaging/version.py | 393 + .../setuptools/_vendor/pyparsing.py | 5696 ++++++++++++ Lib/site-packages/setuptools/_vendor/six.py | 868 ++ Lib/site-packages/setuptools/archive_util.py | 173 + Lib/site-packages/setuptools/build_meta.py | 172 + Lib/site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes Lib/site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes Lib/site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 18 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 731 bytes .../command/__pycache__/alias.cpython-37.pyc | Bin 0 -> 2399 bytes .../__pycache__/bdist_egg.cpython-37.pyc | Bin 0 -> 14195 bytes .../__pycache__/bdist_rpm.cpython-37.pyc | Bin 0 -> 1778 bytes .../__pycache__/bdist_wininst.cpython-37.pyc | Bin 0 -> 969 bytes .../__pycache__/build_clib.cpython-37.pyc | Bin 0 -> 2448 bytes .../__pycache__/build_ext.cpython-37.pyc | Bin 0 -> 9702 bytes .../__pycache__/build_py.cpython-37.pyc | Bin 0 -> 8578 bytes .../__pycache__/develop.cpython-37.pyc | Bin 0 -> 6419 bytes .../__pycache__/dist_info.cpython-37.pyc | Bin 0 -> 1374 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 64554 bytes .../__pycache__/egg_info.cpython-37.pyc | Bin 0 -> 21050 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 4006 bytes .../install_egg_info.cpython-37.pyc | Bin 0 -> 2407 bytes .../__pycache__/install_lib.cpython-37.pyc | Bin 0 -> 4083 bytes .../install_scripts.cpython-37.pyc | Bin 0 -> 2286 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 4619 bytes .../__pycache__/register.cpython-37.pyc | Bin 0 -> 595 bytes .../command/__pycache__/rotate.cpython-37.pyc | Bin 0 -> 2525 bytes .../__pycache__/saveopts.cpython-37.pyc | Bin 0 -> 920 bytes .../command/__pycache__/sdist.cpython-37.pyc | Bin 0 -> 6216 bytes .../command/__pycache__/setopt.cpython-37.pyc | Bin 0 -> 4518 bytes .../command/__pycache__/test.cpython-37.pyc | Bin 0 -> 8113 bytes .../command/__pycache__/upload.cpython-37.pyc | Bin 0 -> 1387 bytes .../__pycache__/upload_docs.cpython-37.pyc | Bin 0 -> 6129 bytes Lib/site-packages/setuptools/command/alias.py | 80 + .../setuptools/command/bdist_egg.py | 502 + .../setuptools/command/bdist_rpm.py | 43 + .../setuptools/command/bdist_wininst.py | 21 + .../setuptools/command/build_clib.py | 98 + .../setuptools/command/build_ext.py | 321 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 218 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2337 +++++ .../setuptools/command/egg_info.py | 696 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 62 + .../setuptools/command/install_lib.py | 121 + .../setuptools/command/install_scripts.py | 65 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 136 + .../setuptools/command/register.py | 10 + .../setuptools/command/rotate.py | 66 + .../setuptools/command/saveopts.py | 22 + Lib/site-packages/setuptools/command/sdist.py | 200 + .../setuptools/command/setopt.py | 149 + Lib/site-packages/setuptools/command/test.py | 270 + .../setuptools/command/upload.py | 42 + .../setuptools/command/upload_docs.py | 206 + Lib/site-packages/setuptools/config.py | 592 ++ Lib/site-packages/setuptools/dep_util.py | 23 + Lib/site-packages/setuptools/depends.py | 186 + Lib/site-packages/setuptools/dist.py | 1071 +++ Lib/site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2415 bytes Lib/site-packages/setuptools/glibc.py | 86 + Lib/site-packages/setuptools/glob.py | 176 + Lib/site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes Lib/site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes Lib/site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes Lib/site-packages/setuptools/launch.py | 35 + Lib/site-packages/setuptools/lib2to3_ex.py | 62 + Lib/site-packages/setuptools/monkey.py | 179 + Lib/site-packages/setuptools/msvc.py | 1302 +++ Lib/site-packages/setuptools/namespaces.py | 107 + Lib/site-packages/setuptools/package_index.py | 1127 +++ Lib/site-packages/setuptools/pep425tags.py | 317 + Lib/site-packages/setuptools/py27compat.py | 28 + Lib/site-packages/setuptools/py31compat.py | 32 + Lib/site-packages/setuptools/py33compat.py | 55 + Lib/site-packages/setuptools/py36compat.py | 82 + Lib/site-packages/setuptools/sandbox.py | 491 + .../setuptools/script (dev).tmpl | 6 + Lib/site-packages/setuptools/script.tmpl | 3 + Lib/site-packages/setuptools/site-patch.py | 74 + Lib/site-packages/setuptools/ssl_support.py | 260 + Lib/site-packages/setuptools/unicode_utils.py | 44 + Lib/site-packages/setuptools/version.py | 6 + Lib/site-packages/setuptools/wheel.py | 210 + .../setuptools/windows_support.py | 29 + .../six-1.11.0.dist-info/DESCRIPTION.rst | 27 + .../six-1.11.0.dist-info/INSTALLER | 1 + .../six-1.11.0.dist-info/METADATA | 43 + Lib/site-packages/six-1.11.0.dist-info/RECORD | 9 + Lib/site-packages/six-1.11.0.dist-info/WHEEL | 6 + .../six-1.11.0.dist-info/metadata.json | 1 + .../six-1.11.0.dist-info/top_level.txt | 1 + Lib/site-packages/six.py | 891 ++ Lib/site-packages/werkzeug/__init__.py | 151 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4689 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 7136 bytes .../__pycache__/_internal.cpython-37.pyc | Bin 0 -> 12557 bytes .../__pycache__/_reloader.cpython-37.pyc | Bin 0 -> 8864 bytes .../__pycache__/datastructures.cpython-37.pyc | Bin 0 -> 100033 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 22949 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 2242 bytes .../__pycache__/formparser.cpython-37.pyc | Bin 0 -> 16082 bytes .../werkzeug/__pycache__/http.cpython-37.pyc | Bin 0 -> 33317 bytes .../werkzeug/__pycache__/local.cpython-37.pyc | Bin 0 -> 18676 bytes .../__pycache__/posixemulation.cpython-37.pyc | Bin 0 -> 2801 bytes .../__pycache__/routing.cpython-37.pyc | Bin 0 -> 60163 bytes .../__pycache__/script.cpython-37.pyc | Bin 0 -> 10074 bytes .../__pycache__/security.cpython-37.pyc | Bin 0 -> 8508 bytes .../__pycache__/serving.cpython-37.pyc | Bin 0 -> 26463 bytes .../werkzeug/__pycache__/test.cpython-37.pyc | Bin 0 -> 31023 bytes .../__pycache__/testapp.cpython-37.pyc | Bin 0 -> 9467 bytes .../werkzeug/__pycache__/urls.cpython-37.pyc | Bin 0 -> 33280 bytes .../__pycache__/useragents.cpython-37.pyc | Bin 0 -> 5450 bytes .../werkzeug/__pycache__/utils.cpython-37.pyc | Bin 0 -> 21107 bytes .../__pycache__/websocket.cpython-37.pyc | Bin 0 -> 8174 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 76375 bytes .../werkzeug/__pycache__/wsgi.cpython-37.pyc | Bin 0 -> 44543 bytes Lib/site-packages/werkzeug/_compat.py | 206 + Lib/site-packages/werkzeug/_internal.py | 419 + Lib/site-packages/werkzeug/_reloader.py | 277 + .../werkzeug/contrib/__init__.py | 16 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 788 bytes .../contrib/__pycache__/atom.cpython-37.pyc | Bin 0 -> 14092 bytes .../contrib/__pycache__/cache.cpython-37.pyc | Bin 0 -> 32384 bytes .../contrib/__pycache__/fixers.cpython-37.pyc | Bin 0 -> 10080 bytes .../contrib/__pycache__/iterio.cpython-37.pyc | Bin 0 -> 10973 bytes .../__pycache__/jsrouting.cpython-37.pyc | Bin 0 -> 8296 bytes .../__pycache__/limiter.cpython-37.pyc | Bin 0 -> 1744 bytes .../contrib/__pycache__/lint.cpython-37.pyc | Bin 0 -> 11864 bytes .../__pycache__/profiler.cpython-37.pyc | Bin 0 -> 5438 bytes .../__pycache__/securecookie.cpython-37.pyc | Bin 0 -> 10342 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 0 -> 12912 bytes .../__pycache__/testtools.cpython-37.pyc | Bin 0 -> 2654 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 10419 bytes Lib/site-packages/werkzeug/contrib/atom.py | 355 + Lib/site-packages/werkzeug/contrib/cache.py | 913 ++ Lib/site-packages/werkzeug/contrib/fixers.py | 254 + Lib/site-packages/werkzeug/contrib/iterio.py | 352 + .../werkzeug/contrib/jsrouting.py | 264 + Lib/site-packages/werkzeug/contrib/limiter.py | 41 + Lib/site-packages/werkzeug/contrib/lint.py | 343 + .../werkzeug/contrib/profiler.py | 147 + .../werkzeug/contrib/securecookie.py | 323 + .../werkzeug/contrib/sessions.py | 352 + .../werkzeug/contrib/testtools.py | 73 + .../werkzeug/contrib/wrappers.py | 284 + Lib/site-packages/werkzeug/datastructures.py | 2762 ++++++ Lib/site-packages/werkzeug/debug/__init__.py | 470 + .../debug/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 12674 bytes .../debug/__pycache__/console.cpython-37.pyc | Bin 0 -> 7362 bytes .../debug/__pycache__/repr.cpython-37.pyc | Bin 0 -> 8656 bytes .../debug/__pycache__/tbtools.cpython-37.pyc | Bin 0 -> 15610 bytes Lib/site-packages/werkzeug/debug/console.py | 215 + Lib/site-packages/werkzeug/debug/repr.py | 280 + .../werkzeug/debug/shared/FONT_LICENSE | 96 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 205 + .../werkzeug/debug/shared/jquery.js | 5 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/source.png | Bin 0 -> 818 bytes .../werkzeug/debug/shared/style.css | 143 + .../werkzeug/debug/shared/ubuntu.ttf | Bin 0 -> 70220 bytes Lib/site-packages/werkzeug/debug/tbtools.py | 556 ++ Lib/site-packages/werkzeug/exceptions.py | 719 ++ Lib/site-packages/werkzeug/filesystem.py | 66 + Lib/site-packages/werkzeug/formparser.py | 534 ++ Lib/site-packages/werkzeug/http.py | 1158 +++ Lib/site-packages/werkzeug/local.py | 420 + Lib/site-packages/werkzeug/posixemulation.py | 106 + Lib/site-packages/werkzeug/routing.py | 1792 ++++ Lib/site-packages/werkzeug/script.py | 318 + Lib/site-packages/werkzeug/security.py | 270 + Lib/site-packages/werkzeug/serving.py | 862 ++ Lib/site-packages/werkzeug/test.py | 948 ++ Lib/site-packages/werkzeug/testapp.py | 230 + Lib/site-packages/werkzeug/urls.py | 1007 ++ Lib/site-packages/werkzeug/useragents.py | 212 + Lib/site-packages/werkzeug/utils.py | 628 ++ Lib/site-packages/werkzeug/websocket.py | 337 + Lib/site-packages/werkzeug/wrappers.py | 2028 ++++ Lib/site-packages/werkzeug/wsgi.py | 1364 +++ .../wheel-0.31.1.dist-info/INSTALLER | 1 + .../wheel-0.31.1.dist-info/LICENSE.txt | 22 + .../wheel-0.31.1.dist-info/METADATA | 395 + .../wheel-0.31.1.dist-info/RECORD | 42 + .../wheel-0.31.1.dist-info/WHEEL | 6 + .../wheel-0.31.1.dist-info/entry_points.txt | 6 + .../wheel-0.31.1.dist-info/top_level.txt | 1 + Lib/site-packages/wheel/__init__.py | 2 + Lib/site-packages/wheel/__main__.py | 19 + .../wheel/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 189 bytes .../wheel/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 584 bytes .../wheel/__pycache__/archive.cpython-37.pyc | Bin 0 -> 2064 bytes .../__pycache__/bdist_wheel.cpython-37.pyc | Bin 0 -> 10830 bytes .../__pycache__/egg2wheel.cpython-37.pyc | Bin 0 -> 2702 bytes .../wheel/__pycache__/install.cpython-37.pyc | Bin 0 -> 15093 bytes .../wheel/__pycache__/metadata.cpython-37.pyc | Bin 0 -> 3693 bytes .../wheel/__pycache__/paths.cpython-37.pyc | Bin 0 -> 1119 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 4572 bytes .../wheel/__pycache__/pkginfo.cpython-37.pyc | Bin 0 -> 1560 bytes .../wheel/__pycache__/util.cpython-37.pyc | Bin 0 -> 4910 bytes .../__pycache__/wininst2wheel.cpython-37.pyc | Bin 0 -> 5358 bytes Lib/site-packages/wheel/archive.py | 77 + Lib/site-packages/wheel/bdist_wheel.py | 409 + Lib/site-packages/wheel/egg2wheel.py | 97 + Lib/site-packages/wheel/install.py | 512 ++ Lib/site-packages/wheel/metadata.py | 130 + Lib/site-packages/wheel/paths.py | 43 + Lib/site-packages/wheel/pep425tags.py | 180 + Lib/site-packages/wheel/pkginfo.py | 43 + .../wheel/signatures/__init__.py | 110 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2908 bytes .../__pycache__/djbec.cpython-37.pyc | Bin 0 -> 9030 bytes .../__pycache__/ed25519py.cpython-37.pyc | Bin 0 -> 1693 bytes .../__pycache__/keys.cpython-37.pyc | Bin 0 -> 4044 bytes Lib/site-packages/wheel/signatures/djbec.py | 323 + .../wheel/signatures/ed25519py.py | 50 + Lib/site-packages/wheel/signatures/keys.py | 101 + Lib/site-packages/wheel/tool/__init__.py | 387 + .../tool/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 11628 bytes Lib/site-packages/wheel/util.py | 156 + Lib/site-packages/wheel/wininst2wheel.py | 219 + Lib/site-packages/wtforms/__init__.py | 16 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 608 bytes .../wtforms/__pycache__/compat.cpython-37.pyc | Bin 0 -> 945 bytes .../wtforms/__pycache__/form.cpython-37.pyc | Bin 0 -> 11525 bytes .../wtforms/__pycache__/i18n.cpython-37.pyc | Bin 0 -> 2801 bytes .../wtforms/__pycache__/meta.cpython-37.pyc | Bin 0 -> 3839 bytes .../wtforms/__pycache__/utils.cpython-37.pyc | Bin 0 -> 2586 bytes .../__pycache__/validators.cpython-37.pyc | Bin 0 -> 20304 bytes Lib/site-packages/wtforms/compat.py | 32 + Lib/site-packages/wtforms/csrf/__init__.py | 0 .../csrf/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 176 bytes .../csrf/__pycache__/core.cpython-37.pyc | Bin 0 -> 3963 bytes .../csrf/__pycache__/session.cpython-37.pyc | Bin 0 -> 3326 bytes Lib/site-packages/wtforms/csrf/core.py | 98 + Lib/site-packages/wtforms/csrf/session.py | 88 + Lib/site-packages/wtforms/ext/__init__.py | 0 .../ext/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 175 bytes .../wtforms/ext/appengine/__init__.py | 8 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 441 bytes .../appengine/__pycache__/db.cpython-37.pyc | Bin 0 -> 18687 bytes .../__pycache__/fields.cpython-37.pyc | Bin 0 -> 8193 bytes .../appengine/__pycache__/ndb.cpython-37.pyc | Bin 0 -> 17774 bytes Lib/site-packages/wtforms/ext/appengine/db.py | 464 + .../wtforms/ext/appengine/fields.py | 215 + .../wtforms/ext/appengine/ndb.py | 418 + .../wtforms/ext/csrf/__init__.py | 1 + .../csrf/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 236 bytes .../csrf/__pycache__/fields.cpython-37.pyc | Bin 0 -> 859 bytes .../ext/csrf/__pycache__/form.cpython-37.pyc | Bin 0 -> 2337 bytes .../csrf/__pycache__/session.cpython-37.pyc | Bin 0 -> 2631 bytes Lib/site-packages/wtforms/ext/csrf/fields.py | 18 + Lib/site-packages/wtforms/ext/csrf/form.py | 53 + Lib/site-packages/wtforms/ext/csrf/session.py | 71 + .../wtforms/ext/dateutil/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 184 bytes .../__pycache__/fields.cpython-37.pyc | Bin 0 -> 3111 bytes .../wtforms/ext/dateutil/fields.py | 97 + .../wtforms/ext/django/__init__.py | 8 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 428 bytes .../django/__pycache__/fields.cpython-37.pyc | Bin 0 -> 5120 bytes .../django/__pycache__/i18n.cpython-37.pyc | Bin 0 -> 1263 bytes .../ext/django/__pycache__/orm.cpython-37.pyc | Bin 0 -> 6617 bytes .../wtforms/ext/django/fields.py | 133 + Lib/site-packages/wtforms/ext/django/i18n.py | 24 + Lib/site-packages/wtforms/ext/django/orm.py | 168 + .../ext/django/templatetags/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 195 bytes .../__pycache__/wtforms.cpython-37.pyc | Bin 0 -> 2929 bytes .../ext/django/templatetags/wtforms.py | 80 + .../wtforms/ext/i18n/__init__.py | 0 .../i18n/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 180 bytes .../ext/i18n/__pycache__/form.cpython-37.pyc | Bin 0 -> 1909 bytes .../ext/i18n/__pycache__/utils.cpython-37.pyc | Bin 0 -> 674 bytes Lib/site-packages/wtforms/ext/i18n/form.py | 45 + Lib/site-packages/wtforms/ext/i18n/utils.py | 15 + .../wtforms/ext/sqlalchemy/__init__.py | 10 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 592 bytes .../__pycache__/fields.cpython-37.pyc | Bin 0 -> 7378 bytes .../sqlalchemy/__pycache__/orm.cpython-37.pyc | Bin 0 -> 9928 bytes .../wtforms/ext/sqlalchemy/fields.py | 190 + .../wtforms/ext/sqlalchemy/orm.py | 304 + Lib/site-packages/wtforms/fields/__init__.py | 7 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 396 bytes .../fields/__pycache__/core.cpython-37.pyc | Bin 0 -> 36065 bytes .../fields/__pycache__/html5.cpython-37.pyc | Bin 0 -> 3248 bytes .../fields/__pycache__/simple.cpython-37.pyc | Bin 0 -> 3257 bytes Lib/site-packages/wtforms/fields/core.py | 1007 ++ Lib/site-packages/wtforms/fields/html5.py | 95 + Lib/site-packages/wtforms/fields/simple.py | 84 + Lib/site-packages/wtforms/form.py | 310 + Lib/site-packages/wtforms/i18n.py | 75 + Lib/site-packages/wtforms/locale/README.md | 22 + .../wtforms/locale/ar/LC_MESSAGES/wtforms.mo | Bin 0 -> 4530 bytes .../wtforms/locale/ar/LC_MESSAGES/wtforms.po | 188 + .../wtforms/locale/bg/LC_MESSAGES/wtforms.mo | Bin 0 -> 4297 bytes .../wtforms/locale/bg/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/ca/LC_MESSAGES/wtforms.mo | Bin 0 -> 3425 bytes .../wtforms/locale/ca/LC_MESSAGES/wtforms.po | 179 + .../locale/cs_CZ/LC_MESSAGES/wtforms.mo | Bin 0 -> 3618 bytes .../locale/cs_CZ/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/cy/LC_MESSAGES/wtforms.mo | Bin 0 -> 3371 bytes .../wtforms/locale/cy/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/de/LC_MESSAGES/wtforms.mo | Bin 0 -> 3412 bytes .../wtforms/locale/de/LC_MESSAGES/wtforms.po | 181 + .../locale/de_CH/LC_MESSAGES/wtforms.mo | Bin 0 -> 3418 bytes .../locale/de_CH/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/el/LC_MESSAGES/wtforms.mo | Bin 0 -> 4307 bytes .../wtforms/locale/el/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/en/LC_MESSAGES/wtforms.mo | Bin 0 -> 3285 bytes .../wtforms/locale/en/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/es/LC_MESSAGES/wtforms.mo | Bin 0 -> 3394 bytes .../wtforms/locale/es/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/et/LC_MESSAGES/wtforms.mo | Bin 0 -> 3456 bytes .../wtforms/locale/et/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/fa/LC_MESSAGES/wtforms.mo | Bin 0 -> 4137 bytes .../wtforms/locale/fa/LC_MESSAGES/wtforms.po | 178 + .../wtforms/locale/fi/LC_MESSAGES/wtforms.mo | Bin 0 -> 3416 bytes .../wtforms/locale/fi/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/fr/LC_MESSAGES/wtforms.mo | Bin 0 -> 3484 bytes .../wtforms/locale/fr/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/he/LC_MESSAGES/wtforms.mo | Bin 0 -> 3649 bytes .../wtforms/locale/he/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/hu/LC_MESSAGES/wtforms.mo | Bin 0 -> 3544 bytes .../wtforms/locale/hu/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/it/LC_MESSAGES/wtforms.mo | Bin 0 -> 3510 bytes .../wtforms/locale/it/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/ja/LC_MESSAGES/wtforms.mo | Bin 0 -> 3736 bytes .../wtforms/locale/ja/LC_MESSAGES/wtforms.po | 177 + .../wtforms/locale/ko/LC_MESSAGES/wtforms.mo | Bin 0 -> 3851 bytes .../wtforms/locale/ko/LC_MESSAGES/wtforms.po | 177 + .../wtforms/locale/nb/LC_MESSAGES/wtforms.mo | Bin 0 -> 3337 bytes .../wtforms/locale/nb/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/nl/LC_MESSAGES/wtforms.mo | Bin 0 -> 3350 bytes .../wtforms/locale/nl/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/pl/LC_MESSAGES/wtforms.mo | Bin 0 -> 3610 bytes .../wtforms/locale/pl/LC_MESSAGES/wtforms.po | 182 + .../wtforms/locale/pt/LC_MESSAGES/wtforms.mo | Bin 0 -> 3438 bytes .../wtforms/locale/pt/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/ru/LC_MESSAGES/wtforms.mo | Bin 0 -> 4406 bytes .../wtforms/locale/ru/LC_MESSAGES/wtforms.po | 184 + .../wtforms/locale/sk/LC_MESSAGES/wtforms.mo | Bin 0 -> 3548 bytes .../wtforms/locale/sk/LC_MESSAGES/wtforms.po | 181 + .../wtforms/locale/sv/LC_MESSAGES/wtforms.mo | Bin 0 -> 3376 bytes .../wtforms/locale/sv/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/tr/LC_MESSAGES/wtforms.mo | Bin 0 -> 3391 bytes .../wtforms/locale/tr/LC_MESSAGES/wtforms.po | 179 + .../wtforms/locale/uk/LC_MESSAGES/wtforms.mo | Bin 0 -> 4451 bytes .../wtforms/locale/uk/LC_MESSAGES/wtforms.po | 182 + Lib/site-packages/wtforms/locale/wtforms.pot | 178 + .../wtforms/locale/zh/LC_MESSAGES/wtforms.mo | Bin 0 -> 3362 bytes .../wtforms/locale/zh/LC_MESSAGES/wtforms.po | 179 + .../locale/zh_TW/LC_MESSAGES/wtforms.mo | Bin 0 -> 3204 bytes .../locale/zh_TW/LC_MESSAGES/wtforms.po | 177 + Lib/site-packages/wtforms/meta.py | 121 + Lib/site-packages/wtforms/utils.py | 54 + Lib/site-packages/wtforms/validators.py | 582 ++ Lib/site-packages/wtforms/widgets/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 287 bytes .../widgets/__pycache__/core.cpython-37.pyc | Bin 0 -> 12473 bytes .../widgets/__pycache__/html5.cpython-37.pyc | Bin 0 -> 3939 bytes Lib/site-packages/wtforms/widgets/core.py | 348 + Lib/site-packages/wtforms/widgets/html5.py | 124 + Lib/site.py | 758 ++ Lib/sre_compile.py | 784 ++ Lib/sre_constants.py | 261 + Lib/sre_parse.py | 1046 +++ Lib/stat.py | 178 + Lib/struct.py | 15 + Lib/tarfile.py | 2537 +++++ Lib/tempfile.py | 809 ++ Lib/token.py | 160 + Lib/tokenize.py | 726 ++ Lib/types.py | 295 + Lib/warnings.py | 554 ++ Lib/weakref.py | 632 ++ Questions/question.html | 24 + Questions/questions.py | 0 Questions/test.py | 0 Questions/test_Questions.py | 0 Scripts/activate | 78 + Scripts/activate.bat | 30 + Scripts/activate.ps1 | 150 + Scripts/activate_this.py | 34 + Scripts/deactivate.bat | 19 + Scripts/easy_install-3.7.exe | Bin 0 -> 102806 bytes Scripts/easy_install.exe | Bin 0 -> 102806 bytes Scripts/flask.exe | Bin 0 -> 102784 bytes Scripts/pip.exe | Bin 0 -> 102788 bytes Scripts/pip3.7.exe | Bin 0 -> 102788 bytes Scripts/pip3.exe | Bin 0 -> 102788 bytes Scripts/py.test.exe | Bin 0 -> 102781 bytes Scripts/pytest.exe | Bin 0 -> 102781 bytes Scripts/python.exe | Bin 0 -> 99992 bytes Scripts/python3.dll | Bin 0 -> 59032 bytes Scripts/python37.dll | Bin 0 -> 3844760 bytes Scripts/pythonw.exe | Bin 0 -> 98456 bytes Scripts/wheel.exe | Bin 0 -> 102785 bytes StackOverflow-LiteAPI.travis.yml | 4 + Static/main.js | 0 Static/mains.css | 317 + Users/Users.py | 18 + Users/test_Users.py | 0 __pycache__/run.cpython-37.pyc | Bin 0 -> 1255 bytes pip-selfcheck.json | 1 + requirements.txt | 16 + run.py | 41 + tcl/tcl8.6/auto.tcl | 646 ++ tcl/tcl8.6/clock.tcl | 4547 +++++++++ tcl/tcl8.6/encoding/ascii.enc | 20 + tcl/tcl8.6/encoding/big5.enc | 1516 +++ tcl/tcl8.6/encoding/cp1250.enc | 20 + tcl/tcl8.6/encoding/cp1251.enc | 20 + tcl/tcl8.6/encoding/cp1252.enc | 20 + tcl/tcl8.6/encoding/cp1253.enc | 20 + tcl/tcl8.6/encoding/cp1254.enc | 20 + tcl/tcl8.6/encoding/cp1255.enc | 20 + tcl/tcl8.6/encoding/cp1256.enc | 20 + tcl/tcl8.6/encoding/cp1257.enc | 20 + tcl/tcl8.6/encoding/cp1258.enc | 20 + tcl/tcl8.6/encoding/cp437.enc | 20 + tcl/tcl8.6/encoding/cp737.enc | 20 + tcl/tcl8.6/encoding/cp775.enc | 20 + tcl/tcl8.6/encoding/cp850.enc | 20 + tcl/tcl8.6/encoding/cp852.enc | 20 + tcl/tcl8.6/encoding/cp855.enc | 20 + tcl/tcl8.6/encoding/cp857.enc | 20 + tcl/tcl8.6/encoding/cp860.enc | 20 + tcl/tcl8.6/encoding/cp861.enc | 20 + tcl/tcl8.6/encoding/cp862.enc | 20 + tcl/tcl8.6/encoding/cp863.enc | 20 + tcl/tcl8.6/encoding/cp864.enc | 20 + tcl/tcl8.6/encoding/cp865.enc | 20 + tcl/tcl8.6/encoding/cp866.enc | 20 + tcl/tcl8.6/encoding/cp869.enc | 20 + tcl/tcl8.6/encoding/cp874.enc | 20 + tcl/tcl8.6/encoding/cp932.enc | 801 ++ tcl/tcl8.6/encoding/cp936.enc | 2162 +++++ tcl/tcl8.6/encoding/cp949.enc | 2128 +++++ tcl/tcl8.6/encoding/cp950.enc | 1499 +++ tcl/tcl8.6/encoding/dingbats.enc | 20 + tcl/tcl8.6/encoding/ebcdic.enc | 19 + tcl/tcl8.6/encoding/euc-cn.enc | 1397 +++ tcl/tcl8.6/encoding/euc-jp.enc | 1353 +++ tcl/tcl8.6/encoding/euc-kr.enc | 1533 +++ tcl/tcl8.6/encoding/gb12345.enc | 1414 +++ tcl/tcl8.6/encoding/gb1988.enc | 20 + tcl/tcl8.6/encoding/gb2312-raw.enc | 1380 +++ tcl/tcl8.6/encoding/gb2312.enc | 1397 +++ tcl/tcl8.6/encoding/iso2022-jp.enc | 12 + tcl/tcl8.6/encoding/iso2022-kr.enc | 7 + tcl/tcl8.6/encoding/iso2022.enc | 14 + tcl/tcl8.6/encoding/iso8859-1.enc | 20 + tcl/tcl8.6/encoding/iso8859-10.enc | 20 + tcl/tcl8.6/encoding/iso8859-13.enc | 20 + tcl/tcl8.6/encoding/iso8859-14.enc | 20 + tcl/tcl8.6/encoding/iso8859-15.enc | 20 + tcl/tcl8.6/encoding/iso8859-16.enc | 20 + tcl/tcl8.6/encoding/iso8859-2.enc | 20 + tcl/tcl8.6/encoding/iso8859-3.enc | 20 + tcl/tcl8.6/encoding/iso8859-4.enc | 20 + tcl/tcl8.6/encoding/iso8859-5.enc | 20 + tcl/tcl8.6/encoding/iso8859-6.enc | 20 + tcl/tcl8.6/encoding/iso8859-7.enc | 20 + tcl/tcl8.6/encoding/iso8859-8.enc | 20 + tcl/tcl8.6/encoding/iso8859-9.enc | 20 + tcl/tcl8.6/encoding/jis0201.enc | 20 + tcl/tcl8.6/encoding/jis0208.enc | 1319 +++ tcl/tcl8.6/encoding/jis0212.enc | 1159 +++ tcl/tcl8.6/encoding/koi8-r.enc | 20 + tcl/tcl8.6/encoding/koi8-u.enc | 20 + tcl/tcl8.6/encoding/ksc5601.enc | 1516 +++ tcl/tcl8.6/encoding/macCentEuro.enc | 20 + tcl/tcl8.6/encoding/macCroatian.enc | 20 + tcl/tcl8.6/encoding/macCyrillic.enc | 20 + tcl/tcl8.6/encoding/macDingbats.enc | 20 + tcl/tcl8.6/encoding/macGreek.enc | 20 + tcl/tcl8.6/encoding/macIceland.enc | 20 + tcl/tcl8.6/encoding/macJapan.enc | 785 ++ tcl/tcl8.6/encoding/macRoman.enc | 20 + tcl/tcl8.6/encoding/macRomania.enc | 20 + tcl/tcl8.6/encoding/macThai.enc | 20 + tcl/tcl8.6/encoding/macTurkish.enc | 20 + tcl/tcl8.6/encoding/macUkraine.enc | 20 + tcl/tcl8.6/encoding/shiftjis.enc | 690 ++ tcl/tcl8.6/encoding/symbol.enc | 20 + tcl/tcl8.6/encoding/tis-620.enc | 20 + tcl/tcl8.6/history.tcl | 335 + tcl/tcl8.6/http1.0/http.tcl | 377 + tcl/tcl8.6/http1.0/pkgIndex.tcl | 11 + tcl/tcl8.6/init.tcl | 819 ++ tcl/tcl8.6/msgs/af.msg | 49 + tcl/tcl8.6/msgs/af_za.msg | 6 + tcl/tcl8.6/msgs/ar.msg | 54 + tcl/tcl8.6/msgs/ar_in.msg | 6 + tcl/tcl8.6/msgs/ar_jo.msg | 39 + tcl/tcl8.6/msgs/ar_lb.msg | 39 + tcl/tcl8.6/msgs/ar_sy.msg | 39 + tcl/tcl8.6/msgs/be.msg | 52 + tcl/tcl8.6/msgs/bg.msg | 52 + tcl/tcl8.6/msgs/bn.msg | 49 + tcl/tcl8.6/msgs/bn_in.msg | 6 + tcl/tcl8.6/msgs/ca.msg | 50 + tcl/tcl8.6/msgs/cs.msg | 54 + tcl/tcl8.6/msgs/da.msg | 52 + tcl/tcl8.6/msgs/de.msg | 54 + tcl/tcl8.6/msgs/de_at.msg | 35 + tcl/tcl8.6/msgs/de_be.msg | 53 + tcl/tcl8.6/msgs/el.msg | 52 + tcl/tcl8.6/msgs/en_au.msg | 7 + tcl/tcl8.6/msgs/en_be.msg | 7 + tcl/tcl8.6/msgs/en_bw.msg | 6 + tcl/tcl8.6/msgs/en_ca.msg | 7 + tcl/tcl8.6/msgs/en_gb.msg | 7 + tcl/tcl8.6/msgs/en_hk.msg | 8 + tcl/tcl8.6/msgs/en_ie.msg | 7 + tcl/tcl8.6/msgs/en_in.msg | 8 + tcl/tcl8.6/msgs/en_nz.msg | 7 + tcl/tcl8.6/msgs/en_ph.msg | 8 + tcl/tcl8.6/msgs/en_sg.msg | 6 + tcl/tcl8.6/msgs/en_za.msg | 6 + tcl/tcl8.6/msgs/en_zw.msg | 6 + tcl/tcl8.6/msgs/eo.msg | 54 + tcl/tcl8.6/msgs/es.msg | 52 + tcl/tcl8.6/msgs/es_ar.msg | 6 + tcl/tcl8.6/msgs/es_bo.msg | 6 + tcl/tcl8.6/msgs/es_cl.msg | 6 + tcl/tcl8.6/msgs/es_co.msg | 6 + tcl/tcl8.6/msgs/es_cr.msg | 6 + tcl/tcl8.6/msgs/es_do.msg | 6 + tcl/tcl8.6/msgs/es_ec.msg | 6 + tcl/tcl8.6/msgs/es_gt.msg | 6 + tcl/tcl8.6/msgs/es_hn.msg | 6 + tcl/tcl8.6/msgs/es_mx.msg | 6 + tcl/tcl8.6/msgs/es_ni.msg | 6 + tcl/tcl8.6/msgs/es_pa.msg | 6 + tcl/tcl8.6/msgs/es_pe.msg | 6 + tcl/tcl8.6/msgs/es_pr.msg | 6 + tcl/tcl8.6/msgs/es_py.msg | 6 + tcl/tcl8.6/msgs/es_sv.msg | 6 + tcl/tcl8.6/msgs/es_uy.msg | 6 + tcl/tcl8.6/msgs/es_ve.msg | 6 + tcl/tcl8.6/msgs/et.msg | 52 + tcl/tcl8.6/msgs/eu.msg | 47 + tcl/tcl8.6/msgs/eu_es.msg | 7 + tcl/tcl8.6/msgs/fa.msg | 47 + tcl/tcl8.6/msgs/fa_in.msg | 52 + tcl/tcl8.6/msgs/fa_ir.msg | 9 + tcl/tcl8.6/msgs/fi.msg | 50 + tcl/tcl8.6/msgs/fo.msg | 47 + tcl/tcl8.6/msgs/fo_fo.msg | 7 + tcl/tcl8.6/msgs/fr.msg | 52 + tcl/tcl8.6/msgs/fr_be.msg | 7 + tcl/tcl8.6/msgs/fr_ca.msg | 7 + tcl/tcl8.6/msgs/fr_ch.msg | 7 + tcl/tcl8.6/msgs/ga.msg | 47 + tcl/tcl8.6/msgs/ga_ie.msg | 7 + tcl/tcl8.6/msgs/gl.msg | 47 + tcl/tcl8.6/msgs/gl_es.msg | 6 + tcl/tcl8.6/msgs/gv.msg | 47 + tcl/tcl8.6/msgs/gv_gb.msg | 6 + tcl/tcl8.6/msgs/he.msg | 52 + tcl/tcl8.6/msgs/hi.msg | 39 + tcl/tcl8.6/msgs/hi_in.msg | 6 + tcl/tcl8.6/msgs/hr.msg | 50 + tcl/tcl8.6/msgs/hu.msg | 54 + tcl/tcl8.6/msgs/id.msg | 47 + tcl/tcl8.6/msgs/id_id.msg | 6 + tcl/tcl8.6/msgs/is.msg | 50 + tcl/tcl8.6/msgs/it.msg | 54 + tcl/tcl8.6/msgs/it_ch.msg | 6 + tcl/tcl8.6/msgs/ja.msg | 44 + tcl/tcl8.6/msgs/kl.msg | 47 + tcl/tcl8.6/msgs/kl_gl.msg | 7 + tcl/tcl8.6/msgs/ko.msg | 55 + tcl/tcl8.6/msgs/ko_kr.msg | 8 + tcl/tcl8.6/msgs/kok.msg | 39 + tcl/tcl8.6/msgs/kok_in.msg | 6 + tcl/tcl8.6/msgs/kw.msg | 47 + tcl/tcl8.6/msgs/kw_gb.msg | 6 + tcl/tcl8.6/msgs/lt.msg | 52 + tcl/tcl8.6/msgs/lv.msg | 52 + tcl/tcl8.6/msgs/mk.msg | 52 + tcl/tcl8.6/msgs/mr.msg | 39 + tcl/tcl8.6/msgs/mr_in.msg | 6 + tcl/tcl8.6/msgs/ms.msg | 47 + tcl/tcl8.6/msgs/ms_my.msg | 6 + tcl/tcl8.6/msgs/mt.msg | 27 + tcl/tcl8.6/msgs/nb.msg | 52 + tcl/tcl8.6/msgs/nl.msg | 50 + tcl/tcl8.6/msgs/nl_be.msg | 7 + tcl/tcl8.6/msgs/nn.msg | 52 + tcl/tcl8.6/msgs/pl.msg | 52 + tcl/tcl8.6/msgs/pt.msg | 50 + tcl/tcl8.6/msgs/pt_br.msg | 7 + tcl/tcl8.6/msgs/ro.msg | 52 + tcl/tcl8.6/msgs/ru.msg | 52 + tcl/tcl8.6/msgs/ru_ua.msg | 6 + tcl/tcl8.6/msgs/sh.msg | 52 + tcl/tcl8.6/msgs/sk.msg | 52 + tcl/tcl8.6/msgs/sl.msg | 52 + tcl/tcl8.6/msgs/sq.msg | 54 + tcl/tcl8.6/msgs/sr.msg | 52 + tcl/tcl8.6/msgs/sv.msg | 52 + tcl/tcl8.6/msgs/sw.msg | 49 + tcl/tcl8.6/msgs/ta.msg | 39 + tcl/tcl8.6/msgs/ta_in.msg | 6 + tcl/tcl8.6/msgs/te.msg | 47 + tcl/tcl8.6/msgs/te_in.msg | 8 + tcl/tcl8.6/msgs/th.msg | 54 + tcl/tcl8.6/msgs/tr.msg | 50 + tcl/tcl8.6/msgs/uk.msg | 52 + tcl/tcl8.6/msgs/vi.msg | 50 + tcl/tcl8.6/msgs/zh.msg | 55 + tcl/tcl8.6/msgs/zh_cn.msg | 7 + tcl/tcl8.6/msgs/zh_hk.msg | 28 + tcl/tcl8.6/msgs/zh_sg.msg | 8 + tcl/tcl8.6/msgs/zh_tw.msg | 8 + tcl/tcl8.6/opt0.4/optparse.tcl | 1072 +++ tcl/tcl8.6/opt0.4/pkgIndex.tcl | 12 + tcl/tcl8.6/package.tcl | 747 ++ tcl/tcl8.6/parray.tcl | 28 + tcl/tcl8.6/safe.tcl | 1133 +++ tcl/tcl8.6/tclIndex | 75 + tcl/tcl8.6/tm.tcl | 375 + tcl/tcl8.6/tzdata/Africa/Abidjan | 6 + tcl/tcl8.6/tzdata/Africa/Accra | 52 + tcl/tcl8.6/tzdata/Africa/Addis_Ababa | 5 + tcl/tcl8.6/tzdata/Africa/Algiers | 39 + tcl/tcl8.6/tzdata/Africa/Asmara | 5 + tcl/tcl8.6/tzdata/Africa/Asmera | 5 + tcl/tcl8.6/tzdata/Africa/Bamako | 5 + tcl/tcl8.6/tzdata/Africa/Bangui | 5 + tcl/tcl8.6/tzdata/Africa/Banjul | 5 + tcl/tcl8.6/tzdata/Africa/Bissau | 7 + tcl/tcl8.6/tzdata/Africa/Blantyre | 5 + tcl/tcl8.6/tzdata/Africa/Brazzaville | 5 + tcl/tcl8.6/tzdata/Africa/Bujumbura | 5 + tcl/tcl8.6/tzdata/Africa/Cairo | 132 + tcl/tcl8.6/tzdata/Africa/Casablanca | 230 + tcl/tcl8.6/tzdata/Africa/Ceuta | 258 + tcl/tcl8.6/tzdata/Africa/Conakry | 5 + tcl/tcl8.6/tzdata/Africa/Dakar | 5 + tcl/tcl8.6/tzdata/Africa/Dar_es_Salaam | 5 + tcl/tcl8.6/tzdata/Africa/Djibouti | 5 + tcl/tcl8.6/tzdata/Africa/Douala | 5 + tcl/tcl8.6/tzdata/Africa/El_Aaiun | 219 + tcl/tcl8.6/tzdata/Africa/Freetown | 5 + tcl/tcl8.6/tzdata/Africa/Gaborone | 5 + tcl/tcl8.6/tzdata/Africa/Harare | 5 + tcl/tcl8.6/tzdata/Africa/Johannesburg | 11 + tcl/tcl8.6/tzdata/Africa/Juba | 39 + tcl/tcl8.6/tzdata/Africa/Kampala | 5 + tcl/tcl8.6/tzdata/Africa/Khartoum | 40 + tcl/tcl8.6/tzdata/Africa/Kigali | 5 + tcl/tcl8.6/tzdata/Africa/Kinshasa | 5 + tcl/tcl8.6/tzdata/Africa/Lagos | 6 + tcl/tcl8.6/tzdata/Africa/Libreville | 5 + tcl/tcl8.6/tzdata/Africa/Lome | 5 + tcl/tcl8.6/tzdata/Africa/Luanda | 5 + tcl/tcl8.6/tzdata/Africa/Lubumbashi | 5 + tcl/tcl8.6/tzdata/Africa/Lusaka | 5 + tcl/tcl8.6/tzdata/Africa/Malabo | 5 + tcl/tcl8.6/tzdata/Africa/Maputo | 6 + tcl/tcl8.6/tzdata/Africa/Maseru | 5 + tcl/tcl8.6/tzdata/Africa/Mbabane | 5 + tcl/tcl8.6/tzdata/Africa/Mogadishu | 5 + tcl/tcl8.6/tzdata/Africa/Monrovia | 8 + tcl/tcl8.6/tzdata/Africa/Nairobi | 9 + tcl/tcl8.6/tzdata/Africa/Ndjamena | 8 + tcl/tcl8.6/tzdata/Africa/Niamey | 5 + tcl/tcl8.6/tzdata/Africa/Nouakchott | 5 + tcl/tcl8.6/tzdata/Africa/Ouagadougou | 5 + tcl/tcl8.6/tzdata/Africa/Porto-Novo | 5 + tcl/tcl8.6/tzdata/Africa/Sao_Tome | 5 + tcl/tcl8.6/tzdata/Africa/Timbuktu | 5 + tcl/tcl8.6/tzdata/Africa/Tripoli | 34 + tcl/tcl8.6/tzdata/Africa/Tunis | 39 + tcl/tcl8.6/tzdata/Africa/Windhoek | 59 + tcl/tcl8.6/tzdata/America/Adak | 276 + tcl/tcl8.6/tzdata/America/Anchorage | 275 + tcl/tcl8.6/tzdata/America/Anguilla | 5 + tcl/tcl8.6/tzdata/America/Antigua | 5 + tcl/tcl8.6/tzdata/America/Araguaina | 60 + .../tzdata/America/Argentina/Buenos_Aires | 67 + tcl/tcl8.6/tzdata/America/Argentina/Catamarca | 68 + .../tzdata/America/Argentina/ComodRivadavia | 5 + tcl/tcl8.6/tzdata/America/Argentina/Cordoba | 67 + tcl/tcl8.6/tzdata/America/Argentina/Jujuy | 67 + tcl/tcl8.6/tzdata/America/Argentina/La_Rioja | 69 + tcl/tcl8.6/tzdata/America/Argentina/Mendoza | 68 + .../tzdata/America/Argentina/Rio_Gallegos | 68 + tcl/tcl8.6/tzdata/America/Argentina/Salta | 66 + tcl/tcl8.6/tzdata/America/Argentina/San_Juan | 69 + tcl/tcl8.6/tzdata/America/Argentina/San_Luis | 68 + tcl/tcl8.6/tzdata/America/Argentina/Tucuman | 69 + tcl/tcl8.6/tzdata/America/Argentina/Ushuaia | 68 + tcl/tcl8.6/tzdata/America/Aruba | 5 + tcl/tcl8.6/tzdata/America/Asuncion | 259 + tcl/tcl8.6/tzdata/America/Atikokan | 12 + tcl/tcl8.6/tzdata/America/Atka | 5 + tcl/tcl8.6/tzdata/America/Bahia | 68 + tcl/tcl8.6/tzdata/America/Bahia_Banderas | 222 + tcl/tcl8.6/tzdata/America/Barbados | 15 + tcl/tcl8.6/tzdata/America/Belem | 35 + tcl/tcl8.6/tzdata/America/Belize | 60 + tcl/tcl8.6/tzdata/America/Blanc-Sablon | 12 + tcl/tcl8.6/tzdata/America/Boa_Vista | 40 + tcl/tcl8.6/tzdata/America/Bogota | 9 + tcl/tcl8.6/tzdata/America/Boise | 281 + tcl/tcl8.6/tzdata/America/Buenos_Aires | 5 + tcl/tcl8.6/tzdata/America/Cambridge_Bay | 252 + tcl/tcl8.6/tzdata/America/Campo_Grande | 257 + tcl/tcl8.6/tzdata/America/Cancun | 47 + tcl/tcl8.6/tzdata/America/Caracas | 10 + tcl/tcl8.6/tzdata/America/Catamarca | 5 + tcl/tcl8.6/tzdata/America/Cayenne | 7 + tcl/tcl8.6/tzdata/America/Cayman | 5 + tcl/tcl8.6/tzdata/America/Chicago | 369 + tcl/tcl8.6/tzdata/America/Chihuahua | 221 + tcl/tcl8.6/tzdata/America/Coral_Harbour | 5 + tcl/tcl8.6/tzdata/America/Cordoba | 5 + tcl/tcl8.6/tzdata/America/Costa_Rica | 15 + tcl/tcl8.6/tzdata/America/Creston | 8 + tcl/tcl8.6/tzdata/America/Cuiaba | 257 + tcl/tcl8.6/tzdata/America/Curacao | 7 + tcl/tcl8.6/tzdata/America/Danmarkshavn | 39 + tcl/tcl8.6/tzdata/America/Dawson | 256 + tcl/tcl8.6/tzdata/America/Dawson_Creek | 64 + tcl/tcl8.6/tzdata/America/Denver | 291 + tcl/tcl8.6/tzdata/America/Detroit | 270 + tcl/tcl8.6/tzdata/America/Dominica | 5 + tcl/tcl8.6/tzdata/America/Edmonton | 284 + tcl/tcl8.6/tzdata/America/Eirunepe | 41 + tcl/tcl8.6/tzdata/America/El_Salvador | 10 + tcl/tcl8.6/tzdata/America/Ensenada | 5 + tcl/tcl8.6/tzdata/America/Fort_Nelson | 151 + tcl/tcl8.6/tzdata/America/Fort_Wayne | 5 + tcl/tcl8.6/tzdata/America/Fortaleza | 48 + tcl/tcl8.6/tzdata/America/Glace_Bay | 273 + tcl/tcl8.6/tzdata/America/Godthab | 246 + tcl/tcl8.6/tzdata/America/Goose_Bay | 338 + tcl/tcl8.6/tzdata/America/Grand_Turk | 246 + tcl/tcl8.6/tzdata/America/Grenada | 5 + tcl/tcl8.6/tzdata/America/Guadeloupe | 5 + tcl/tcl8.6/tzdata/America/Guatemala | 14 + tcl/tcl8.6/tzdata/America/Guayaquil | 9 + tcl/tcl8.6/tzdata/America/Guyana | 8 + tcl/tcl8.6/tzdata/America/Halifax | 361 + tcl/tcl8.6/tzdata/America/Havana | 285 + tcl/tcl8.6/tzdata/America/Hermosillo | 21 + .../tzdata/America/Indiana/Indianapolis | 234 + tcl/tcl8.6/tzdata/America/Indiana/Knox | 285 + tcl/tcl8.6/tzdata/America/Indiana/Marengo | 236 + tcl/tcl8.6/tzdata/America/Indiana/Petersburg | 247 + tcl/tcl8.6/tzdata/America/Indiana/Tell_City | 234 + tcl/tcl8.6/tzdata/America/Indiana/Vevay | 213 + tcl/tcl8.6/tzdata/America/Indiana/Vincennes | 234 + tcl/tcl8.6/tzdata/America/Indiana/Winamac | 240 + tcl/tcl8.6/tzdata/America/Indianapolis | 5 + tcl/tcl8.6/tzdata/America/Inuvik | 249 + tcl/tcl8.6/tzdata/America/Iqaluit | 250 + tcl/tcl8.6/tzdata/America/Jamaica | 29 + tcl/tcl8.6/tzdata/America/Jujuy | 5 + tcl/tcl8.6/tzdata/America/Juneau | 276 + tcl/tcl8.6/tzdata/America/Kentucky/Louisville | 314 + tcl/tcl8.6/tzdata/America/Kentucky/Monticello | 279 + tcl/tcl8.6/tzdata/America/Knox_IN | 5 + tcl/tcl8.6/tzdata/America/Kralendijk | 5 + tcl/tcl8.6/tzdata/America/La_Paz | 8 + tcl/tcl8.6/tzdata/America/Lima | 16 + tcl/tcl8.6/tzdata/America/Los_Angeles | 317 + tcl/tcl8.6/tzdata/America/Louisville | 5 + tcl/tcl8.6/tzdata/America/Lower_Princes | 5 + tcl/tcl8.6/tzdata/America/Maceio | 52 + tcl/tcl8.6/tzdata/America/Managua | 21 + tcl/tcl8.6/tzdata/America/Manaus | 39 + tcl/tcl8.6/tzdata/America/Marigot | 5 + tcl/tcl8.6/tzdata/America/Martinique | 9 + tcl/tcl8.6/tzdata/America/Matamoros | 219 + tcl/tcl8.6/tzdata/America/Mazatlan | 222 + tcl/tcl8.6/tzdata/America/Mendoza | 5 + tcl/tcl8.6/tzdata/America/Menominee | 274 + tcl/tcl8.6/tzdata/America/Merida | 216 + tcl/tcl8.6/tzdata/America/Metlakatla | 212 + tcl/tcl8.6/tzdata/America/Mexico_City | 228 + tcl/tcl8.6/tzdata/America/Miquelon | 234 + tcl/tcl8.6/tzdata/America/Moncton | 342 + tcl/tcl8.6/tzdata/America/Monterrey | 218 + tcl/tcl8.6/tzdata/America/Montevideo | 96 + tcl/tcl8.6/tzdata/America/Montreal | 5 + tcl/tcl8.6/tzdata/America/Montserrat | 5 + tcl/tcl8.6/tzdata/America/Nassau | 279 + tcl/tcl8.6/tzdata/America/New_York | 369 + tcl/tcl8.6/tzdata/America/Nipigon | 264 + tcl/tcl8.6/tzdata/America/Nome | 276 + tcl/tcl8.6/tzdata/America/Noronha | 48 + tcl/tcl8.6/tzdata/America/North_Dakota/Beulah | 279 + tcl/tcl8.6/tzdata/America/North_Dakota/Center | 279 + .../tzdata/America/North_Dakota/New_Salem | 279 + tcl/tcl8.6/tzdata/America/Ojinaga | 222 + tcl/tcl8.6/tzdata/America/Panama | 7 + tcl/tcl8.6/tzdata/America/Pangnirtung | 252 + tcl/tcl8.6/tzdata/America/Paramaribo | 9 + tcl/tcl8.6/tzdata/America/Phoenix | 17 + tcl/tcl8.6/tzdata/America/Port-au-Prince | 215 + tcl/tcl8.6/tzdata/America/Port_of_Spain | 6 + tcl/tcl8.6/tzdata/America/Porto_Acre | 5 + tcl/tcl8.6/tzdata/America/Porto_Velho | 35 + tcl/tcl8.6/tzdata/America/Puerto_Rico | 10 + tcl/tcl8.6/tzdata/America/Punta_Arenas | 122 + tcl/tcl8.6/tzdata/America/Rainy_River | 264 + tcl/tcl8.6/tzdata/America/Rankin_Inlet | 248 + tcl/tcl8.6/tzdata/America/Recife | 48 + tcl/tcl8.6/tzdata/America/Regina | 58 + tcl/tcl8.6/tzdata/America/Resolute | 248 + tcl/tcl8.6/tzdata/America/Rio_Branco | 37 + tcl/tcl8.6/tzdata/America/Rosario | 5 + tcl/tcl8.6/tzdata/America/Santa_Isabel | 5 + tcl/tcl8.6/tzdata/America/Santarem | 36 + tcl/tcl8.6/tzdata/America/Santiago | 289 + tcl/tcl8.6/tzdata/America/Santo_Domingo | 21 + tcl/tcl8.6/tzdata/America/Sao_Paulo | 258 + tcl/tcl8.6/tzdata/America/Scoresbysund | 246 + tcl/tcl8.6/tzdata/America/Shiprock | 5 + tcl/tcl8.6/tzdata/America/Sitka | 275 + tcl/tcl8.6/tzdata/America/St_Barthelemy | 5 + tcl/tcl8.6/tzdata/America/St_Johns | 372 + tcl/tcl8.6/tzdata/America/St_Kitts | 5 + tcl/tcl8.6/tzdata/America/St_Lucia | 5 + tcl/tcl8.6/tzdata/America/St_Thomas | 5 + tcl/tcl8.6/tzdata/America/St_Vincent | 5 + tcl/tcl8.6/tzdata/America/Swift_Current | 29 + tcl/tcl8.6/tzdata/America/Tegucigalpa | 12 + tcl/tcl8.6/tzdata/America/Thule | 224 + tcl/tcl8.6/tzdata/America/Thunder_Bay | 272 + tcl/tcl8.6/tzdata/America/Tijuana | 285 + tcl/tcl8.6/tzdata/America/Toronto | 365 + tcl/tcl8.6/tzdata/America/Tortola | 5 + tcl/tcl8.6/tzdata/America/Vancouver | 320 + tcl/tcl8.6/tzdata/America/Virgin | 5 + tcl/tcl8.6/tzdata/America/Whitehorse | 256 + tcl/tcl8.6/tzdata/America/Winnipeg | 316 + tcl/tcl8.6/tzdata/America/Yakutat | 276 + tcl/tcl8.6/tzdata/America/Yellowknife | 252 + tcl/tcl8.6/tzdata/Antarctica/Casey | 11 + tcl/tcl8.6/tzdata/Antarctica/Davis | 12 + tcl/tcl8.6/tzdata/Antarctica/DumontDUrville | 8 + tcl/tcl8.6/tzdata/Antarctica/Macquarie | 97 + tcl/tcl8.6/tzdata/Antarctica/Mawson | 7 + tcl/tcl8.6/tzdata/Antarctica/McMurdo | 5 + tcl/tcl8.6/tzdata/Antarctica/Palmer | 87 + tcl/tcl8.6/tzdata/Antarctica/Rothera | 6 + tcl/tcl8.6/tzdata/Antarctica/South_Pole | 5 + tcl/tcl8.6/tzdata/Antarctica/Syowa | 6 + tcl/tcl8.6/tzdata/Antarctica/Troll | 196 + tcl/tcl8.6/tzdata/Antarctica/Vostok | 6 + tcl/tcl8.6/tzdata/Arctic/Longyearbyen | 5 + tcl/tcl8.6/tzdata/Asia/Aden | 5 + tcl/tcl8.6/tzdata/Asia/Almaty | 57 + tcl/tcl8.6/tzdata/Asia/Amman | 246 + tcl/tcl8.6/tzdata/Asia/Anadyr | 72 + tcl/tcl8.6/tzdata/Asia/Aqtau | 58 + tcl/tcl8.6/tzdata/Asia/Aqtobe | 58 + tcl/tcl8.6/tzdata/Asia/Ashgabat | 31 + tcl/tcl8.6/tzdata/Asia/Ashkhabad | 5 + tcl/tcl8.6/tzdata/Asia/Atyrau | 58 + tcl/tcl8.6/tzdata/Asia/Baghdad | 59 + tcl/tcl8.6/tzdata/Asia/Bahrain | 5 + tcl/tcl8.6/tzdata/Asia/Baku | 74 + tcl/tcl8.6/tzdata/Asia/Bangkok | 7 + tcl/tcl8.6/tzdata/Asia/Barnaul | 73 + tcl/tcl8.6/tzdata/Asia/Beirut | 270 + tcl/tcl8.6/tzdata/Asia/Bishkek | 58 + tcl/tcl8.6/tzdata/Asia/Brunei | 7 + tcl/tcl8.6/tzdata/Asia/Calcutta | 5 + tcl/tcl8.6/tzdata/Asia/Chita | 72 + tcl/tcl8.6/tzdata/Asia/Choibalsan | 56 + tcl/tcl8.6/tzdata/Asia/Chongqing | 5 + tcl/tcl8.6/tzdata/Asia/Chungking | 5 + tcl/tcl8.6/tzdata/Asia/Colombo | 13 + tcl/tcl8.6/tzdata/Asia/Dacca | 5 + tcl/tcl8.6/tzdata/Asia/Damascus | 280 + tcl/tcl8.6/tzdata/Asia/Dhaka | 13 + tcl/tcl8.6/tzdata/Asia/Dili | 9 + tcl/tcl8.6/tzdata/Asia/Dubai | 6 + tcl/tcl8.6/tzdata/Asia/Dushanbe | 29 + tcl/tcl8.6/tzdata/Asia/Famagusta | 256 + tcl/tcl8.6/tzdata/Asia/Gaza | 278 + tcl/tcl8.6/tzdata/Asia/Harbin | 5 + tcl/tcl8.6/tzdata/Asia/Hebron | 277 + tcl/tcl8.6/tzdata/Asia/Ho_Chi_Minh | 14 + tcl/tcl8.6/tzdata/Asia/Hong_Kong | 75 + tcl/tcl8.6/tzdata/Asia/Hovd | 55 + tcl/tcl8.6/tzdata/Asia/Irkutsk | 72 + tcl/tcl8.6/tzdata/Asia/Istanbul | 5 + tcl/tcl8.6/tzdata/Asia/Jakarta | 13 + tcl/tcl8.6/tzdata/Asia/Jayapura | 8 + tcl/tcl8.6/tzdata/Asia/Jerusalem | 272 + tcl/tcl8.6/tzdata/Asia/Kabul | 7 + tcl/tcl8.6/tzdata/Asia/Kamchatka | 71 + tcl/tcl8.6/tzdata/Asia/Karachi | 16 + tcl/tcl8.6/tzdata/Asia/Kashgar | 5 + tcl/tcl8.6/tzdata/Asia/Kathmandu | 7 + tcl/tcl8.6/tzdata/Asia/Katmandu | 5 + tcl/tcl8.6/tzdata/Asia/Khandyga | 73 + tcl/tcl8.6/tzdata/Asia/Kolkata | 12 + tcl/tcl8.6/tzdata/Asia/Krasnoyarsk | 71 + tcl/tcl8.6/tzdata/Asia/Kuala_Lumpur | 13 + tcl/tcl8.6/tzdata/Asia/Kuching | 23 + tcl/tcl8.6/tzdata/Asia/Kuwait | 5 + tcl/tcl8.6/tzdata/Asia/Macao | 5 + tcl/tcl8.6/tzdata/Asia/Macau | 46 + tcl/tcl8.6/tzdata/Asia/Magadan | 72 + tcl/tcl8.6/tzdata/Asia/Makassar | 9 + tcl/tcl8.6/tzdata/Asia/Manila | 15 + tcl/tcl8.6/tzdata/Asia/Muscat | 5 + tcl/tcl8.6/tzdata/Asia/Nicosia | 257 + tcl/tcl8.6/tzdata/Asia/Novokuznetsk | 71 + tcl/tcl8.6/tzdata/Asia/Novosibirsk | 73 + tcl/tcl8.6/tzdata/Asia/Omsk | 71 + tcl/tcl8.6/tzdata/Asia/Oral | 58 + tcl/tcl8.6/tzdata/Asia/Phnom_Penh | 5 + tcl/tcl8.6/tzdata/Asia/Pontianak | 13 + tcl/tcl8.6/tzdata/Asia/Pyongyang | 9 + tcl/tcl8.6/tzdata/Asia/Qatar | 7 + tcl/tcl8.6/tzdata/Asia/Qyzylorda | 57 + tcl/tcl8.6/tzdata/Asia/Rangoon | 5 + tcl/tcl8.6/tzdata/Asia/Riyadh | 6 + tcl/tcl8.6/tzdata/Asia/Saigon | 5 + tcl/tcl8.6/tzdata/Asia/Sakhalin | 73 + tcl/tcl8.6/tzdata/Asia/Samarkand | 31 + tcl/tcl8.6/tzdata/Asia/Seoul | 26 + tcl/tcl8.6/tzdata/Asia/Shanghai | 23 + tcl/tcl8.6/tzdata/Asia/Singapore | 13 + tcl/tcl8.6/tzdata/Asia/Srednekolymsk | 71 + tcl/tcl8.6/tzdata/Asia/Taipei | 46 + tcl/tcl8.6/tzdata/Asia/Tashkent | 31 + tcl/tcl8.6/tzdata/Asia/Tbilisi | 60 + tcl/tcl8.6/tzdata/Asia/Tehran | 229 + tcl/tcl8.6/tzdata/Asia/Tel_Aviv | 5 + tcl/tcl8.6/tzdata/Asia/Thimbu | 5 + tcl/tcl8.6/tzdata/Asia/Thimphu | 7 + tcl/tcl8.6/tzdata/Asia/Tokyo | 14 + tcl/tcl8.6/tzdata/Asia/Tomsk | 73 + tcl/tcl8.6/tzdata/Asia/Ujung_Pandang | 5 + tcl/tcl8.6/tzdata/Asia/Ulaanbaatar | 55 + tcl/tcl8.6/tzdata/Asia/Ulan_Bator | 5 + tcl/tcl8.6/tzdata/Asia/Urumqi | 6 + tcl/tcl8.6/tzdata/Asia/Ust-Nera | 71 + tcl/tcl8.6/tzdata/Asia/Vientiane | 5 + tcl/tcl8.6/tzdata/Asia/Vladivostok | 71 + tcl/tcl8.6/tzdata/Asia/Yakutsk | 71 + tcl/tcl8.6/tzdata/Asia/Yangon | 9 + tcl/tcl8.6/tzdata/Asia/Yekaterinburg | 72 + tcl/tcl8.6/tzdata/Asia/Yerevan | 70 + tcl/tcl8.6/tzdata/Atlantic/Azores | 345 + tcl/tcl8.6/tzdata/Atlantic/Bermuda | 259 + tcl/tcl8.6/tzdata/Atlantic/Canary | 247 + tcl/tcl8.6/tzdata/Atlantic/Cape_Verde | 9 + tcl/tcl8.6/tzdata/Atlantic/Faeroe | 5 + tcl/tcl8.6/tzdata/Atlantic/Faroe | 245 + tcl/tcl8.6/tzdata/Atlantic/Jan_Mayen | 5 + tcl/tcl8.6/tzdata/Atlantic/Madeira | 346 + tcl/tcl8.6/tzdata/Atlantic/Reykjavik | 73 + tcl/tcl8.6/tzdata/Atlantic/South_Georgia | 6 + tcl/tcl8.6/tzdata/Atlantic/St_Helena | 5 + tcl/tcl8.6/tzdata/Atlantic/Stanley | 75 + tcl/tcl8.6/tzdata/Australia/ACT | 5 + tcl/tcl8.6/tzdata/Australia/Adelaide | 273 + tcl/tcl8.6/tzdata/Australia/Brisbane | 23 + tcl/tcl8.6/tzdata/Australia/Broken_Hill | 275 + tcl/tcl8.6/tzdata/Australia/Canberra | 5 + tcl/tcl8.6/tzdata/Australia/Currie | 273 + tcl/tcl8.6/tzdata/Australia/Darwin | 15 + tcl/tcl8.6/tzdata/Australia/Eucla | 25 + tcl/tcl8.6/tzdata/Australia/Hobart | 281 + tcl/tcl8.6/tzdata/Australia/LHI | 5 + tcl/tcl8.6/tzdata/Australia/Lindeman | 28 + tcl/tcl8.6/tzdata/Australia/Lord_Howe | 245 + tcl/tcl8.6/tzdata/Australia/Melbourne | 272 + tcl/tcl8.6/tzdata/Australia/NSW | 5 + tcl/tcl8.6/tzdata/Australia/North | 5 + tcl/tcl8.6/tzdata/Australia/Perth | 25 + tcl/tcl8.6/tzdata/Australia/Queensland | 5 + tcl/tcl8.6/tzdata/Australia/South | 5 + tcl/tcl8.6/tzdata/Australia/Sydney | 272 + tcl/tcl8.6/tzdata/Australia/Tasmania | 5 + tcl/tcl8.6/tzdata/Australia/Victoria | 5 + tcl/tcl8.6/tzdata/Australia/West | 5 + tcl/tcl8.6/tzdata/Australia/Yancowinna | 5 + tcl/tcl8.6/tzdata/Brazil/Acre | 5 + tcl/tcl8.6/tzdata/Brazil/DeNoronha | 5 + tcl/tcl8.6/tzdata/Brazil/East | 5 + tcl/tcl8.6/tzdata/Brazil/West | 5 + tcl/tcl8.6/tzdata/CET | 265 + tcl/tcl8.6/tzdata/CST6CDT | 278 + tcl/tcl8.6/tzdata/Canada/Atlantic | 5 + tcl/tcl8.6/tzdata/Canada/Central | 5 + tcl/tcl8.6/tzdata/Canada/East-Saskatchewan | 5 + tcl/tcl8.6/tzdata/Canada/Eastern | 5 + tcl/tcl8.6/tzdata/Canada/Mountain | 5 + tcl/tcl8.6/tzdata/Canada/Newfoundland | 5 + tcl/tcl8.6/tzdata/Canada/Pacific | 5 + tcl/tcl8.6/tzdata/Canada/Saskatchewan | 5 + tcl/tcl8.6/tzdata/Canada/Yukon | 5 + tcl/tcl8.6/tzdata/Chile/Continental | 5 + tcl/tcl8.6/tzdata/Chile/EasterIsland | 5 + tcl/tcl8.6/tzdata/Cuba | 5 + tcl/tcl8.6/tzdata/EET | 251 + tcl/tcl8.6/tzdata/EST | 5 + tcl/tcl8.6/tzdata/EST5EDT | 278 + tcl/tcl8.6/tzdata/Egypt | 5 + tcl/tcl8.6/tzdata/Eire | 5 + tcl/tcl8.6/tzdata/Etc/GMT | 5 + tcl/tcl8.6/tzdata/Etc/GMT+0 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+1 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+10 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+11 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+12 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+2 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+3 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+4 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+5 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+6 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+7 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+8 | 5 + tcl/tcl8.6/tzdata/Etc/GMT+9 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-0 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-1 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-10 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-11 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-12 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-13 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-14 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-2 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-3 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-4 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-5 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-6 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-7 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-8 | 5 + tcl/tcl8.6/tzdata/Etc/GMT-9 | 5 + tcl/tcl8.6/tzdata/Etc/GMT0 | 5 + tcl/tcl8.6/tzdata/Etc/Greenwich | 5 + tcl/tcl8.6/tzdata/Etc/UCT | 5 + tcl/tcl8.6/tzdata/Etc/UTC | 5 + tcl/tcl8.6/tzdata/Etc/Universal | 5 + tcl/tcl8.6/tzdata/Etc/Zulu | 5 + tcl/tcl8.6/tzdata/Europe/Amsterdam | 310 + tcl/tcl8.6/tzdata/Europe/Andorra | 237 + tcl/tcl8.6/tzdata/Europe/Astrakhan | 71 + tcl/tcl8.6/tzdata/Europe/Athens | 268 + tcl/tcl8.6/tzdata/Europe/Belfast | 5 + tcl/tcl8.6/tzdata/Europe/Belgrade | 250 + tcl/tcl8.6/tzdata/Europe/Berlin | 274 + tcl/tcl8.6/tzdata/Europe/Bratislava | 5 + tcl/tcl8.6/tzdata/Europe/Brussels | 316 + tcl/tcl8.6/tzdata/Europe/Bucharest | 268 + tcl/tcl8.6/tzdata/Europe/Budapest | 282 + tcl/tcl8.6/tzdata/Europe/Busingen | 5 + tcl/tcl8.6/tzdata/Europe/Chisinau | 272 + tcl/tcl8.6/tzdata/Europe/Copenhagen | 264 + tcl/tcl8.6/tzdata/Europe/Dublin | 359 + tcl/tcl8.6/tzdata/Europe/Gibraltar | 328 + tcl/tcl8.6/tzdata/Europe/Guernsey | 5 + tcl/tcl8.6/tzdata/Europe/Helsinki | 248 + tcl/tcl8.6/tzdata/Europe/Isle_of_Man | 5 + tcl/tcl8.6/tzdata/Europe/Istanbul | 140 + tcl/tcl8.6/tzdata/Europe/Jersey | 5 + tcl/tcl8.6/tzdata/Europe/Kaliningrad | 85 + tcl/tcl8.6/tzdata/Europe/Kiev | 251 + tcl/tcl8.6/tzdata/Europe/Kirov | 70 + tcl/tcl8.6/tzdata/Europe/Lisbon | 351 + tcl/tcl8.6/tzdata/Europe/Ljubljana | 5 + tcl/tcl8.6/tzdata/Europe/London | 372 + tcl/tcl8.6/tzdata/Europe/Luxembourg | 313 + tcl/tcl8.6/tzdata/Europe/Madrid | 292 + tcl/tcl8.6/tzdata/Europe/Malta | 299 + tcl/tcl8.6/tzdata/Europe/Mariehamn | 5 + tcl/tcl8.6/tzdata/Europe/Minsk | 75 + tcl/tcl8.6/tzdata/Europe/Monaco | 315 + tcl/tcl8.6/tzdata/Europe/Moscow | 83 + tcl/tcl8.6/tzdata/Europe/Nicosia | 5 + tcl/tcl8.6/tzdata/Europe/Oslo | 271 + tcl/tcl8.6/tzdata/Europe/Paris | 314 + tcl/tcl8.6/tzdata/Europe/Podgorica | 5 + tcl/tcl8.6/tzdata/Europe/Prague | 272 + tcl/tcl8.6/tzdata/Europe/Riga | 258 + tcl/tcl8.6/tzdata/Europe/Rome | 302 + tcl/tcl8.6/tzdata/Europe/Samara | 73 + tcl/tcl8.6/tzdata/Europe/San_Marino | 5 + tcl/tcl8.6/tzdata/Europe/Sarajevo | 5 + tcl/tcl8.6/tzdata/Europe/Saratov | 71 + tcl/tcl8.6/tzdata/Europe/Simferopol | 82 + tcl/tcl8.6/tzdata/Europe/Skopje | 5 + tcl/tcl8.6/tzdata/Europe/Sofia | 258 + tcl/tcl8.6/tzdata/Europe/Stockholm | 250 + tcl/tcl8.6/tzdata/Europe/Tallinn | 254 + tcl/tcl8.6/tzdata/Europe/Tirane | 263 + tcl/tcl8.6/tzdata/Europe/Tiraspol | 5 + tcl/tcl8.6/tzdata/Europe/Ulyanovsk | 73 + tcl/tcl8.6/tzdata/Europe/Uzhgorod | 254 + tcl/tcl8.6/tzdata/Europe/Vaduz | 5 + tcl/tcl8.6/tzdata/Europe/Vatican | 5 + tcl/tcl8.6/tzdata/Europe/Vienna | 271 + tcl/tcl8.6/tzdata/Europe/Vilnius | 252 + tcl/tcl8.6/tzdata/Europe/Volgograd | 71 + tcl/tcl8.6/tzdata/Europe/Warsaw | 296 + tcl/tcl8.6/tzdata/Europe/Zagreb | 5 + tcl/tcl8.6/tzdata/Europe/Zaporozhye | 252 + tcl/tcl8.6/tzdata/Europe/Zurich | 250 + tcl/tcl8.6/tzdata/GB | 5 + tcl/tcl8.6/tzdata/GB-Eire | 5 + tcl/tcl8.6/tzdata/GMT | 5 + tcl/tcl8.6/tzdata/GMT+0 | 5 + tcl/tcl8.6/tzdata/GMT-0 | 5 + tcl/tcl8.6/tzdata/GMT0 | 5 + tcl/tcl8.6/tzdata/Greenwich | 5 + tcl/tcl8.6/tzdata/HST | 5 + tcl/tcl8.6/tzdata/Hongkong | 5 + tcl/tcl8.6/tzdata/Iceland | 5 + tcl/tcl8.6/tzdata/Indian/Antananarivo | 5 + tcl/tcl8.6/tzdata/Indian/Chagos | 7 + tcl/tcl8.6/tzdata/Indian/Christmas | 6 + tcl/tcl8.6/tzdata/Indian/Cocos | 6 + tcl/tcl8.6/tzdata/Indian/Comoro | 5 + tcl/tcl8.6/tzdata/Indian/Kerguelen | 6 + tcl/tcl8.6/tzdata/Indian/Mahe | 6 + tcl/tcl8.6/tzdata/Indian/Maldives | 7 + tcl/tcl8.6/tzdata/Indian/Mauritius | 10 + tcl/tcl8.6/tzdata/Indian/Mayotte | 5 + tcl/tcl8.6/tzdata/Indian/Reunion | 6 + tcl/tcl8.6/tzdata/Iran | 5 + tcl/tcl8.6/tzdata/Israel | 5 + tcl/tcl8.6/tzdata/Jamaica | 5 + tcl/tcl8.6/tzdata/Japan | 5 + tcl/tcl8.6/tzdata/Kwajalein | 5 + tcl/tcl8.6/tzdata/Libya | 5 + tcl/tcl8.6/tzdata/MET | 265 + tcl/tcl8.6/tzdata/MST | 5 + tcl/tcl8.6/tzdata/MST7MDT | 278 + tcl/tcl8.6/tzdata/Mexico/BajaNorte | 5 + tcl/tcl8.6/tzdata/Mexico/BajaSur | 5 + tcl/tcl8.6/tzdata/Mexico/General | 5 + tcl/tcl8.6/tzdata/NZ | 5 + tcl/tcl8.6/tzdata/NZ-CHAT | 5 + tcl/tcl8.6/tzdata/Navajo | 5 + tcl/tcl8.6/tzdata/PRC | 5 + tcl/tcl8.6/tzdata/PST8PDT | 278 + tcl/tcl8.6/tzdata/Pacific/Apia | 188 + tcl/tcl8.6/tzdata/Pacific/Auckland | 285 + tcl/tcl8.6/tzdata/Pacific/Bougainville | 10 + tcl/tcl8.6/tzdata/Pacific/Chatham | 258 + tcl/tcl8.6/tzdata/Pacific/Chuuk | 6 + tcl/tcl8.6/tzdata/Pacific/Easter | 268 + tcl/tcl8.6/tzdata/Pacific/Efate | 26 + tcl/tcl8.6/tzdata/Pacific/Enderbury | 8 + tcl/tcl8.6/tzdata/Pacific/Fakaofo | 7 + tcl/tcl8.6/tzdata/Pacific/Fiji | 191 + tcl/tcl8.6/tzdata/Pacific/Funafuti | 6 + tcl/tcl8.6/tzdata/Pacific/Galapagos | 9 + tcl/tcl8.6/tzdata/Pacific/Gambier | 6 + tcl/tcl8.6/tzdata/Pacific/Guadalcanal | 6 + tcl/tcl8.6/tzdata/Pacific/Guam | 8 + tcl/tcl8.6/tzdata/Pacific/Honolulu | 11 + tcl/tcl8.6/tzdata/Pacific/Johnston | 5 + tcl/tcl8.6/tzdata/Pacific/Kiritimati | 8 + tcl/tcl8.6/tzdata/Pacific/Kosrae | 8 + tcl/tcl8.6/tzdata/Pacific/Kwajalein | 8 + tcl/tcl8.6/tzdata/Pacific/Majuro | 7 + tcl/tcl8.6/tzdata/Pacific/Marquesas | 6 + tcl/tcl8.6/tzdata/Pacific/Midway | 5 + tcl/tcl8.6/tzdata/Pacific/Nauru | 9 + tcl/tcl8.6/tzdata/Pacific/Niue | 8 + tcl/tcl8.6/tzdata/Pacific/Norfolk | 10 + tcl/tcl8.6/tzdata/Pacific/Noumea | 12 + tcl/tcl8.6/tzdata/Pacific/Pago_Pago | 7 + tcl/tcl8.6/tzdata/Pacific/Palau | 6 + tcl/tcl8.6/tzdata/Pacific/Pitcairn | 7 + tcl/tcl8.6/tzdata/Pacific/Pohnpei | 6 + tcl/tcl8.6/tzdata/Pacific/Ponape | 5 + tcl/tcl8.6/tzdata/Pacific/Port_Moresby | 7 + tcl/tcl8.6/tzdata/Pacific/Rarotonga | 32 + tcl/tcl8.6/tzdata/Pacific/Saipan | 5 + tcl/tcl8.6/tzdata/Pacific/Samoa | 5 + tcl/tcl8.6/tzdata/Pacific/Tahiti | 6 + tcl/tcl8.6/tzdata/Pacific/Tarawa | 6 + tcl/tcl8.6/tzdata/Pacific/Tongatapu | 16 + tcl/tcl8.6/tzdata/Pacific/Truk | 5 + tcl/tcl8.6/tzdata/Pacific/Wake | 6 + tcl/tcl8.6/tzdata/Pacific/Wallis | 6 + tcl/tcl8.6/tzdata/Pacific/Yap | 5 + tcl/tcl8.6/tzdata/Poland | 5 + tcl/tcl8.6/tzdata/Portugal | 5 + tcl/tcl8.6/tzdata/ROC | 5 + tcl/tcl8.6/tzdata/ROK | 5 + tcl/tcl8.6/tzdata/Singapore | 5 + tcl/tcl8.6/tzdata/SystemV/AST4 | 5 + tcl/tcl8.6/tzdata/SystemV/AST4ADT | 5 + tcl/tcl8.6/tzdata/SystemV/CST6 | 5 + tcl/tcl8.6/tzdata/SystemV/CST6CDT | 5 + tcl/tcl8.6/tzdata/SystemV/EST5 | 5 + tcl/tcl8.6/tzdata/SystemV/EST5EDT | 5 + tcl/tcl8.6/tzdata/SystemV/HST10 | 5 + tcl/tcl8.6/tzdata/SystemV/MST7 | 5 + tcl/tcl8.6/tzdata/SystemV/MST7MDT | 5 + tcl/tcl8.6/tzdata/SystemV/PST8 | 5 + tcl/tcl8.6/tzdata/SystemV/PST8PDT | 5 + tcl/tcl8.6/tzdata/SystemV/YST9 | 5 + tcl/tcl8.6/tzdata/SystemV/YST9YDT | 5 + tcl/tcl8.6/tzdata/Turkey | 5 + tcl/tcl8.6/tzdata/UCT | 5 + tcl/tcl8.6/tzdata/US/Alaska | 5 + tcl/tcl8.6/tzdata/US/Aleutian | 5 + tcl/tcl8.6/tzdata/US/Arizona | 5 + tcl/tcl8.6/tzdata/US/Central | 5 + tcl/tcl8.6/tzdata/US/East-Indiana | 5 + tcl/tcl8.6/tzdata/US/Eastern | 5 + tcl/tcl8.6/tzdata/US/Hawaii | 5 + tcl/tcl8.6/tzdata/US/Indiana-Starke | 5 + tcl/tcl8.6/tzdata/US/Michigan | 5 + tcl/tcl8.6/tzdata/US/Mountain | 5 + tcl/tcl8.6/tzdata/US/Pacific | 5 + tcl/tcl8.6/tzdata/US/Pacific-New | 5 + tcl/tcl8.6/tzdata/US/Samoa | 5 + tcl/tcl8.6/tzdata/UTC | 5 + tcl/tcl8.6/tzdata/Universal | 5 + tcl/tcl8.6/tzdata/W-SU | 5 + tcl/tcl8.6/tzdata/WET | 251 + tcl/tcl8.6/tzdata/Zulu | 5 + tcl/tcl8.6/word.tcl | 152 + tcl/tk8.6/bgerror.tcl | 265 + tcl/tk8.6/button.tcl | 778 ++ tcl/tk8.6/choosedir.tcl | 308 + tcl/tk8.6/clrpick.tcl | 695 ++ tcl/tk8.6/comdlg.tcl | 319 + tcl/tk8.6/console.tcl | 1150 +++ tcl/tk8.6/demos/README | 44 + tcl/tk8.6/demos/anilabel.tcl | 160 + tcl/tk8.6/demos/aniwave.tcl | 104 + tcl/tk8.6/demos/arrow.tcl | 237 + tcl/tk8.6/demos/bind.tcl | 78 + tcl/tk8.6/demos/bitmap.tcl | 52 + tcl/tk8.6/demos/browse | 66 + tcl/tk8.6/demos/button.tcl | 47 + tcl/tk8.6/demos/check.tcl | 71 + tcl/tk8.6/demos/clrpick.tcl | 54 + tcl/tk8.6/demos/colors.tcl | 99 + tcl/tk8.6/demos/combo.tcl | 61 + tcl/tk8.6/demos/cscroll.tcl | 108 + tcl/tk8.6/demos/ctext.tcl | 172 + tcl/tk8.6/demos/dialog1.tcl | 13 + tcl/tk8.6/demos/dialog2.tcl | 17 + tcl/tk8.6/demos/en.msg | 97 + tcl/tk8.6/demos/entry1.tcl | 34 + tcl/tk8.6/demos/entry2.tcl | 46 + tcl/tk8.6/demos/entry3.tcl | 185 + tcl/tk8.6/demos/filebox.tcl | 81 + tcl/tk8.6/demos/floor.tcl | 1366 +++ tcl/tk8.6/demos/fontchoose.tcl | 69 + tcl/tk8.6/demos/form.tcl | 38 + tcl/tk8.6/demos/goldberg.tcl | 1833 ++++ tcl/tk8.6/demos/hello | 22 + tcl/tk8.6/demos/hscale.tcl | 45 + tcl/tk8.6/demos/icon.tcl | 51 + tcl/tk8.6/demos/image1.tcl | 35 + tcl/tk8.6/demos/image2.tcl | 108 + tcl/tk8.6/demos/images/earth.gif | Bin 0 -> 51712 bytes tcl/tk8.6/demos/images/earthmenu.png | Bin 0 -> 8157 bytes tcl/tk8.6/demos/images/earthris.gif | Bin 0 -> 6343 bytes tcl/tk8.6/demos/images/flagdown.xbm | 27 + tcl/tk8.6/demos/images/flagup.xbm | 27 + tcl/tk8.6/demos/images/gray25.xbm | 6 + tcl/tk8.6/demos/images/letters.xbm | 27 + tcl/tk8.6/demos/images/noletter.xbm | 27 + tcl/tk8.6/demos/images/ouster.png | Bin 0 -> 54257 bytes tcl/tk8.6/demos/images/pattern.xbm | 6 + tcl/tk8.6/demos/images/tcllogo.gif | Bin 0 -> 2341 bytes tcl/tk8.6/demos/images/teapot.ppm | 31 + tcl/tk8.6/demos/items.tcl | 291 + tcl/tk8.6/demos/ixset | 328 + tcl/tk8.6/demos/knightstour.tcl | 268 + tcl/tk8.6/demos/label.tcl | 40 + tcl/tk8.6/demos/labelframe.tcl | 76 + tcl/tk8.6/demos/license.terms | 40 + tcl/tk8.6/demos/mclist.tcl | 119 + tcl/tk8.6/demos/menu.tcl | 163 + tcl/tk8.6/demos/menubu.tcl | 90 + tcl/tk8.6/demos/msgbox.tcl | 62 + tcl/tk8.6/demos/nl.msg | 125 + tcl/tk8.6/demos/paned1.tcl | 32 + tcl/tk8.6/demos/paned2.tcl | 74 + tcl/tk8.6/demos/pendulum.tcl | 197 + tcl/tk8.6/demos/plot.tcl | 97 + tcl/tk8.6/demos/puzzle.tcl | 82 + tcl/tk8.6/demos/radio.tcl | 66 + tcl/tk8.6/demos/rmt | 210 + tcl/tk8.6/demos/rolodex | 204 + tcl/tk8.6/demos/ruler.tcl | 171 + tcl/tk8.6/demos/sayings.tcl | 44 + tcl/tk8.6/demos/search.tcl | 139 + tcl/tk8.6/demos/spin.tcl | 53 + tcl/tk8.6/demos/square | 60 + tcl/tk8.6/demos/states.tcl | 54 + tcl/tk8.6/demos/style.tcl | 155 + tcl/tk8.6/demos/tclIndex | 67 + tcl/tk8.6/demos/tcolor | 358 + tcl/tk8.6/demos/text.tcl | 111 + tcl/tk8.6/demos/textpeer.tcl | 62 + tcl/tk8.6/demos/timer | 47 + tcl/tk8.6/demos/toolbar.tcl | 92 + tcl/tk8.6/demos/tree.tcl | 88 + tcl/tk8.6/demos/ttkbut.tcl | 84 + tcl/tk8.6/demos/ttkmenu.tcl | 53 + tcl/tk8.6/demos/ttknote.tcl | 57 + tcl/tk8.6/demos/ttkpane.tcl | 112 + tcl/tk8.6/demos/ttkprogress.tcl | 46 + tcl/tk8.6/demos/ttkscale.tcl | 39 + tcl/tk8.6/demos/twind.tcl | 327 + tcl/tk8.6/demos/unicodeout.tcl | 137 + tcl/tk8.6/demos/vscale.tcl | 46 + tcl/tk8.6/demos/widget | 721 ++ tcl/tk8.6/dialog.tcl | 180 + tcl/tk8.6/entry.tcl | 654 ++ tcl/tk8.6/focus.tcl | 178 + tcl/tk8.6/fontchooser.tcl | 452 + tcl/tk8.6/iconlist.tcl | 696 ++ tcl/tk8.6/icons.tcl | 153 + tcl/tk8.6/images/README | 7 + tcl/tk8.6/images/logo.eps | 2091 +++++ tcl/tk8.6/images/logo100.gif | Bin 0 -> 2341 bytes tcl/tk8.6/images/logo64.gif | Bin 0 -> 1670 bytes tcl/tk8.6/images/logoLarge.gif | Bin 0 -> 11000 bytes tcl/tk8.6/images/logoMed.gif | Bin 0 -> 3889 bytes tcl/tk8.6/images/pwrdLogo.eps | 1897 ++++ tcl/tk8.6/images/pwrdLogo100.gif | Bin 0 -> 1615 bytes tcl/tk8.6/images/pwrdLogo150.gif | Bin 0 -> 2489 bytes tcl/tk8.6/images/pwrdLogo175.gif | Bin 0 -> 2981 bytes tcl/tk8.6/images/pwrdLogo200.gif | Bin 0 -> 3491 bytes tcl/tk8.6/images/pwrdLogo75.gif | Bin 0 -> 1171 bytes tcl/tk8.6/images/tai-ku.gif | Bin 0 -> 5473 bytes tcl/tk8.6/license.terms | 40 + tcl/tk8.6/listbox.tcl | 552 ++ tcl/tk8.6/megawidget.tcl | 297 + tcl/tk8.6/menu.tcl | 1354 +++ tcl/tk8.6/mkpsenc.tcl | 1488 +++ tcl/tk8.6/msgbox.tcl | 429 + tcl/tk8.6/msgs/cs.msg | 77 + tcl/tk8.6/msgs/da.msg | 78 + tcl/tk8.6/msgs/de.msg | 91 + tcl/tk8.6/msgs/el.msg | 86 + tcl/tk8.6/msgs/en.msg | 91 + tcl/tk8.6/msgs/en_gb.msg | 3 + tcl/tk8.6/msgs/eo.msg | 75 + tcl/tk8.6/msgs/es.msg | 76 + tcl/tk8.6/msgs/fr.msg | 72 + tcl/tk8.6/msgs/hu.msg | 78 + tcl/tk8.6/msgs/it.msg | 73 + tcl/tk8.6/msgs/nl.msg | 91 + tcl/tk8.6/msgs/pl.msg | 91 + tcl/tk8.6/msgs/pt.msg | 74 + tcl/tk8.6/msgs/ru.msg | 75 + tcl/tk8.6/msgs/sv.msg | 76 + tcl/tk8.6/obsolete.tcl | 178 + tcl/tk8.6/optMenu.tcl | 43 + tcl/tk8.6/palette.tcl | 244 + tcl/tk8.6/panedwindow.tcl | 194 + tcl/tk8.6/pkgIndex.tcl | 7 + tcl/tk8.6/safetk.tcl | 262 + tcl/tk8.6/scale.tcl | 290 + tcl/tk8.6/scrlbar.tcl | 454 + tcl/tk8.6/spinbox.tcl | 580 ++ tcl/tk8.6/tclIndex | 253 + tcl/tk8.6/tearoff.tcl | 180 + tcl/tk8.6/text.tcl | 1207 +++ tcl/tk8.6/tk.tcl | 695 ++ tcl/tk8.6/tkfbox.tcl | 1240 +++ tcl/tk8.6/ttk/altTheme.tcl | 107 + tcl/tk8.6/ttk/aquaTheme.tcl | 59 + tcl/tk8.6/ttk/button.tcl | 83 + tcl/tk8.6/ttk/clamTheme.tcl | 145 + tcl/tk8.6/ttk/classicTheme.tcl | 113 + tcl/tk8.6/ttk/combobox.tcl | 457 + tcl/tk8.6/ttk/cursors.tcl | 186 + tcl/tk8.6/ttk/defaults.tcl | 141 + tcl/tk8.6/ttk/entry.tcl | 607 ++ tcl/tk8.6/ttk/fonts.tcl | 157 + tcl/tk8.6/ttk/menubutton.tcl | 169 + tcl/tk8.6/ttk/notebook.tcl | 197 + tcl/tk8.6/ttk/panedwindow.tcl | 82 + tcl/tk8.6/ttk/progress.tcl | 49 + tcl/tk8.6/ttk/scale.tcl | 94 + tcl/tk8.6/ttk/scrollbar.tcl | 123 + tcl/tk8.6/ttk/sizegrip.tcl | 102 + tcl/tk8.6/ttk/spinbox.tcl | 173 + tcl/tk8.6/ttk/treeview.tcl | 363 + tcl/tk8.6/ttk/ttk.tcl | 176 + tcl/tk8.6/ttk/utils.tcl | 350 + tcl/tk8.6/ttk/vistaTheme.tcl | 224 + tcl/tk8.6/ttk/winTheme.tcl | 80 + tcl/tk8.6/ttk/xpTheme.tcl | 65 + tcl/tk8.6/unsupported.tcl | 269 + tcl/tk8.6/xmfbox.tcl | 989 ++ templates | 1 + 2910 files changed, 446120 insertions(+) create mode 100644 Include/Python-ast.h create mode 100644 Include/Python.h create mode 100644 Include/abstract.h create mode 100644 Include/accu.h create mode 100644 Include/asdl.h create mode 100644 Include/ast.h create mode 100644 Include/bitset.h create mode 100644 Include/bltinmodule.h create mode 100644 Include/boolobject.h create mode 100644 Include/bytearrayobject.h create mode 100644 Include/bytes_methods.h create mode 100644 Include/bytesobject.h create mode 100644 Include/cellobject.h create mode 100644 Include/ceval.h create mode 100644 Include/classobject.h create mode 100644 Include/code.h create mode 100644 Include/codecs.h create mode 100644 Include/compile.h create mode 100644 Include/complexobject.h create mode 100644 Include/context.h create mode 100644 Include/datetime.h create mode 100644 Include/descrobject.h create mode 100644 Include/dictobject.h create mode 100644 Include/dtoa.h create mode 100644 Include/dynamic_annotations.h create mode 100644 Include/enumobject.h create mode 100644 Include/errcode.h create mode 100644 Include/eval.h create mode 100644 Include/fileobject.h create mode 100644 Include/fileutils.h create mode 100644 Include/floatobject.h create mode 100644 Include/frameobject.h create mode 100644 Include/funcobject.h create mode 100644 Include/genobject.h create mode 100644 Include/graminit.h create mode 100644 Include/grammar.h create mode 100644 Include/import.h create mode 100644 Include/intrcheck.h create mode 100644 Include/iterobject.h create mode 100644 Include/listobject.h create mode 100644 Include/longintrepr.h create mode 100644 Include/longobject.h create mode 100644 Include/marshal.h create mode 100644 Include/memoryobject.h create mode 100644 Include/metagrammar.h create mode 100644 Include/methodobject.h create mode 100644 Include/modsupport.h create mode 100644 Include/moduleobject.h create mode 100644 Include/namespaceobject.h create mode 100644 Include/node.h create mode 100644 Include/object.h create mode 100644 Include/objimpl.h create mode 100644 Include/odictobject.h create mode 100644 Include/opcode.h create mode 100644 Include/osdefs.h create mode 100644 Include/osmodule.h create mode 100644 Include/parsetok.h create mode 100644 Include/patchlevel.h create mode 100644 Include/pgen.h create mode 100644 Include/pgenheaders.h create mode 100644 Include/py_curses.h create mode 100644 Include/pyarena.h create mode 100644 Include/pyatomic.h create mode 100644 Include/pycapsule.h create mode 100644 Include/pyconfig.h create mode 100644 Include/pyctype.h create mode 100644 Include/pydebug.h create mode 100644 Include/pydtrace.h create mode 100644 Include/pyerrors.h create mode 100644 Include/pyexpat.h create mode 100644 Include/pyfpe.h create mode 100644 Include/pyhash.h create mode 100644 Include/pylifecycle.h create mode 100644 Include/pymacconfig.h create mode 100644 Include/pymacro.h create mode 100644 Include/pymath.h create mode 100644 Include/pymem.h create mode 100644 Include/pyport.h create mode 100644 Include/pystate.h create mode 100644 Include/pystrcmp.h create mode 100644 Include/pystrhex.h create mode 100644 Include/pystrtod.h create mode 100644 Include/pythonrun.h create mode 100644 Include/pythread.h create mode 100644 Include/pytime.h create mode 100644 Include/rangeobject.h create mode 100644 Include/setobject.h create mode 100644 Include/sliceobject.h create mode 100644 Include/structmember.h create mode 100644 Include/structseq.h create mode 100644 Include/symtable.h create mode 100644 Include/sysmodule.h create mode 100644 Include/token.h create mode 100644 Include/traceback.h create mode 100644 Include/tupleobject.h create mode 100644 Include/typeslots.h create mode 100644 Include/ucnhash.h create mode 100644 Include/unicodeobject.h create mode 100644 Include/warnings.h create mode 100644 Include/weakrefobject.h create mode 100644 Lib/__future__.py create mode 100644 Lib/__pycache__/__future__.cpython-37.pyc create mode 100644 Lib/__pycache__/_bootlocale.cpython-37.pyc create mode 100644 Lib/__pycache__/_collections_abc.cpython-37.pyc create mode 100644 Lib/__pycache__/_weakrefset.cpython-37.pyc create mode 100644 Lib/__pycache__/abc.cpython-37.pyc create mode 100644 Lib/__pycache__/base64.cpython-37.pyc create mode 100644 Lib/__pycache__/bisect.cpython-37.pyc create mode 100644 Lib/__pycache__/codecs.cpython-37.pyc create mode 100644 Lib/__pycache__/copy.cpython-37.pyc create mode 100644 Lib/__pycache__/copyreg.cpython-37.pyc create mode 100644 Lib/__pycache__/enum.cpython-37.pyc create mode 100644 Lib/__pycache__/fnmatch.cpython-37.pyc create mode 100644 Lib/__pycache__/functools.cpython-37.pyc create mode 100644 Lib/__pycache__/genericpath.cpython-37.pyc create mode 100644 Lib/__pycache__/hashlib.cpython-37.pyc create mode 100644 Lib/__pycache__/heapq.cpython-37.pyc create mode 100644 Lib/__pycache__/hmac.cpython-37.pyc create mode 100644 Lib/__pycache__/imp.cpython-37.pyc create mode 100644 Lib/__pycache__/io.cpython-37.pyc create mode 100644 Lib/__pycache__/keyword.cpython-37.pyc create mode 100644 Lib/__pycache__/linecache.cpython-37.pyc create mode 100644 Lib/__pycache__/locale.cpython-37.pyc create mode 100644 Lib/__pycache__/ntpath.cpython-37.pyc create mode 100644 Lib/__pycache__/operator.cpython-37.pyc create mode 100644 Lib/__pycache__/os.cpython-37.pyc create mode 100644 Lib/__pycache__/posixpath.cpython-37.pyc create mode 100644 Lib/__pycache__/random.cpython-37.pyc create mode 100644 Lib/__pycache__/re.cpython-37.pyc create mode 100644 Lib/__pycache__/reprlib.cpython-37.pyc create mode 100644 Lib/__pycache__/shutil.cpython-37.pyc create mode 100644 Lib/__pycache__/site.cpython-37.pyc create mode 100644 Lib/__pycache__/sre_compile.cpython-37.pyc create mode 100644 Lib/__pycache__/sre_constants.cpython-37.pyc create mode 100644 Lib/__pycache__/sre_parse.cpython-37.pyc create mode 100644 Lib/__pycache__/stat.cpython-37.pyc create mode 100644 Lib/__pycache__/struct.cpython-37.pyc create mode 100644 Lib/__pycache__/tarfile.cpython-37.pyc create mode 100644 Lib/__pycache__/tempfile.cpython-37.pyc create mode 100644 Lib/__pycache__/token.cpython-37.pyc create mode 100644 Lib/__pycache__/tokenize.cpython-37.pyc create mode 100644 Lib/__pycache__/types.cpython-37.pyc create mode 100644 Lib/__pycache__/warnings.cpython-37.pyc create mode 100644 Lib/__pycache__/weakref.cpython-37.pyc create mode 100644 Lib/_bootlocale.py create mode 100644 Lib/_collections_abc.py create mode 100644 Lib/_dummy_thread.py create mode 100644 Lib/_weakrefset.py create mode 100644 Lib/abc.py create mode 100644 Lib/base64.py create mode 100644 Lib/bisect.py create mode 100644 Lib/codecs.py create mode 100644 Lib/collections/__init__.py create mode 100644 Lib/collections/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/collections/__pycache__/abc.cpython-37.pyc create mode 100644 Lib/collections/abc.py create mode 100644 Lib/copy.py create mode 100644 Lib/copyreg.py create mode 100644 Lib/distutils/__init__.py create mode 100644 Lib/distutils/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/distutils/distutils.cfg create mode 100644 Lib/encodings/__init__.py create mode 100644 Lib/encodings/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/aliases.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/cp1252.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/cp437.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/idna.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/latin_1.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/utf_16_be.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/utf_16_le.cpython-37.pyc create mode 100644 Lib/encodings/__pycache__/utf_8.cpython-37.pyc create mode 100644 Lib/encodings/aliases.py create mode 100644 Lib/encodings/ascii.py create mode 100644 Lib/encodings/base64_codec.py create mode 100644 Lib/encodings/big5.py create mode 100644 Lib/encodings/big5hkscs.py create mode 100644 Lib/encodings/bz2_codec.py create mode 100644 Lib/encodings/charmap.py create mode 100644 Lib/encodings/cp037.py create mode 100644 Lib/encodings/cp1006.py create mode 100644 Lib/encodings/cp1026.py create mode 100644 Lib/encodings/cp1125.py create mode 100644 Lib/encodings/cp1140.py create mode 100644 Lib/encodings/cp1250.py create mode 100644 Lib/encodings/cp1251.py create mode 100644 Lib/encodings/cp1252.py create mode 100644 Lib/encodings/cp1253.py create mode 100644 Lib/encodings/cp1254.py create mode 100644 Lib/encodings/cp1255.py create mode 100644 Lib/encodings/cp1256.py create mode 100644 Lib/encodings/cp1257.py create mode 100644 Lib/encodings/cp1258.py create mode 100644 Lib/encodings/cp273.py create mode 100644 Lib/encodings/cp424.py create mode 100644 Lib/encodings/cp437.py create mode 100644 Lib/encodings/cp500.py create mode 100644 Lib/encodings/cp65001.py create mode 100644 Lib/encodings/cp720.py create mode 100644 Lib/encodings/cp737.py create mode 100644 Lib/encodings/cp775.py create mode 100644 Lib/encodings/cp850.py create mode 100644 Lib/encodings/cp852.py create mode 100644 Lib/encodings/cp855.py create mode 100644 Lib/encodings/cp856.py create mode 100644 Lib/encodings/cp857.py create mode 100644 Lib/encodings/cp858.py create mode 100644 Lib/encodings/cp860.py create mode 100644 Lib/encodings/cp861.py create mode 100644 Lib/encodings/cp862.py create mode 100644 Lib/encodings/cp863.py create mode 100644 Lib/encodings/cp864.py create mode 100644 Lib/encodings/cp865.py create mode 100644 Lib/encodings/cp866.py create mode 100644 Lib/encodings/cp869.py create mode 100644 Lib/encodings/cp874.py create mode 100644 Lib/encodings/cp875.py create mode 100644 Lib/encodings/cp932.py create mode 100644 Lib/encodings/cp949.py create mode 100644 Lib/encodings/cp950.py create mode 100644 Lib/encodings/euc_jis_2004.py create mode 100644 Lib/encodings/euc_jisx0213.py create mode 100644 Lib/encodings/euc_jp.py create mode 100644 Lib/encodings/euc_kr.py create mode 100644 Lib/encodings/gb18030.py create mode 100644 Lib/encodings/gb2312.py create mode 100644 Lib/encodings/gbk.py create mode 100644 Lib/encodings/hex_codec.py create mode 100644 Lib/encodings/hp_roman8.py create mode 100644 Lib/encodings/hz.py create mode 100644 Lib/encodings/idna.py create mode 100644 Lib/encodings/iso2022_jp.py create mode 100644 Lib/encodings/iso2022_jp_1.py create mode 100644 Lib/encodings/iso2022_jp_2.py create mode 100644 Lib/encodings/iso2022_jp_2004.py create mode 100644 Lib/encodings/iso2022_jp_3.py create mode 100644 Lib/encodings/iso2022_jp_ext.py create mode 100644 Lib/encodings/iso2022_kr.py create mode 100644 Lib/encodings/iso8859_1.py create mode 100644 Lib/encodings/iso8859_10.py create mode 100644 Lib/encodings/iso8859_11.py create mode 100644 Lib/encodings/iso8859_13.py create mode 100644 Lib/encodings/iso8859_14.py create mode 100644 Lib/encodings/iso8859_15.py create mode 100644 Lib/encodings/iso8859_16.py create mode 100644 Lib/encodings/iso8859_2.py create mode 100644 Lib/encodings/iso8859_3.py create mode 100644 Lib/encodings/iso8859_4.py create mode 100644 Lib/encodings/iso8859_5.py create mode 100644 Lib/encodings/iso8859_6.py create mode 100644 Lib/encodings/iso8859_7.py create mode 100644 Lib/encodings/iso8859_8.py create mode 100644 Lib/encodings/iso8859_9.py create mode 100644 Lib/encodings/johab.py create mode 100644 Lib/encodings/koi8_r.py create mode 100644 Lib/encodings/koi8_t.py create mode 100644 Lib/encodings/koi8_u.py create mode 100644 Lib/encodings/kz1048.py create mode 100644 Lib/encodings/latin_1.py create mode 100644 Lib/encodings/mac_arabic.py create mode 100644 Lib/encodings/mac_centeuro.py create mode 100644 Lib/encodings/mac_croatian.py create mode 100644 Lib/encodings/mac_cyrillic.py create mode 100644 Lib/encodings/mac_farsi.py create mode 100644 Lib/encodings/mac_greek.py create mode 100644 Lib/encodings/mac_iceland.py create mode 100644 Lib/encodings/mac_latin2.py create mode 100644 Lib/encodings/mac_roman.py create mode 100644 Lib/encodings/mac_romanian.py create mode 100644 Lib/encodings/mac_turkish.py create mode 100644 Lib/encodings/mbcs.py create mode 100644 Lib/encodings/oem.py create mode 100644 Lib/encodings/palmos.py create mode 100644 Lib/encodings/ptcp154.py create mode 100644 Lib/encodings/punycode.py create mode 100644 Lib/encodings/quopri_codec.py create mode 100644 Lib/encodings/raw_unicode_escape.py create mode 100644 Lib/encodings/rot_13.py create mode 100644 Lib/encodings/shift_jis.py create mode 100644 Lib/encodings/shift_jis_2004.py create mode 100644 Lib/encodings/shift_jisx0213.py create mode 100644 Lib/encodings/tis_620.py create mode 100644 Lib/encodings/undefined.py create mode 100644 Lib/encodings/unicode_escape.py create mode 100644 Lib/encodings/unicode_internal.py create mode 100644 Lib/encodings/utf_16.py create mode 100644 Lib/encodings/utf_16_be.py create mode 100644 Lib/encodings/utf_16_le.py create mode 100644 Lib/encodings/utf_32.py create mode 100644 Lib/encodings/utf_32_be.py create mode 100644 Lib/encodings/utf_32_le.py create mode 100644 Lib/encodings/utf_7.py create mode 100644 Lib/encodings/utf_8.py create mode 100644 Lib/encodings/utf_8_sig.py create mode 100644 Lib/encodings/uu_codec.py create mode 100644 Lib/encodings/zlib_codec.py create mode 100644 Lib/enum.py create mode 100644 Lib/fnmatch.py create mode 100644 Lib/functools.py create mode 100644 Lib/genericpath.py create mode 100644 Lib/hashlib.py create mode 100644 Lib/heapq.py create mode 100644 Lib/hmac.py create mode 100644 Lib/imp.py create mode 100644 Lib/importlib/__init__.py create mode 100644 Lib/importlib/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/importlib/__pycache__/abc.cpython-37.pyc create mode 100644 Lib/importlib/__pycache__/machinery.cpython-37.pyc create mode 100644 Lib/importlib/__pycache__/util.cpython-37.pyc create mode 100644 Lib/importlib/_bootstrap.py create mode 100644 Lib/importlib/_bootstrap_external.py create mode 100644 Lib/importlib/abc.py create mode 100644 Lib/importlib/machinery.py create mode 100644 Lib/importlib/resources.py create mode 100644 Lib/importlib/util.py create mode 100644 Lib/io.py create mode 100644 Lib/keyword.py create mode 100644 Lib/linecache.py create mode 100644 Lib/locale.py create mode 100644 Lib/no-global-site-packages.txt create mode 100644 Lib/ntpath.py create mode 100644 Lib/operator.py create mode 100644 Lib/orig-prefix.txt create mode 100644 Lib/os.py create mode 100644 Lib/posixpath.py create mode 100644 Lib/random.py create mode 100644 Lib/re.py create mode 100644 Lib/reprlib.py create mode 100644 Lib/rlcompleter.py create mode 100644 Lib/shutil.py create mode 100644 Lib/site-packages/Flask-1.0.2.dist-info/INSTALLER create mode 100644 Lib/site-packages/Flask-1.0.2.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/Flask-1.0.2.dist-info/METADATA create mode 100644 Lib/site-packages/Flask-1.0.2.dist-info/RECORD create mode 100644 Lib/site-packages/Flask-1.0.2.dist-info/WHEEL create mode 100644 Lib/site-packages/Flask-1.0.2.dist-info/entry_points.txt create mode 100644 Lib/site-packages/Flask-1.0.2.dist-info/top_level.txt create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/DESCRIPTION.rst create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/INSTALLER create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/METADATA create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/RECORD create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/WHEEL create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/metadata.json create mode 100644 Lib/site-packages/Flask_WTF-0.14.2.dist-info/top_level.txt create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/INSTALLER create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/METADATA create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/RECORD create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/WHEEL create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/entry_points.txt create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/metadata.json create mode 100644 Lib/site-packages/Jinja2-2.10.dist-info/top_level.txt create mode 100644 Lib/site-packages/MarkupSafe-1.0.dist-info/INSTALLER create mode 100644 Lib/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/MarkupSafe-1.0.dist-info/METADATA create mode 100644 Lib/site-packages/MarkupSafe-1.0.dist-info/RECORD create mode 100644 Lib/site-packages/MarkupSafe-1.0.dist-info/WHEEL create mode 100644 Lib/site-packages/MarkupSafe-1.0.dist-info/top_level.txt create mode 100644 Lib/site-packages/WTForms-2.2.1.dist-info/INSTALLER create mode 100644 Lib/site-packages/WTForms-2.2.1.dist-info/METADATA create mode 100644 Lib/site-packages/WTForms-2.2.1.dist-info/RECORD create mode 100644 Lib/site-packages/WTForms-2.2.1.dist-info/WHEEL create mode 100644 Lib/site-packages/WTForms-2.2.1.dist-info/top_level.txt create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/METADATA create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/RECORD create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/WHEEL create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/metadata.json create mode 100644 Lib/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt create mode 100644 Lib/site-packages/__pycache__/easy_install.cpython-37.pyc create mode 100644 Lib/site-packages/__pycache__/itsdangerous.cpython-37.pyc create mode 100644 Lib/site-packages/__pycache__/pytest.cpython-37.pyc create mode 100644 Lib/site-packages/__pycache__/six.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__init__.py create mode 100644 Lib/site-packages/_pytest/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/_argcomplete.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/_version.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/cacheprovider.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/capture.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/debugging.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/deprecated.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/doctest.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/experiments.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/fixtures.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/freeze_support.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/helpconfig.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/hookspec.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/junitxml.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/logging.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/main.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/monkeypatch.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/nodes.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/nose.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/outcomes.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/pastebin.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/paths.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/pytester.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/python.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/python_api.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/recwarn.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/reports.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/resultlog.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/runner.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/setuponly.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/setupplan.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/skipping.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/terminal.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/tmpdir.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/unittest.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/__pycache__/warnings.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/_argcomplete.py create mode 100644 Lib/site-packages/_pytest/_code/__init__.py create mode 100644 Lib/site-packages/_pytest/_code/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/_code/__pycache__/_py2traceback.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/_code/__pycache__/code.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/_code/__pycache__/source.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/_code/_py2traceback.py create mode 100644 Lib/site-packages/_pytest/_code/code.py create mode 100644 Lib/site-packages/_pytest/_code/source.py create mode 100644 Lib/site-packages/_pytest/_version.py create mode 100644 Lib/site-packages/_pytest/assertion/__init__.py create mode 100644 Lib/site-packages/_pytest/assertion/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/assertion/__pycache__/rewrite.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/assertion/__pycache__/truncate.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/assertion/__pycache__/util.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/assertion/rewrite.py create mode 100644 Lib/site-packages/_pytest/assertion/truncate.py create mode 100644 Lib/site-packages/_pytest/assertion/util.py create mode 100644 Lib/site-packages/_pytest/cacheprovider.py create mode 100644 Lib/site-packages/_pytest/capture.py create mode 100644 Lib/site-packages/_pytest/compat.py create mode 100644 Lib/site-packages/_pytest/config/__init__.py create mode 100644 Lib/site-packages/_pytest/config/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/config/__pycache__/argparsing.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/config/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/config/__pycache__/findpaths.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/config/argparsing.py create mode 100644 Lib/site-packages/_pytest/config/exceptions.py create mode 100644 Lib/site-packages/_pytest/config/findpaths.py create mode 100644 Lib/site-packages/_pytest/debugging.py create mode 100644 Lib/site-packages/_pytest/deprecated.py create mode 100644 Lib/site-packages/_pytest/doctest.py create mode 100644 Lib/site-packages/_pytest/experiments.py create mode 100644 Lib/site-packages/_pytest/fixtures.py create mode 100644 Lib/site-packages/_pytest/freeze_support.py create mode 100644 Lib/site-packages/_pytest/helpconfig.py create mode 100644 Lib/site-packages/_pytest/hookspec.py create mode 100644 Lib/site-packages/_pytest/junitxml.py create mode 100644 Lib/site-packages/_pytest/logging.py create mode 100644 Lib/site-packages/_pytest/main.py create mode 100644 Lib/site-packages/_pytest/mark/__init__.py create mode 100644 Lib/site-packages/_pytest/mark/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/mark/__pycache__/evaluate.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/mark/__pycache__/legacy.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/mark/__pycache__/structures.cpython-37.pyc create mode 100644 Lib/site-packages/_pytest/mark/evaluate.py create mode 100644 Lib/site-packages/_pytest/mark/legacy.py create mode 100644 Lib/site-packages/_pytest/mark/structures.py create mode 100644 Lib/site-packages/_pytest/monkeypatch.py create mode 100644 Lib/site-packages/_pytest/nodes.py create mode 100644 Lib/site-packages/_pytest/nose.py create mode 100644 Lib/site-packages/_pytest/outcomes.py create mode 100644 Lib/site-packages/_pytest/pastebin.py create mode 100644 Lib/site-packages/_pytest/paths.py create mode 100644 Lib/site-packages/_pytest/pytester.py create mode 100644 Lib/site-packages/_pytest/python.py create mode 100644 Lib/site-packages/_pytest/python_api.py create mode 100644 Lib/site-packages/_pytest/recwarn.py create mode 100644 Lib/site-packages/_pytest/reports.py create mode 100644 Lib/site-packages/_pytest/resultlog.py create mode 100644 Lib/site-packages/_pytest/runner.py create mode 100644 Lib/site-packages/_pytest/setuponly.py create mode 100644 Lib/site-packages/_pytest/setupplan.py create mode 100644 Lib/site-packages/_pytest/skipping.py create mode 100644 Lib/site-packages/_pytest/terminal.py create mode 100644 Lib/site-packages/_pytest/tmpdir.py create mode 100644 Lib/site-packages/_pytest/unittest.py create mode 100644 Lib/site-packages/_pytest/warnings.py create mode 100644 Lib/site-packages/atomicwrites-1.1.5.dist-info/DESCRIPTION.rst create mode 100644 Lib/site-packages/atomicwrites-1.1.5.dist-info/INSTALLER create mode 100644 Lib/site-packages/atomicwrites-1.1.5.dist-info/METADATA create mode 100644 Lib/site-packages/atomicwrites-1.1.5.dist-info/RECORD create mode 100644 Lib/site-packages/atomicwrites-1.1.5.dist-info/WHEEL create mode 100644 Lib/site-packages/atomicwrites-1.1.5.dist-info/metadata.json create mode 100644 Lib/site-packages/atomicwrites-1.1.5.dist-info/top_level.txt create mode 100644 Lib/site-packages/atomicwrites/__init__.py create mode 100644 Lib/site-packages/atomicwrites/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__init__.py create mode 100644 Lib/site-packages/attr/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/_config.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/_funcs.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/_make.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/converters.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/filters.cpython-37.pyc create mode 100644 Lib/site-packages/attr/__pycache__/validators.cpython-37.pyc create mode 100644 Lib/site-packages/attr/_compat.py create mode 100644 Lib/site-packages/attr/_config.py create mode 100644 Lib/site-packages/attr/_funcs.py create mode 100644 Lib/site-packages/attr/_make.py create mode 100644 Lib/site-packages/attr/converters.py create mode 100644 Lib/site-packages/attr/exceptions.py create mode 100644 Lib/site-packages/attr/filters.py create mode 100644 Lib/site-packages/attr/validators.py create mode 100644 Lib/site-packages/attrs-18.1.0.dist-info/INSTALLER create mode 100644 Lib/site-packages/attrs-18.1.0.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/attrs-18.1.0.dist-info/METADATA create mode 100644 Lib/site-packages/attrs-18.1.0.dist-info/RECORD create mode 100644 Lib/site-packages/attrs-18.1.0.dist-info/WHEEL create mode 100644 Lib/site-packages/attrs-18.1.0.dist-info/top_level.txt create mode 100644 Lib/site-packages/click-6.7.dist-info/DESCRIPTION.rst create mode 100644 Lib/site-packages/click-6.7.dist-info/INSTALLER create mode 100644 Lib/site-packages/click-6.7.dist-info/METADATA create mode 100644 Lib/site-packages/click-6.7.dist-info/RECORD create mode 100644 Lib/site-packages/click-6.7.dist-info/WHEEL create mode 100644 Lib/site-packages/click-6.7.dist-info/metadata.json create mode 100644 Lib/site-packages/click-6.7.dist-info/top_level.txt create mode 100644 Lib/site-packages/click/__init__.py create mode 100644 Lib/site-packages/click/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/_bashcomplete.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/_termui_impl.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/_textwrap.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/_unicodefun.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/_winconsole.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/core.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/decorators.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/formatting.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/globals.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/parser.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/termui.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/testing.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/types.cpython-37.pyc create mode 100644 Lib/site-packages/click/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/click/_bashcomplete.py create mode 100644 Lib/site-packages/click/_compat.py create mode 100644 Lib/site-packages/click/_termui_impl.py create mode 100644 Lib/site-packages/click/_textwrap.py create mode 100644 Lib/site-packages/click/_unicodefun.py create mode 100644 Lib/site-packages/click/_winconsole.py create mode 100644 Lib/site-packages/click/core.py create mode 100644 Lib/site-packages/click/decorators.py create mode 100644 Lib/site-packages/click/exceptions.py create mode 100644 Lib/site-packages/click/formatting.py create mode 100644 Lib/site-packages/click/globals.py create mode 100644 Lib/site-packages/click/parser.py create mode 100644 Lib/site-packages/click/termui.py create mode 100644 Lib/site-packages/click/testing.py create mode 100644 Lib/site-packages/click/types.py create mode 100644 Lib/site-packages/click/utils.py create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/DESCRIPTION.rst create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/INSTALLER create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/METADATA create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/RECORD create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/WHEEL create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/metadata.json create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/pbr.json create mode 100644 Lib/site-packages/colorama-0.3.9.dist-info/top_level.txt create mode 100644 Lib/site-packages/colorama/__init__.py create mode 100644 Lib/site-packages/colorama/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/colorama/__pycache__/ansi.cpython-37.pyc create mode 100644 Lib/site-packages/colorama/__pycache__/ansitowin32.cpython-37.pyc create mode 100644 Lib/site-packages/colorama/__pycache__/initialise.cpython-37.pyc create mode 100644 Lib/site-packages/colorama/__pycache__/win32.cpython-37.pyc create mode 100644 Lib/site-packages/colorama/__pycache__/winterm.cpython-37.pyc create mode 100644 Lib/site-packages/colorama/ansi.py create mode 100644 Lib/site-packages/colorama/ansitowin32.py create mode 100644 Lib/site-packages/colorama/initialise.py create mode 100644 Lib/site-packages/colorama/win32.py create mode 100644 Lib/site-packages/colorama/winterm.py create mode 100644 Lib/site-packages/easy_install.py create mode 100644 Lib/site-packages/flask/__init__.py create mode 100644 Lib/site-packages/flask/__main__.py create mode 100644 Lib/site-packages/flask/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/__main__.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/app.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/blueprints.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/cli.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/config.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/ctx.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/debughelpers.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/globals.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/helpers.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/logging.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/sessions.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/signals.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/templating.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/testing.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/views.cpython-37.pyc create mode 100644 Lib/site-packages/flask/__pycache__/wrappers.cpython-37.pyc create mode 100644 Lib/site-packages/flask/_compat.py create mode 100644 Lib/site-packages/flask/app.py create mode 100644 Lib/site-packages/flask/blueprints.py create mode 100644 Lib/site-packages/flask/cli.py create mode 100644 Lib/site-packages/flask/config.py create mode 100644 Lib/site-packages/flask/ctx.py create mode 100644 Lib/site-packages/flask/debughelpers.py create mode 100644 Lib/site-packages/flask/globals.py create mode 100644 Lib/site-packages/flask/helpers.py create mode 100644 Lib/site-packages/flask/json/__init__.py create mode 100644 Lib/site-packages/flask/json/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/flask/json/__pycache__/tag.cpython-37.pyc create mode 100644 Lib/site-packages/flask/json/tag.py create mode 100644 Lib/site-packages/flask/logging.py create mode 100644 Lib/site-packages/flask/sessions.py create mode 100644 Lib/site-packages/flask/signals.py create mode 100644 Lib/site-packages/flask/templating.py create mode 100644 Lib/site-packages/flask/testing.py create mode 100644 Lib/site-packages/flask/views.py create mode 100644 Lib/site-packages/flask/wrappers.py create mode 100644 Lib/site-packages/flask_wtf/__init__.py create mode 100644 Lib/site-packages/flask_wtf/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/__pycache__/csrf.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/__pycache__/file.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/__pycache__/form.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/__pycache__/html5.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/__pycache__/i18n.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/_compat.py create mode 100644 Lib/site-packages/flask_wtf/csrf.py create mode 100644 Lib/site-packages/flask_wtf/file.py create mode 100644 Lib/site-packages/flask_wtf/form.py create mode 100644 Lib/site-packages/flask_wtf/html5.py create mode 100644 Lib/site-packages/flask_wtf/i18n.py create mode 100644 Lib/site-packages/flask_wtf/recaptcha/__init__.py create mode 100644 Lib/site-packages/flask_wtf/recaptcha/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/recaptcha/__pycache__/fields.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/recaptcha/__pycache__/validators.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/recaptcha/__pycache__/widgets.cpython-37.pyc create mode 100644 Lib/site-packages/flask_wtf/recaptcha/fields.py create mode 100644 Lib/site-packages/flask_wtf/recaptcha/validators.py create mode 100644 Lib/site-packages/flask_wtf/recaptcha/widgets.py create mode 100644 Lib/site-packages/itsdangerous-0.24.dist-info/INSTALLER create mode 100644 Lib/site-packages/itsdangerous-0.24.dist-info/METADATA create mode 100644 Lib/site-packages/itsdangerous-0.24.dist-info/RECORD create mode 100644 Lib/site-packages/itsdangerous-0.24.dist-info/WHEEL create mode 100644 Lib/site-packages/itsdangerous-0.24.dist-info/top_level.txt create mode 100644 Lib/site-packages/itsdangerous.py create mode 100644 Lib/site-packages/jinja2/__init__.py create mode 100644 Lib/site-packages/jinja2/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/_identifier.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/asyncfilters.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/asyncsupport.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/bccache.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/compiler.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/constants.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/debug.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/defaults.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/environment.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/ext.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/filters.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/idtracking.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/lexer.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/loaders.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/meta.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/nativetypes.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/nodes.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/optimizer.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/parser.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/runtime.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/sandbox.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/tests.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/__pycache__/visitor.cpython-37.pyc create mode 100644 Lib/site-packages/jinja2/_compat.py create mode 100644 Lib/site-packages/jinja2/_identifier.py create mode 100644 Lib/site-packages/jinja2/asyncfilters.py create mode 100644 Lib/site-packages/jinja2/asyncsupport.py create mode 100644 Lib/site-packages/jinja2/bccache.py create mode 100644 Lib/site-packages/jinja2/compiler.py create mode 100644 Lib/site-packages/jinja2/constants.py create mode 100644 Lib/site-packages/jinja2/debug.py create mode 100644 Lib/site-packages/jinja2/defaults.py create mode 100644 Lib/site-packages/jinja2/environment.py create mode 100644 Lib/site-packages/jinja2/exceptions.py create mode 100644 Lib/site-packages/jinja2/ext.py create mode 100644 Lib/site-packages/jinja2/filters.py create mode 100644 Lib/site-packages/jinja2/idtracking.py create mode 100644 Lib/site-packages/jinja2/lexer.py create mode 100644 Lib/site-packages/jinja2/loaders.py create mode 100644 Lib/site-packages/jinja2/meta.py create mode 100644 Lib/site-packages/jinja2/nativetypes.py create mode 100644 Lib/site-packages/jinja2/nodes.py create mode 100644 Lib/site-packages/jinja2/optimizer.py create mode 100644 Lib/site-packages/jinja2/parser.py create mode 100644 Lib/site-packages/jinja2/runtime.py create mode 100644 Lib/site-packages/jinja2/sandbox.py create mode 100644 Lib/site-packages/jinja2/tests.py create mode 100644 Lib/site-packages/jinja2/utils.py create mode 100644 Lib/site-packages/jinja2/visitor.py create mode 100644 Lib/site-packages/markupsafe/__init__.py create mode 100644 Lib/site-packages/markupsafe/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/markupsafe/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/markupsafe/__pycache__/_constants.cpython-37.pyc create mode 100644 Lib/site-packages/markupsafe/__pycache__/_native.cpython-37.pyc create mode 100644 Lib/site-packages/markupsafe/_compat.py create mode 100644 Lib/site-packages/markupsafe/_constants.py create mode 100644 Lib/site-packages/markupsafe/_native.py create mode 100644 Lib/site-packages/markupsafe/_speedups.c create mode 100644 Lib/site-packages/more_itertools-4.3.0.dist-info/INSTALLER create mode 100644 Lib/site-packages/more_itertools-4.3.0.dist-info/METADATA create mode 100644 Lib/site-packages/more_itertools-4.3.0.dist-info/RECORD create mode 100644 Lib/site-packages/more_itertools-4.3.0.dist-info/WHEEL create mode 100644 Lib/site-packages/more_itertools-4.3.0.dist-info/top_level.txt create mode 100644 Lib/site-packages/more_itertools/__init__.py create mode 100644 Lib/site-packages/more_itertools/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/more_itertools/__pycache__/more.cpython-37.pyc create mode 100644 Lib/site-packages/more_itertools/__pycache__/recipes.cpython-37.pyc create mode 100644 Lib/site-packages/more_itertools/more.py create mode 100644 Lib/site-packages/more_itertools/recipes.py create mode 100644 Lib/site-packages/more_itertools/tests/__init__.py create mode 100644 Lib/site-packages/more_itertools/tests/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/more_itertools/tests/__pycache__/test_more.cpython-37.pyc create mode 100644 Lib/site-packages/more_itertools/tests/__pycache__/test_recipes.cpython-37.pyc create mode 100644 Lib/site-packages/more_itertools/tests/test_more.py create mode 100644 Lib/site-packages/more_itertools/tests/test_recipes.py create mode 100644 Lib/site-packages/pip-18.0.dist-info/INSTALLER create mode 100644 Lib/site-packages/pip-18.0.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/pip-18.0.dist-info/METADATA create mode 100644 Lib/site-packages/pip-18.0.dist-info/RECORD create mode 100644 Lib/site-packages/pip-18.0.dist-info/WHEEL create mode 100644 Lib/site-packages/pip-18.0.dist-info/entry_points.txt create mode 100644 Lib/site-packages/pip-18.0.dist-info/top_level.txt create mode 100644 Lib/site-packages/pip/__init__.py create mode 100644 Lib/site-packages/pip/__main__.py create mode 100644 Lib/site-packages/pip/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/__pycache__/__main__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__init__.py create mode 100644 Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/basecommand.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/baseparser.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/cmdoptions.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/index.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/locations.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/status_codes.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/__pycache__/wheel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/basecommand.py create mode 100644 Lib/site-packages/pip/_internal/baseparser.py create mode 100644 Lib/site-packages/pip/_internal/build_env.py create mode 100644 Lib/site-packages/pip/_internal/cache.py create mode 100644 Lib/site-packages/pip/_internal/cmdoptions.py create mode 100644 Lib/site-packages/pip/_internal/commands/__init__.py create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/download.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/show.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/commands/check.py create mode 100644 Lib/site-packages/pip/_internal/commands/completion.py create mode 100644 Lib/site-packages/pip/_internal/commands/configuration.py create mode 100644 Lib/site-packages/pip/_internal/commands/download.py create mode 100644 Lib/site-packages/pip/_internal/commands/freeze.py create mode 100644 Lib/site-packages/pip/_internal/commands/hash.py create mode 100644 Lib/site-packages/pip/_internal/commands/help.py create mode 100644 Lib/site-packages/pip/_internal/commands/install.py create mode 100644 Lib/site-packages/pip/_internal/commands/list.py create mode 100644 Lib/site-packages/pip/_internal/commands/search.py create mode 100644 Lib/site-packages/pip/_internal/commands/show.py create mode 100644 Lib/site-packages/pip/_internal/commands/uninstall.py create mode 100644 Lib/site-packages/pip/_internal/commands/wheel.py create mode 100644 Lib/site-packages/pip/_internal/compat.py create mode 100644 Lib/site-packages/pip/_internal/configuration.py create mode 100644 Lib/site-packages/pip/_internal/download.py create mode 100644 Lib/site-packages/pip/_internal/exceptions.py create mode 100644 Lib/site-packages/pip/_internal/index.py create mode 100644 Lib/site-packages/pip/_internal/locations.py create mode 100644 Lib/site-packages/pip/_internal/models/__init__.py create mode 100644 Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/models/index.py create mode 100644 Lib/site-packages/pip/_internal/operations/__init__.py create mode 100644 Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/operations/check.py create mode 100644 Lib/site-packages/pip/_internal/operations/freeze.py create mode 100644 Lib/site-packages/pip/_internal/operations/prepare.py create mode 100644 Lib/site-packages/pip/_internal/pep425tags.py create mode 100644 Lib/site-packages/pip/_internal/req/__init__.py create mode 100644 Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/req/req_file.py create mode 100644 Lib/site-packages/pip/_internal/req/req_install.py create mode 100644 Lib/site-packages/pip/_internal/req/req_set.py create mode 100644 Lib/site-packages/pip/_internal/req/req_tracker.py create mode 100644 Lib/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 Lib/site-packages/pip/_internal/resolve.py create mode 100644 Lib/site-packages/pip/_internal/status_codes.py create mode 100644 Lib/site-packages/pip/_internal/utils/__init__.py create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/typing.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/utils/appdirs.py create mode 100644 Lib/site-packages/pip/_internal/utils/deprecation.py create mode 100644 Lib/site-packages/pip/_internal/utils/encoding.py create mode 100644 Lib/site-packages/pip/_internal/utils/filesystem.py create mode 100644 Lib/site-packages/pip/_internal/utils/glibc.py create mode 100644 Lib/site-packages/pip/_internal/utils/hashes.py create mode 100644 Lib/site-packages/pip/_internal/utils/logging.py create mode 100644 Lib/site-packages/pip/_internal/utils/misc.py create mode 100644 Lib/site-packages/pip/_internal/utils/outdated.py create mode 100644 Lib/site-packages/pip/_internal/utils/packaging.py create mode 100644 Lib/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 Lib/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 Lib/site-packages/pip/_internal/utils/typing.py create mode 100644 Lib/site-packages/pip/_internal/utils/ui.py create mode 100644 Lib/site-packages/pip/_internal/vcs/__init__.py create mode 100644 Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 Lib/site-packages/pip/_internal/vcs/git.py create mode 100644 Lib/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 Lib/site-packages/pip/_internal/vcs/subversion.py create mode 100644 Lib/site-packages/pip/_internal/wheel.py create mode 100644 Lib/site-packages/pip/_vendor/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/appdirs.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 Lib/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 Lib/site-packages/pip/_vendor/certifi/core.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/compat.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/enums.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/langcyrillicmodel.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 Lib/site-packages/pip/_vendor/chardet/version.py create mode 100644 Lib/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 Lib/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 Lib/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 Lib/site-packages/pip/_vendor/colorama/win32.py create mode 100644 Lib/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/compat.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/database.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/index.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/locators.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/markers.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/resources.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 Lib/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 Lib/site-packages/pip/_vendor/distlib/util.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/version.py create mode 100644 Lib/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 Lib/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 Lib/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 Lib/site-packages/pip/_vendor/distro.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/datrie.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 Lib/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 Lib/site-packages/pip/_vendor/idna/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/idna/codec.py create mode 100644 Lib/site-packages/pip/_vendor/idna/compat.py create mode 100644 Lib/site-packages/pip/_vendor/idna/core.py create mode 100644 Lib/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 Lib/site-packages/pip/_vendor/idna/intranges.py create mode 100644 Lib/site-packages/pip/_vendor/idna/package_data.py create mode 100644 Lib/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 Lib/site-packages/pip/_vendor/ipaddress.py create mode 100644 Lib/site-packages/pip/_vendor/lockfile/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/lockfile/linklockfile.py create mode 100644 Lib/site-packages/pip/_vendor/lockfile/mkdirlockfile.py create mode 100644 Lib/site-packages/pip/_vendor/lockfile/pidlockfile.py create mode 100644 Lib/site-packages/pip/_vendor/lockfile/sqlitelockfile.py create mode 100644 Lib/site-packages/pip/_vendor/lockfile/symlinklockfile.py create mode 100644 Lib/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 Lib/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 Lib/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/packaging/_compat.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/markers.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/utils.py create mode 100644 Lib/site-packages/pip/_vendor/packaging/version.py create mode 100644 Lib/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 Lib/site-packages/pip/_vendor/progress/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/progress/bar.py create mode 100644 Lib/site-packages/pip/_vendor/progress/counter.py create mode 100644 Lib/site-packages/pip/_vendor/progress/helpers.py create mode 100644 Lib/site-packages/pip/_vendor/progress/spinner.py create mode 100644 Lib/site-packages/pip/_vendor/pyparsing.py create mode 100644 Lib/site-packages/pip/_vendor/pytoml/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/pytoml/core.py create mode 100644 Lib/site-packages/pip/_vendor/pytoml/parser.py create mode 100644 Lib/site-packages/pip/_vendor/pytoml/writer.py create mode 100644 Lib/site-packages/pip/_vendor/requests/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/requests/__version__.py create mode 100644 Lib/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 Lib/site-packages/pip/_vendor/requests/adapters.py create mode 100644 Lib/site-packages/pip/_vendor/requests/api.py create mode 100644 Lib/site-packages/pip/_vendor/requests/auth.py create mode 100644 Lib/site-packages/pip/_vendor/requests/certs.py create mode 100644 Lib/site-packages/pip/_vendor/requests/compat.py create mode 100644 Lib/site-packages/pip/_vendor/requests/cookies.py create mode 100644 Lib/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 Lib/site-packages/pip/_vendor/requests/help.py create mode 100644 Lib/site-packages/pip/_vendor/requests/hooks.py create mode 100644 Lib/site-packages/pip/_vendor/requests/models.py create mode 100644 Lib/site-packages/pip/_vendor/requests/packages.py create mode 100644 Lib/site-packages/pip/_vendor/requests/sessions.py create mode 100644 Lib/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 Lib/site-packages/pip/_vendor/requests/structures.py create mode 100644 Lib/site-packages/pip/_vendor/requests/utils.py create mode 100644 Lib/site-packages/pip/_vendor/retrying.py create mode 100644 Lib/site-packages/pip/_vendor/six.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/request.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/response.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 Lib/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 Lib/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 Lib/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc create mode 100644 Lib/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 Lib/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 Lib/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 Lib/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 Lib/site-packages/pkg_resources/__init__.py create mode 100644 Lib/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 Lib/site-packages/pkg_resources/_vendor/six.py create mode 100644 Lib/site-packages/pkg_resources/extern/__init__.py create mode 100644 Lib/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pkg_resources/py31compat.py create mode 100644 Lib/site-packages/pluggy-0.7.1.dist-info/INSTALLER create mode 100644 Lib/site-packages/pluggy-0.7.1.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/pluggy-0.7.1.dist-info/METADATA create mode 100644 Lib/site-packages/pluggy-0.7.1.dist-info/RECORD create mode 100644 Lib/site-packages/pluggy-0.7.1.dist-info/WHEEL create mode 100644 Lib/site-packages/pluggy-0.7.1.dist-info/top_level.txt create mode 100644 Lib/site-packages/pluggy/__init__.py create mode 100644 Lib/site-packages/pluggy/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/pluggy/__pycache__/_tracing.cpython-37.pyc create mode 100644 Lib/site-packages/pluggy/__pycache__/_version.cpython-37.pyc create mode 100644 Lib/site-packages/pluggy/__pycache__/callers.cpython-37.pyc create mode 100644 Lib/site-packages/pluggy/__pycache__/hooks.cpython-37.pyc create mode 100644 Lib/site-packages/pluggy/__pycache__/manager.cpython-37.pyc create mode 100644 Lib/site-packages/pluggy/_tracing.py create mode 100644 Lib/site-packages/pluggy/_version.py create mode 100644 Lib/site-packages/pluggy/callers.py create mode 100644 Lib/site-packages/pluggy/hooks.py create mode 100644 Lib/site-packages/pluggy/manager.py create mode 100644 Lib/site-packages/py-1.5.4.dist-info/INSTALLER create mode 100644 Lib/site-packages/py-1.5.4.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/py-1.5.4.dist-info/METADATA create mode 100644 Lib/site-packages/py-1.5.4.dist-info/RECORD create mode 100644 Lib/site-packages/py-1.5.4.dist-info/WHEEL create mode 100644 Lib/site-packages/py-1.5.4.dist-info/top_level.txt create mode 100644 Lib/site-packages/py/__init__.py create mode 100644 Lib/site-packages/py/__metainfo.py create mode 100644 Lib/site-packages/py/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/py/__pycache__/__metainfo.cpython-37.pyc create mode 100644 Lib/site-packages/py/__pycache__/_builtin.cpython-37.pyc create mode 100644 Lib/site-packages/py/__pycache__/_error.cpython-37.pyc create mode 100644 Lib/site-packages/py/__pycache__/_std.cpython-37.pyc create mode 100644 Lib/site-packages/py/__pycache__/_version.cpython-37.pyc create mode 100644 Lib/site-packages/py/__pycache__/_xmlgen.cpython-37.pyc create mode 100644 Lib/site-packages/py/__pycache__/test.cpython-37.pyc create mode 100644 Lib/site-packages/py/_builtin.py create mode 100644 Lib/site-packages/py/_code/__init__.py create mode 100644 Lib/site-packages/py/_code/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/py/_code/__pycache__/_assertionnew.cpython-37.pyc create mode 100644 Lib/site-packages/py/_code/__pycache__/_assertionold.cpython-37.pyc create mode 100644 Lib/site-packages/py/_code/__pycache__/_py2traceback.cpython-37.pyc create mode 100644 Lib/site-packages/py/_code/__pycache__/assertion.cpython-37.pyc create mode 100644 Lib/site-packages/py/_code/__pycache__/code.cpython-37.pyc create mode 100644 Lib/site-packages/py/_code/__pycache__/source.cpython-37.pyc create mode 100644 Lib/site-packages/py/_code/_assertionnew.py create mode 100644 Lib/site-packages/py/_code/_assertionold.py create mode 100644 Lib/site-packages/py/_code/_py2traceback.py create mode 100644 Lib/site-packages/py/_code/assertion.py create mode 100644 Lib/site-packages/py/_code/code.py create mode 100644 Lib/site-packages/py/_code/source.py create mode 100644 Lib/site-packages/py/_error.py create mode 100644 Lib/site-packages/py/_io/__init__.py create mode 100644 Lib/site-packages/py/_io/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/py/_io/__pycache__/capture.cpython-37.pyc create mode 100644 Lib/site-packages/py/_io/__pycache__/saferepr.cpython-37.pyc create mode 100644 Lib/site-packages/py/_io/__pycache__/terminalwriter.cpython-37.pyc create mode 100644 Lib/site-packages/py/_io/capture.py create mode 100644 Lib/site-packages/py/_io/saferepr.py create mode 100644 Lib/site-packages/py/_io/terminalwriter.py create mode 100644 Lib/site-packages/py/_log/__init__.py create mode 100644 Lib/site-packages/py/_log/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/py/_log/__pycache__/log.cpython-37.pyc create mode 100644 Lib/site-packages/py/_log/__pycache__/warning.cpython-37.pyc create mode 100644 Lib/site-packages/py/_log/log.py create mode 100644 Lib/site-packages/py/_log/warning.py create mode 100644 Lib/site-packages/py/_path/__init__.py create mode 100644 Lib/site-packages/py/_path/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/py/_path/__pycache__/cacheutil.cpython-37.pyc create mode 100644 Lib/site-packages/py/_path/__pycache__/common.cpython-37.pyc create mode 100644 Lib/site-packages/py/_path/__pycache__/local.cpython-37.pyc create mode 100644 Lib/site-packages/py/_path/__pycache__/svnurl.cpython-37.pyc create mode 100644 Lib/site-packages/py/_path/__pycache__/svnwc.cpython-37.pyc create mode 100644 Lib/site-packages/py/_path/cacheutil.py create mode 100644 Lib/site-packages/py/_path/common.py create mode 100644 Lib/site-packages/py/_path/local.py create mode 100644 Lib/site-packages/py/_path/svnurl.py create mode 100644 Lib/site-packages/py/_path/svnwc.py create mode 100644 Lib/site-packages/py/_process/__init__.py create mode 100644 Lib/site-packages/py/_process/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/py/_process/__pycache__/cmdexec.cpython-37.pyc create mode 100644 Lib/site-packages/py/_process/__pycache__/forkedfunc.cpython-37.pyc create mode 100644 Lib/site-packages/py/_process/__pycache__/killproc.cpython-37.pyc create mode 100644 Lib/site-packages/py/_process/cmdexec.py create mode 100644 Lib/site-packages/py/_process/forkedfunc.py create mode 100644 Lib/site-packages/py/_process/killproc.py create mode 100644 Lib/site-packages/py/_std.py create mode 100644 Lib/site-packages/py/_vendored_packages/__init__.py create mode 100644 Lib/site-packages/py/_vendored_packages/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/py/_vendored_packages/__pycache__/apipkg.cpython-37.pyc create mode 100644 Lib/site-packages/py/_vendored_packages/__pycache__/iniconfig.cpython-37.pyc create mode 100644 Lib/site-packages/py/_vendored_packages/apipkg.py create mode 100644 Lib/site-packages/py/_vendored_packages/iniconfig.py create mode 100644 Lib/site-packages/py/_version.py create mode 100644 Lib/site-packages/py/_xmlgen.py create mode 100644 Lib/site-packages/py/test.py create mode 100644 Lib/site-packages/pytest-3.7.1.dist-info/INSTALLER create mode 100644 Lib/site-packages/pytest-3.7.1.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/pytest-3.7.1.dist-info/METADATA create mode 100644 Lib/site-packages/pytest-3.7.1.dist-info/RECORD create mode 100644 Lib/site-packages/pytest-3.7.1.dist-info/WHEEL create mode 100644 Lib/site-packages/pytest-3.7.1.dist-info/entry_points.txt create mode 100644 Lib/site-packages/pytest-3.7.1.dist-info/top_level.txt create mode 100644 Lib/site-packages/pytest.py create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/INSTALLER create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/METADATA create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/RECORD create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/WHEEL create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/dependency_links.txt create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/entry_points.txt create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/top_level.txt create mode 100644 Lib/site-packages/setuptools-40.0.0.dist-info/zip-safe create mode 100644 Lib/site-packages/setuptools/__init__.py create mode 100644 Lib/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/config.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/depends.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/dist.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/extension.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/glob.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/launch.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/version.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/__init__.py create mode 100644 Lib/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 Lib/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 Lib/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 Lib/site-packages/setuptools/_vendor/six.py create mode 100644 Lib/site-packages/setuptools/archive_util.py create mode 100644 Lib/site-packages/setuptools/build_meta.py create mode 100644 Lib/site-packages/setuptools/cli-32.exe create mode 100644 Lib/site-packages/setuptools/cli-64.exe create mode 100644 Lib/site-packages/setuptools/cli.exe create mode 100644 Lib/site-packages/setuptools/command/__init__.py create mode 100644 Lib/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/command/alias.py create mode 100644 Lib/site-packages/setuptools/command/bdist_egg.py create mode 100644 Lib/site-packages/setuptools/command/bdist_rpm.py create mode 100644 Lib/site-packages/setuptools/command/bdist_wininst.py create mode 100644 Lib/site-packages/setuptools/command/build_clib.py create mode 100644 Lib/site-packages/setuptools/command/build_ext.py create mode 100644 Lib/site-packages/setuptools/command/build_py.py create mode 100644 Lib/site-packages/setuptools/command/develop.py create mode 100644 Lib/site-packages/setuptools/command/dist_info.py create mode 100644 Lib/site-packages/setuptools/command/easy_install.py create mode 100644 Lib/site-packages/setuptools/command/egg_info.py create mode 100644 Lib/site-packages/setuptools/command/install.py create mode 100644 Lib/site-packages/setuptools/command/install_egg_info.py create mode 100644 Lib/site-packages/setuptools/command/install_lib.py create mode 100644 Lib/site-packages/setuptools/command/install_scripts.py create mode 100644 Lib/site-packages/setuptools/command/launcher manifest.xml create mode 100644 Lib/site-packages/setuptools/command/py36compat.py create mode 100644 Lib/site-packages/setuptools/command/register.py create mode 100644 Lib/site-packages/setuptools/command/rotate.py create mode 100644 Lib/site-packages/setuptools/command/saveopts.py create mode 100644 Lib/site-packages/setuptools/command/sdist.py create mode 100644 Lib/site-packages/setuptools/command/setopt.py create mode 100644 Lib/site-packages/setuptools/command/test.py create mode 100644 Lib/site-packages/setuptools/command/upload.py create mode 100644 Lib/site-packages/setuptools/command/upload_docs.py create mode 100644 Lib/site-packages/setuptools/config.py create mode 100644 Lib/site-packages/setuptools/dep_util.py create mode 100644 Lib/site-packages/setuptools/depends.py create mode 100644 Lib/site-packages/setuptools/dist.py create mode 100644 Lib/site-packages/setuptools/extension.py create mode 100644 Lib/site-packages/setuptools/extern/__init__.py create mode 100644 Lib/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/setuptools/glibc.py create mode 100644 Lib/site-packages/setuptools/glob.py create mode 100644 Lib/site-packages/setuptools/gui-32.exe create mode 100644 Lib/site-packages/setuptools/gui-64.exe create mode 100644 Lib/site-packages/setuptools/gui.exe create mode 100644 Lib/site-packages/setuptools/launch.py create mode 100644 Lib/site-packages/setuptools/lib2to3_ex.py create mode 100644 Lib/site-packages/setuptools/monkey.py create mode 100644 Lib/site-packages/setuptools/msvc.py create mode 100644 Lib/site-packages/setuptools/namespaces.py create mode 100644 Lib/site-packages/setuptools/package_index.py create mode 100644 Lib/site-packages/setuptools/pep425tags.py create mode 100644 Lib/site-packages/setuptools/py27compat.py create mode 100644 Lib/site-packages/setuptools/py31compat.py create mode 100644 Lib/site-packages/setuptools/py33compat.py create mode 100644 Lib/site-packages/setuptools/py36compat.py create mode 100644 Lib/site-packages/setuptools/sandbox.py create mode 100644 Lib/site-packages/setuptools/script (dev).tmpl create mode 100644 Lib/site-packages/setuptools/script.tmpl create mode 100644 Lib/site-packages/setuptools/site-patch.py create mode 100644 Lib/site-packages/setuptools/ssl_support.py create mode 100644 Lib/site-packages/setuptools/unicode_utils.py create mode 100644 Lib/site-packages/setuptools/version.py create mode 100644 Lib/site-packages/setuptools/wheel.py create mode 100644 Lib/site-packages/setuptools/windows_support.py create mode 100644 Lib/site-packages/six-1.11.0.dist-info/DESCRIPTION.rst create mode 100644 Lib/site-packages/six-1.11.0.dist-info/INSTALLER create mode 100644 Lib/site-packages/six-1.11.0.dist-info/METADATA create mode 100644 Lib/site-packages/six-1.11.0.dist-info/RECORD create mode 100644 Lib/site-packages/six-1.11.0.dist-info/WHEEL create mode 100644 Lib/site-packages/six-1.11.0.dist-info/metadata.json create mode 100644 Lib/site-packages/six-1.11.0.dist-info/top_level.txt create mode 100644 Lib/site-packages/six.py create mode 100644 Lib/site-packages/werkzeug/__init__.py create mode 100644 Lib/site-packages/werkzeug/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/_compat.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/_internal.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/_reloader.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/datastructures.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/exceptions.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/filesystem.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/formparser.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/http.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/local.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/posixemulation.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/routing.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/script.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/security.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/serving.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/test.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/testapp.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/urls.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/useragents.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/websocket.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/wrappers.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/__pycache__/wsgi.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/_compat.py create mode 100644 Lib/site-packages/werkzeug/_internal.py create mode 100644 Lib/site-packages/werkzeug/_reloader.py create mode 100644 Lib/site-packages/werkzeug/contrib/__init__.py create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/atom.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/cache.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/fixers.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/iterio.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/jsrouting.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/limiter.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/lint.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/profiler.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/securecookie.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/sessions.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/testtools.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/__pycache__/wrappers.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/contrib/atom.py create mode 100644 Lib/site-packages/werkzeug/contrib/cache.py create mode 100644 Lib/site-packages/werkzeug/contrib/fixers.py create mode 100644 Lib/site-packages/werkzeug/contrib/iterio.py create mode 100644 Lib/site-packages/werkzeug/contrib/jsrouting.py create mode 100644 Lib/site-packages/werkzeug/contrib/limiter.py create mode 100644 Lib/site-packages/werkzeug/contrib/lint.py create mode 100644 Lib/site-packages/werkzeug/contrib/profiler.py create mode 100644 Lib/site-packages/werkzeug/contrib/securecookie.py create mode 100644 Lib/site-packages/werkzeug/contrib/sessions.py create mode 100644 Lib/site-packages/werkzeug/contrib/testtools.py create mode 100644 Lib/site-packages/werkzeug/contrib/wrappers.py create mode 100644 Lib/site-packages/werkzeug/datastructures.py create mode 100644 Lib/site-packages/werkzeug/debug/__init__.py create mode 100644 Lib/site-packages/werkzeug/debug/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/debug/__pycache__/console.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/debug/__pycache__/repr.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-37.pyc create mode 100644 Lib/site-packages/werkzeug/debug/console.py create mode 100644 Lib/site-packages/werkzeug/debug/repr.py create mode 100644 Lib/site-packages/werkzeug/debug/shared/FONT_LICENSE create mode 100644 Lib/site-packages/werkzeug/debug/shared/console.png create mode 100644 Lib/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 Lib/site-packages/werkzeug/debug/shared/jquery.js create mode 100644 Lib/site-packages/werkzeug/debug/shared/less.png create mode 100644 Lib/site-packages/werkzeug/debug/shared/more.png create mode 100644 Lib/site-packages/werkzeug/debug/shared/source.png create mode 100644 Lib/site-packages/werkzeug/debug/shared/style.css create mode 100644 Lib/site-packages/werkzeug/debug/shared/ubuntu.ttf create mode 100644 Lib/site-packages/werkzeug/debug/tbtools.py create mode 100644 Lib/site-packages/werkzeug/exceptions.py create mode 100644 Lib/site-packages/werkzeug/filesystem.py create mode 100644 Lib/site-packages/werkzeug/formparser.py create mode 100644 Lib/site-packages/werkzeug/http.py create mode 100644 Lib/site-packages/werkzeug/local.py create mode 100644 Lib/site-packages/werkzeug/posixemulation.py create mode 100644 Lib/site-packages/werkzeug/routing.py create mode 100644 Lib/site-packages/werkzeug/script.py create mode 100644 Lib/site-packages/werkzeug/security.py create mode 100644 Lib/site-packages/werkzeug/serving.py create mode 100644 Lib/site-packages/werkzeug/test.py create mode 100644 Lib/site-packages/werkzeug/testapp.py create mode 100644 Lib/site-packages/werkzeug/urls.py create mode 100644 Lib/site-packages/werkzeug/useragents.py create mode 100644 Lib/site-packages/werkzeug/utils.py create mode 100644 Lib/site-packages/werkzeug/websocket.py create mode 100644 Lib/site-packages/werkzeug/wrappers.py create mode 100644 Lib/site-packages/werkzeug/wsgi.py create mode 100644 Lib/site-packages/wheel-0.31.1.dist-info/INSTALLER create mode 100644 Lib/site-packages/wheel-0.31.1.dist-info/LICENSE.txt create mode 100644 Lib/site-packages/wheel-0.31.1.dist-info/METADATA create mode 100644 Lib/site-packages/wheel-0.31.1.dist-info/RECORD create mode 100644 Lib/site-packages/wheel-0.31.1.dist-info/WHEEL create mode 100644 Lib/site-packages/wheel-0.31.1.dist-info/entry_points.txt create mode 100644 Lib/site-packages/wheel-0.31.1.dist-info/top_level.txt create mode 100644 Lib/site-packages/wheel/__init__.py create mode 100644 Lib/site-packages/wheel/__main__.py create mode 100644 Lib/site-packages/wheel/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/__main__.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/archive.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/bdist_wheel.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/egg2wheel.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/install.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/metadata.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/paths.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/pep425tags.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/pkginfo.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/util.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/__pycache__/wininst2wheel.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/archive.py create mode 100644 Lib/site-packages/wheel/bdist_wheel.py create mode 100644 Lib/site-packages/wheel/egg2wheel.py create mode 100644 Lib/site-packages/wheel/install.py create mode 100644 Lib/site-packages/wheel/metadata.py create mode 100644 Lib/site-packages/wheel/paths.py create mode 100644 Lib/site-packages/wheel/pep425tags.py create mode 100644 Lib/site-packages/wheel/pkginfo.py create mode 100644 Lib/site-packages/wheel/signatures/__init__.py create mode 100644 Lib/site-packages/wheel/signatures/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/signatures/__pycache__/djbec.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/signatures/__pycache__/ed25519py.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/signatures/__pycache__/keys.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/signatures/djbec.py create mode 100644 Lib/site-packages/wheel/signatures/ed25519py.py create mode 100644 Lib/site-packages/wheel/signatures/keys.py create mode 100644 Lib/site-packages/wheel/tool/__init__.py create mode 100644 Lib/site-packages/wheel/tool/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wheel/util.py create mode 100644 Lib/site-packages/wheel/wininst2wheel.py create mode 100644 Lib/site-packages/wtforms/__init__.py create mode 100644 Lib/site-packages/wtforms/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/__pycache__/compat.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/__pycache__/form.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/__pycache__/i18n.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/__pycache__/meta.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/__pycache__/validators.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/compat.py create mode 100644 Lib/site-packages/wtforms/csrf/__init__.py create mode 100644 Lib/site-packages/wtforms/csrf/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/csrf/__pycache__/core.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/csrf/__pycache__/session.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/csrf/core.py create mode 100644 Lib/site-packages/wtforms/csrf/session.py create mode 100644 Lib/site-packages/wtforms/ext/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/appengine/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/appengine/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/appengine/__pycache__/db.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/appengine/__pycache__/fields.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/appengine/__pycache__/ndb.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/appengine/db.py create mode 100644 Lib/site-packages/wtforms/ext/appengine/fields.py create mode 100644 Lib/site-packages/wtforms/ext/appengine/ndb.py create mode 100644 Lib/site-packages/wtforms/ext/csrf/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/csrf/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/csrf/__pycache__/fields.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/csrf/__pycache__/form.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/csrf/__pycache__/session.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/csrf/fields.py create mode 100644 Lib/site-packages/wtforms/ext/csrf/form.py create mode 100644 Lib/site-packages/wtforms/ext/csrf/session.py create mode 100644 Lib/site-packages/wtforms/ext/dateutil/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/dateutil/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/dateutil/__pycache__/fields.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/dateutil/fields.py create mode 100644 Lib/site-packages/wtforms/ext/django/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/django/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/django/__pycache__/fields.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/django/__pycache__/i18n.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/django/__pycache__/orm.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/django/fields.py create mode 100644 Lib/site-packages/wtforms/ext/django/i18n.py create mode 100644 Lib/site-packages/wtforms/ext/django/orm.py create mode 100644 Lib/site-packages/wtforms/ext/django/templatetags/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/django/templatetags/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/django/templatetags/__pycache__/wtforms.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/django/templatetags/wtforms.py create mode 100644 Lib/site-packages/wtforms/ext/i18n/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/i18n/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/i18n/__pycache__/form.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/i18n/__pycache__/utils.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/i18n/form.py create mode 100644 Lib/site-packages/wtforms/ext/i18n/utils.py create mode 100644 Lib/site-packages/wtforms/ext/sqlalchemy/__init__.py create mode 100644 Lib/site-packages/wtforms/ext/sqlalchemy/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/sqlalchemy/__pycache__/fields.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/sqlalchemy/__pycache__/orm.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/ext/sqlalchemy/fields.py create mode 100644 Lib/site-packages/wtforms/ext/sqlalchemy/orm.py create mode 100644 Lib/site-packages/wtforms/fields/__init__.py create mode 100644 Lib/site-packages/wtforms/fields/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/fields/__pycache__/core.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/fields/__pycache__/html5.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/fields/__pycache__/simple.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/fields/core.py create mode 100644 Lib/site-packages/wtforms/fields/html5.py create mode 100644 Lib/site-packages/wtforms/fields/simple.py create mode 100644 Lib/site-packages/wtforms/form.py create mode 100644 Lib/site-packages/wtforms/i18n.py create mode 100644 Lib/site-packages/wtforms/locale/README.md create mode 100644 Lib/site-packages/wtforms/locale/ar/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/ar/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/bg/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/bg/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/ca/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/ca/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/cs_CZ/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/cs_CZ/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/cy/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/cy/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/de/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/de/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/de_CH/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/de_CH/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/el/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/el/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/en/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/en/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/es/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/es/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/et/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/et/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/fa/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/fa/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/fi/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/fi/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/fr/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/fr/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/he/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/he/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/hu/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/hu/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/it/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/it/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/ja/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/ja/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/ko/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/ko/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/nb/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/nb/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/nl/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/nl/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/pl/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/pl/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/pt/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/pt/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/ru/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/ru/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/sk/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/sk/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/sv/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/sv/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/tr/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/tr/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/uk/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/uk/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/wtforms.pot create mode 100644 Lib/site-packages/wtforms/locale/zh/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/zh/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/locale/zh_TW/LC_MESSAGES/wtforms.mo create mode 100644 Lib/site-packages/wtforms/locale/zh_TW/LC_MESSAGES/wtforms.po create mode 100644 Lib/site-packages/wtforms/meta.py create mode 100644 Lib/site-packages/wtforms/utils.py create mode 100644 Lib/site-packages/wtforms/validators.py create mode 100644 Lib/site-packages/wtforms/widgets/__init__.py create mode 100644 Lib/site-packages/wtforms/widgets/__pycache__/__init__.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/widgets/__pycache__/core.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/widgets/__pycache__/html5.cpython-37.pyc create mode 100644 Lib/site-packages/wtforms/widgets/core.py create mode 100644 Lib/site-packages/wtforms/widgets/html5.py create mode 100644 Lib/site.py create mode 100644 Lib/sre_compile.py create mode 100644 Lib/sre_constants.py create mode 100644 Lib/sre_parse.py create mode 100644 Lib/stat.py create mode 100644 Lib/struct.py create mode 100644 Lib/tarfile.py create mode 100644 Lib/tempfile.py create mode 100644 Lib/token.py create mode 100644 Lib/tokenize.py create mode 100644 Lib/types.py create mode 100644 Lib/warnings.py create mode 100644 Lib/weakref.py create mode 100644 Questions/question.html create mode 100644 Questions/questions.py create mode 100644 Questions/test.py create mode 100644 Questions/test_Questions.py create mode 100644 Scripts/activate create mode 100644 Scripts/activate.bat create mode 100644 Scripts/activate.ps1 create mode 100644 Scripts/activate_this.py create mode 100644 Scripts/deactivate.bat create mode 100644 Scripts/easy_install-3.7.exe create mode 100644 Scripts/easy_install.exe create mode 100644 Scripts/flask.exe create mode 100644 Scripts/pip.exe create mode 100644 Scripts/pip3.7.exe create mode 100644 Scripts/pip3.exe create mode 100644 Scripts/py.test.exe create mode 100644 Scripts/pytest.exe create mode 100644 Scripts/python.exe create mode 100644 Scripts/python3.dll create mode 100644 Scripts/python37.dll create mode 100644 Scripts/pythonw.exe create mode 100644 Scripts/wheel.exe create mode 100644 StackOverflow-LiteAPI.travis.yml create mode 100644 Static/main.js create mode 100644 Static/mains.css create mode 100644 Users/Users.py create mode 100644 Users/test_Users.py create mode 100644 __pycache__/run.cpython-37.pyc create mode 100644 pip-selfcheck.json create mode 100644 requirements.txt create mode 100644 run.py create mode 100644 tcl/tcl8.6/auto.tcl create mode 100644 tcl/tcl8.6/clock.tcl create mode 100644 tcl/tcl8.6/encoding/ascii.enc create mode 100644 tcl/tcl8.6/encoding/big5.enc create mode 100644 tcl/tcl8.6/encoding/cp1250.enc create mode 100644 tcl/tcl8.6/encoding/cp1251.enc create mode 100644 tcl/tcl8.6/encoding/cp1252.enc create mode 100644 tcl/tcl8.6/encoding/cp1253.enc create mode 100644 tcl/tcl8.6/encoding/cp1254.enc create mode 100644 tcl/tcl8.6/encoding/cp1255.enc create mode 100644 tcl/tcl8.6/encoding/cp1256.enc create mode 100644 tcl/tcl8.6/encoding/cp1257.enc create mode 100644 tcl/tcl8.6/encoding/cp1258.enc create mode 100644 tcl/tcl8.6/encoding/cp437.enc create mode 100644 tcl/tcl8.6/encoding/cp737.enc create mode 100644 tcl/tcl8.6/encoding/cp775.enc create mode 100644 tcl/tcl8.6/encoding/cp850.enc create mode 100644 tcl/tcl8.6/encoding/cp852.enc create mode 100644 tcl/tcl8.6/encoding/cp855.enc create mode 100644 tcl/tcl8.6/encoding/cp857.enc create mode 100644 tcl/tcl8.6/encoding/cp860.enc create mode 100644 tcl/tcl8.6/encoding/cp861.enc create mode 100644 tcl/tcl8.6/encoding/cp862.enc create mode 100644 tcl/tcl8.6/encoding/cp863.enc create mode 100644 tcl/tcl8.6/encoding/cp864.enc create mode 100644 tcl/tcl8.6/encoding/cp865.enc create mode 100644 tcl/tcl8.6/encoding/cp866.enc create mode 100644 tcl/tcl8.6/encoding/cp869.enc create mode 100644 tcl/tcl8.6/encoding/cp874.enc create mode 100644 tcl/tcl8.6/encoding/cp932.enc create mode 100644 tcl/tcl8.6/encoding/cp936.enc create mode 100644 tcl/tcl8.6/encoding/cp949.enc create mode 100644 tcl/tcl8.6/encoding/cp950.enc create mode 100644 tcl/tcl8.6/encoding/dingbats.enc create mode 100644 tcl/tcl8.6/encoding/ebcdic.enc create mode 100644 tcl/tcl8.6/encoding/euc-cn.enc create mode 100644 tcl/tcl8.6/encoding/euc-jp.enc create mode 100644 tcl/tcl8.6/encoding/euc-kr.enc create mode 100644 tcl/tcl8.6/encoding/gb12345.enc create mode 100644 tcl/tcl8.6/encoding/gb1988.enc create mode 100644 tcl/tcl8.6/encoding/gb2312-raw.enc create mode 100644 tcl/tcl8.6/encoding/gb2312.enc create mode 100644 tcl/tcl8.6/encoding/iso2022-jp.enc create mode 100644 tcl/tcl8.6/encoding/iso2022-kr.enc create mode 100644 tcl/tcl8.6/encoding/iso2022.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-1.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-10.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-13.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-14.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-15.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-16.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-2.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-3.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-4.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-5.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-6.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-7.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-8.enc create mode 100644 tcl/tcl8.6/encoding/iso8859-9.enc create mode 100644 tcl/tcl8.6/encoding/jis0201.enc create mode 100644 tcl/tcl8.6/encoding/jis0208.enc create mode 100644 tcl/tcl8.6/encoding/jis0212.enc create mode 100644 tcl/tcl8.6/encoding/koi8-r.enc create mode 100644 tcl/tcl8.6/encoding/koi8-u.enc create mode 100644 tcl/tcl8.6/encoding/ksc5601.enc create mode 100644 tcl/tcl8.6/encoding/macCentEuro.enc create mode 100644 tcl/tcl8.6/encoding/macCroatian.enc create mode 100644 tcl/tcl8.6/encoding/macCyrillic.enc create mode 100644 tcl/tcl8.6/encoding/macDingbats.enc create mode 100644 tcl/tcl8.6/encoding/macGreek.enc create mode 100644 tcl/tcl8.6/encoding/macIceland.enc create mode 100644 tcl/tcl8.6/encoding/macJapan.enc create mode 100644 tcl/tcl8.6/encoding/macRoman.enc create mode 100644 tcl/tcl8.6/encoding/macRomania.enc create mode 100644 tcl/tcl8.6/encoding/macThai.enc create mode 100644 tcl/tcl8.6/encoding/macTurkish.enc create mode 100644 tcl/tcl8.6/encoding/macUkraine.enc create mode 100644 tcl/tcl8.6/encoding/shiftjis.enc create mode 100644 tcl/tcl8.6/encoding/symbol.enc create mode 100644 tcl/tcl8.6/encoding/tis-620.enc create mode 100644 tcl/tcl8.6/history.tcl create mode 100644 tcl/tcl8.6/http1.0/http.tcl create mode 100644 tcl/tcl8.6/http1.0/pkgIndex.tcl create mode 100644 tcl/tcl8.6/init.tcl create mode 100644 tcl/tcl8.6/msgs/af.msg create mode 100644 tcl/tcl8.6/msgs/af_za.msg create mode 100644 tcl/tcl8.6/msgs/ar.msg create mode 100644 tcl/tcl8.6/msgs/ar_in.msg create mode 100644 tcl/tcl8.6/msgs/ar_jo.msg create mode 100644 tcl/tcl8.6/msgs/ar_lb.msg create mode 100644 tcl/tcl8.6/msgs/ar_sy.msg create mode 100644 tcl/tcl8.6/msgs/be.msg create mode 100644 tcl/tcl8.6/msgs/bg.msg create mode 100644 tcl/tcl8.6/msgs/bn.msg create mode 100644 tcl/tcl8.6/msgs/bn_in.msg create mode 100644 tcl/tcl8.6/msgs/ca.msg create mode 100644 tcl/tcl8.6/msgs/cs.msg create mode 100644 tcl/tcl8.6/msgs/da.msg create mode 100644 tcl/tcl8.6/msgs/de.msg create mode 100644 tcl/tcl8.6/msgs/de_at.msg create mode 100644 tcl/tcl8.6/msgs/de_be.msg create mode 100644 tcl/tcl8.6/msgs/el.msg create mode 100644 tcl/tcl8.6/msgs/en_au.msg create mode 100644 tcl/tcl8.6/msgs/en_be.msg create mode 100644 tcl/tcl8.6/msgs/en_bw.msg create mode 100644 tcl/tcl8.6/msgs/en_ca.msg create mode 100644 tcl/tcl8.6/msgs/en_gb.msg create mode 100644 tcl/tcl8.6/msgs/en_hk.msg create mode 100644 tcl/tcl8.6/msgs/en_ie.msg create mode 100644 tcl/tcl8.6/msgs/en_in.msg create mode 100644 tcl/tcl8.6/msgs/en_nz.msg create mode 100644 tcl/tcl8.6/msgs/en_ph.msg create mode 100644 tcl/tcl8.6/msgs/en_sg.msg create mode 100644 tcl/tcl8.6/msgs/en_za.msg create mode 100644 tcl/tcl8.6/msgs/en_zw.msg create mode 100644 tcl/tcl8.6/msgs/eo.msg create mode 100644 tcl/tcl8.6/msgs/es.msg create mode 100644 tcl/tcl8.6/msgs/es_ar.msg create mode 100644 tcl/tcl8.6/msgs/es_bo.msg create mode 100644 tcl/tcl8.6/msgs/es_cl.msg create mode 100644 tcl/tcl8.6/msgs/es_co.msg create mode 100644 tcl/tcl8.6/msgs/es_cr.msg create mode 100644 tcl/tcl8.6/msgs/es_do.msg create mode 100644 tcl/tcl8.6/msgs/es_ec.msg create mode 100644 tcl/tcl8.6/msgs/es_gt.msg create mode 100644 tcl/tcl8.6/msgs/es_hn.msg create mode 100644 tcl/tcl8.6/msgs/es_mx.msg create mode 100644 tcl/tcl8.6/msgs/es_ni.msg create mode 100644 tcl/tcl8.6/msgs/es_pa.msg create mode 100644 tcl/tcl8.6/msgs/es_pe.msg create mode 100644 tcl/tcl8.6/msgs/es_pr.msg create mode 100644 tcl/tcl8.6/msgs/es_py.msg create mode 100644 tcl/tcl8.6/msgs/es_sv.msg create mode 100644 tcl/tcl8.6/msgs/es_uy.msg create mode 100644 tcl/tcl8.6/msgs/es_ve.msg create mode 100644 tcl/tcl8.6/msgs/et.msg create mode 100644 tcl/tcl8.6/msgs/eu.msg create mode 100644 tcl/tcl8.6/msgs/eu_es.msg create mode 100644 tcl/tcl8.6/msgs/fa.msg create mode 100644 tcl/tcl8.6/msgs/fa_in.msg create mode 100644 tcl/tcl8.6/msgs/fa_ir.msg create mode 100644 tcl/tcl8.6/msgs/fi.msg create mode 100644 tcl/tcl8.6/msgs/fo.msg create mode 100644 tcl/tcl8.6/msgs/fo_fo.msg create mode 100644 tcl/tcl8.6/msgs/fr.msg create mode 100644 tcl/tcl8.6/msgs/fr_be.msg create mode 100644 tcl/tcl8.6/msgs/fr_ca.msg create mode 100644 tcl/tcl8.6/msgs/fr_ch.msg create mode 100644 tcl/tcl8.6/msgs/ga.msg create mode 100644 tcl/tcl8.6/msgs/ga_ie.msg create mode 100644 tcl/tcl8.6/msgs/gl.msg create mode 100644 tcl/tcl8.6/msgs/gl_es.msg create mode 100644 tcl/tcl8.6/msgs/gv.msg create mode 100644 tcl/tcl8.6/msgs/gv_gb.msg create mode 100644 tcl/tcl8.6/msgs/he.msg create mode 100644 tcl/tcl8.6/msgs/hi.msg create mode 100644 tcl/tcl8.6/msgs/hi_in.msg create mode 100644 tcl/tcl8.6/msgs/hr.msg create mode 100644 tcl/tcl8.6/msgs/hu.msg create mode 100644 tcl/tcl8.6/msgs/id.msg create mode 100644 tcl/tcl8.6/msgs/id_id.msg create mode 100644 tcl/tcl8.6/msgs/is.msg create mode 100644 tcl/tcl8.6/msgs/it.msg create mode 100644 tcl/tcl8.6/msgs/it_ch.msg create mode 100644 tcl/tcl8.6/msgs/ja.msg create mode 100644 tcl/tcl8.6/msgs/kl.msg create mode 100644 tcl/tcl8.6/msgs/kl_gl.msg create mode 100644 tcl/tcl8.6/msgs/ko.msg create mode 100644 tcl/tcl8.6/msgs/ko_kr.msg create mode 100644 tcl/tcl8.6/msgs/kok.msg create mode 100644 tcl/tcl8.6/msgs/kok_in.msg create mode 100644 tcl/tcl8.6/msgs/kw.msg create mode 100644 tcl/tcl8.6/msgs/kw_gb.msg create mode 100644 tcl/tcl8.6/msgs/lt.msg create mode 100644 tcl/tcl8.6/msgs/lv.msg create mode 100644 tcl/tcl8.6/msgs/mk.msg create mode 100644 tcl/tcl8.6/msgs/mr.msg create mode 100644 tcl/tcl8.6/msgs/mr_in.msg create mode 100644 tcl/tcl8.6/msgs/ms.msg create mode 100644 tcl/tcl8.6/msgs/ms_my.msg create mode 100644 tcl/tcl8.6/msgs/mt.msg create mode 100644 tcl/tcl8.6/msgs/nb.msg create mode 100644 tcl/tcl8.6/msgs/nl.msg create mode 100644 tcl/tcl8.6/msgs/nl_be.msg create mode 100644 tcl/tcl8.6/msgs/nn.msg create mode 100644 tcl/tcl8.6/msgs/pl.msg create mode 100644 tcl/tcl8.6/msgs/pt.msg create mode 100644 tcl/tcl8.6/msgs/pt_br.msg create mode 100644 tcl/tcl8.6/msgs/ro.msg create mode 100644 tcl/tcl8.6/msgs/ru.msg create mode 100644 tcl/tcl8.6/msgs/ru_ua.msg create mode 100644 tcl/tcl8.6/msgs/sh.msg create mode 100644 tcl/tcl8.6/msgs/sk.msg create mode 100644 tcl/tcl8.6/msgs/sl.msg create mode 100644 tcl/tcl8.6/msgs/sq.msg create mode 100644 tcl/tcl8.6/msgs/sr.msg create mode 100644 tcl/tcl8.6/msgs/sv.msg create mode 100644 tcl/tcl8.6/msgs/sw.msg create mode 100644 tcl/tcl8.6/msgs/ta.msg create mode 100644 tcl/tcl8.6/msgs/ta_in.msg create mode 100644 tcl/tcl8.6/msgs/te.msg create mode 100644 tcl/tcl8.6/msgs/te_in.msg create mode 100644 tcl/tcl8.6/msgs/th.msg create mode 100644 tcl/tcl8.6/msgs/tr.msg create mode 100644 tcl/tcl8.6/msgs/uk.msg create mode 100644 tcl/tcl8.6/msgs/vi.msg create mode 100644 tcl/tcl8.6/msgs/zh.msg create mode 100644 tcl/tcl8.6/msgs/zh_cn.msg create mode 100644 tcl/tcl8.6/msgs/zh_hk.msg create mode 100644 tcl/tcl8.6/msgs/zh_sg.msg create mode 100644 tcl/tcl8.6/msgs/zh_tw.msg create mode 100644 tcl/tcl8.6/opt0.4/optparse.tcl create mode 100644 tcl/tcl8.6/opt0.4/pkgIndex.tcl create mode 100644 tcl/tcl8.6/package.tcl create mode 100644 tcl/tcl8.6/parray.tcl create mode 100644 tcl/tcl8.6/safe.tcl create mode 100644 tcl/tcl8.6/tclIndex create mode 100644 tcl/tcl8.6/tm.tcl create mode 100644 tcl/tcl8.6/tzdata/Africa/Abidjan create mode 100644 tcl/tcl8.6/tzdata/Africa/Accra create mode 100644 tcl/tcl8.6/tzdata/Africa/Addis_Ababa create mode 100644 tcl/tcl8.6/tzdata/Africa/Algiers create mode 100644 tcl/tcl8.6/tzdata/Africa/Asmara create mode 100644 tcl/tcl8.6/tzdata/Africa/Asmera create mode 100644 tcl/tcl8.6/tzdata/Africa/Bamako create mode 100644 tcl/tcl8.6/tzdata/Africa/Bangui create mode 100644 tcl/tcl8.6/tzdata/Africa/Banjul create mode 100644 tcl/tcl8.6/tzdata/Africa/Bissau create mode 100644 tcl/tcl8.6/tzdata/Africa/Blantyre create mode 100644 tcl/tcl8.6/tzdata/Africa/Brazzaville create mode 100644 tcl/tcl8.6/tzdata/Africa/Bujumbura create mode 100644 tcl/tcl8.6/tzdata/Africa/Cairo create mode 100644 tcl/tcl8.6/tzdata/Africa/Casablanca create mode 100644 tcl/tcl8.6/tzdata/Africa/Ceuta create mode 100644 tcl/tcl8.6/tzdata/Africa/Conakry create mode 100644 tcl/tcl8.6/tzdata/Africa/Dakar create mode 100644 tcl/tcl8.6/tzdata/Africa/Dar_es_Salaam create mode 100644 tcl/tcl8.6/tzdata/Africa/Djibouti create mode 100644 tcl/tcl8.6/tzdata/Africa/Douala create mode 100644 tcl/tcl8.6/tzdata/Africa/El_Aaiun create mode 100644 tcl/tcl8.6/tzdata/Africa/Freetown create mode 100644 tcl/tcl8.6/tzdata/Africa/Gaborone create mode 100644 tcl/tcl8.6/tzdata/Africa/Harare create mode 100644 tcl/tcl8.6/tzdata/Africa/Johannesburg create mode 100644 tcl/tcl8.6/tzdata/Africa/Juba create mode 100644 tcl/tcl8.6/tzdata/Africa/Kampala create mode 100644 tcl/tcl8.6/tzdata/Africa/Khartoum create mode 100644 tcl/tcl8.6/tzdata/Africa/Kigali create mode 100644 tcl/tcl8.6/tzdata/Africa/Kinshasa create mode 100644 tcl/tcl8.6/tzdata/Africa/Lagos create mode 100644 tcl/tcl8.6/tzdata/Africa/Libreville create mode 100644 tcl/tcl8.6/tzdata/Africa/Lome create mode 100644 tcl/tcl8.6/tzdata/Africa/Luanda create mode 100644 tcl/tcl8.6/tzdata/Africa/Lubumbashi create mode 100644 tcl/tcl8.6/tzdata/Africa/Lusaka create mode 100644 tcl/tcl8.6/tzdata/Africa/Malabo create mode 100644 tcl/tcl8.6/tzdata/Africa/Maputo create mode 100644 tcl/tcl8.6/tzdata/Africa/Maseru create mode 100644 tcl/tcl8.6/tzdata/Africa/Mbabane create mode 100644 tcl/tcl8.6/tzdata/Africa/Mogadishu create mode 100644 tcl/tcl8.6/tzdata/Africa/Monrovia create mode 100644 tcl/tcl8.6/tzdata/Africa/Nairobi create mode 100644 tcl/tcl8.6/tzdata/Africa/Ndjamena create mode 100644 tcl/tcl8.6/tzdata/Africa/Niamey create mode 100644 tcl/tcl8.6/tzdata/Africa/Nouakchott create mode 100644 tcl/tcl8.6/tzdata/Africa/Ouagadougou create mode 100644 tcl/tcl8.6/tzdata/Africa/Porto-Novo create mode 100644 tcl/tcl8.6/tzdata/Africa/Sao_Tome create mode 100644 tcl/tcl8.6/tzdata/Africa/Timbuktu create mode 100644 tcl/tcl8.6/tzdata/Africa/Tripoli create mode 100644 tcl/tcl8.6/tzdata/Africa/Tunis create mode 100644 tcl/tcl8.6/tzdata/Africa/Windhoek create mode 100644 tcl/tcl8.6/tzdata/America/Adak create mode 100644 tcl/tcl8.6/tzdata/America/Anchorage create mode 100644 tcl/tcl8.6/tzdata/America/Anguilla create mode 100644 tcl/tcl8.6/tzdata/America/Antigua create mode 100644 tcl/tcl8.6/tzdata/America/Araguaina create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Buenos_Aires create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Catamarca create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/ComodRivadavia create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Cordoba create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Jujuy create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/La_Rioja create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Mendoza create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Rio_Gallegos create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Salta create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/San_Juan create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/San_Luis create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Tucuman create mode 100644 tcl/tcl8.6/tzdata/America/Argentina/Ushuaia create mode 100644 tcl/tcl8.6/tzdata/America/Aruba create mode 100644 tcl/tcl8.6/tzdata/America/Asuncion create mode 100644 tcl/tcl8.6/tzdata/America/Atikokan create mode 100644 tcl/tcl8.6/tzdata/America/Atka create mode 100644 tcl/tcl8.6/tzdata/America/Bahia create mode 100644 tcl/tcl8.6/tzdata/America/Bahia_Banderas create mode 100644 tcl/tcl8.6/tzdata/America/Barbados create mode 100644 tcl/tcl8.6/tzdata/America/Belem create mode 100644 tcl/tcl8.6/tzdata/America/Belize create mode 100644 tcl/tcl8.6/tzdata/America/Blanc-Sablon create mode 100644 tcl/tcl8.6/tzdata/America/Boa_Vista create mode 100644 tcl/tcl8.6/tzdata/America/Bogota create mode 100644 tcl/tcl8.6/tzdata/America/Boise create mode 100644 tcl/tcl8.6/tzdata/America/Buenos_Aires create mode 100644 tcl/tcl8.6/tzdata/America/Cambridge_Bay create mode 100644 tcl/tcl8.6/tzdata/America/Campo_Grande create mode 100644 tcl/tcl8.6/tzdata/America/Cancun create mode 100644 tcl/tcl8.6/tzdata/America/Caracas create mode 100644 tcl/tcl8.6/tzdata/America/Catamarca create mode 100644 tcl/tcl8.6/tzdata/America/Cayenne create mode 100644 tcl/tcl8.6/tzdata/America/Cayman create mode 100644 tcl/tcl8.6/tzdata/America/Chicago create mode 100644 tcl/tcl8.6/tzdata/America/Chihuahua create mode 100644 tcl/tcl8.6/tzdata/America/Coral_Harbour create mode 100644 tcl/tcl8.6/tzdata/America/Cordoba create mode 100644 tcl/tcl8.6/tzdata/America/Costa_Rica create mode 100644 tcl/tcl8.6/tzdata/America/Creston create mode 100644 tcl/tcl8.6/tzdata/America/Cuiaba create mode 100644 tcl/tcl8.6/tzdata/America/Curacao create mode 100644 tcl/tcl8.6/tzdata/America/Danmarkshavn create mode 100644 tcl/tcl8.6/tzdata/America/Dawson create mode 100644 tcl/tcl8.6/tzdata/America/Dawson_Creek create mode 100644 tcl/tcl8.6/tzdata/America/Denver create mode 100644 tcl/tcl8.6/tzdata/America/Detroit create mode 100644 tcl/tcl8.6/tzdata/America/Dominica create mode 100644 tcl/tcl8.6/tzdata/America/Edmonton create mode 100644 tcl/tcl8.6/tzdata/America/Eirunepe create mode 100644 tcl/tcl8.6/tzdata/America/El_Salvador create mode 100644 tcl/tcl8.6/tzdata/America/Ensenada create mode 100644 tcl/tcl8.6/tzdata/America/Fort_Nelson create mode 100644 tcl/tcl8.6/tzdata/America/Fort_Wayne create mode 100644 tcl/tcl8.6/tzdata/America/Fortaleza create mode 100644 tcl/tcl8.6/tzdata/America/Glace_Bay create mode 100644 tcl/tcl8.6/tzdata/America/Godthab create mode 100644 tcl/tcl8.6/tzdata/America/Goose_Bay create mode 100644 tcl/tcl8.6/tzdata/America/Grand_Turk create mode 100644 tcl/tcl8.6/tzdata/America/Grenada create mode 100644 tcl/tcl8.6/tzdata/America/Guadeloupe create mode 100644 tcl/tcl8.6/tzdata/America/Guatemala create mode 100644 tcl/tcl8.6/tzdata/America/Guayaquil create mode 100644 tcl/tcl8.6/tzdata/America/Guyana create mode 100644 tcl/tcl8.6/tzdata/America/Halifax create mode 100644 tcl/tcl8.6/tzdata/America/Havana create mode 100644 tcl/tcl8.6/tzdata/America/Hermosillo create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Indianapolis create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Knox create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Marengo create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Petersburg create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Tell_City create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Vevay create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Vincennes create mode 100644 tcl/tcl8.6/tzdata/America/Indiana/Winamac create mode 100644 tcl/tcl8.6/tzdata/America/Indianapolis create mode 100644 tcl/tcl8.6/tzdata/America/Inuvik create mode 100644 tcl/tcl8.6/tzdata/America/Iqaluit create mode 100644 tcl/tcl8.6/tzdata/America/Jamaica create mode 100644 tcl/tcl8.6/tzdata/America/Jujuy create mode 100644 tcl/tcl8.6/tzdata/America/Juneau create mode 100644 tcl/tcl8.6/tzdata/America/Kentucky/Louisville create mode 100644 tcl/tcl8.6/tzdata/America/Kentucky/Monticello create mode 100644 tcl/tcl8.6/tzdata/America/Knox_IN create mode 100644 tcl/tcl8.6/tzdata/America/Kralendijk create mode 100644 tcl/tcl8.6/tzdata/America/La_Paz create mode 100644 tcl/tcl8.6/tzdata/America/Lima create mode 100644 tcl/tcl8.6/tzdata/America/Los_Angeles create mode 100644 tcl/tcl8.6/tzdata/America/Louisville create mode 100644 tcl/tcl8.6/tzdata/America/Lower_Princes create mode 100644 tcl/tcl8.6/tzdata/America/Maceio create mode 100644 tcl/tcl8.6/tzdata/America/Managua create mode 100644 tcl/tcl8.6/tzdata/America/Manaus create mode 100644 tcl/tcl8.6/tzdata/America/Marigot create mode 100644 tcl/tcl8.6/tzdata/America/Martinique create mode 100644 tcl/tcl8.6/tzdata/America/Matamoros create mode 100644 tcl/tcl8.6/tzdata/America/Mazatlan create mode 100644 tcl/tcl8.6/tzdata/America/Mendoza create mode 100644 tcl/tcl8.6/tzdata/America/Menominee create mode 100644 tcl/tcl8.6/tzdata/America/Merida create mode 100644 tcl/tcl8.6/tzdata/America/Metlakatla create mode 100644 tcl/tcl8.6/tzdata/America/Mexico_City create mode 100644 tcl/tcl8.6/tzdata/America/Miquelon create mode 100644 tcl/tcl8.6/tzdata/America/Moncton create mode 100644 tcl/tcl8.6/tzdata/America/Monterrey create mode 100644 tcl/tcl8.6/tzdata/America/Montevideo create mode 100644 tcl/tcl8.6/tzdata/America/Montreal create mode 100644 tcl/tcl8.6/tzdata/America/Montserrat create mode 100644 tcl/tcl8.6/tzdata/America/Nassau create mode 100644 tcl/tcl8.6/tzdata/America/New_York create mode 100644 tcl/tcl8.6/tzdata/America/Nipigon create mode 100644 tcl/tcl8.6/tzdata/America/Nome create mode 100644 tcl/tcl8.6/tzdata/America/Noronha create mode 100644 tcl/tcl8.6/tzdata/America/North_Dakota/Beulah create mode 100644 tcl/tcl8.6/tzdata/America/North_Dakota/Center create mode 100644 tcl/tcl8.6/tzdata/America/North_Dakota/New_Salem create mode 100644 tcl/tcl8.6/tzdata/America/Ojinaga create mode 100644 tcl/tcl8.6/tzdata/America/Panama create mode 100644 tcl/tcl8.6/tzdata/America/Pangnirtung create mode 100644 tcl/tcl8.6/tzdata/America/Paramaribo create mode 100644 tcl/tcl8.6/tzdata/America/Phoenix create mode 100644 tcl/tcl8.6/tzdata/America/Port-au-Prince create mode 100644 tcl/tcl8.6/tzdata/America/Port_of_Spain create mode 100644 tcl/tcl8.6/tzdata/America/Porto_Acre create mode 100644 tcl/tcl8.6/tzdata/America/Porto_Velho create mode 100644 tcl/tcl8.6/tzdata/America/Puerto_Rico create mode 100644 tcl/tcl8.6/tzdata/America/Punta_Arenas create mode 100644 tcl/tcl8.6/tzdata/America/Rainy_River create mode 100644 tcl/tcl8.6/tzdata/America/Rankin_Inlet create mode 100644 tcl/tcl8.6/tzdata/America/Recife create mode 100644 tcl/tcl8.6/tzdata/America/Regina create mode 100644 tcl/tcl8.6/tzdata/America/Resolute create mode 100644 tcl/tcl8.6/tzdata/America/Rio_Branco create mode 100644 tcl/tcl8.6/tzdata/America/Rosario create mode 100644 tcl/tcl8.6/tzdata/America/Santa_Isabel create mode 100644 tcl/tcl8.6/tzdata/America/Santarem create mode 100644 tcl/tcl8.6/tzdata/America/Santiago create mode 100644 tcl/tcl8.6/tzdata/America/Santo_Domingo create mode 100644 tcl/tcl8.6/tzdata/America/Sao_Paulo create mode 100644 tcl/tcl8.6/tzdata/America/Scoresbysund create mode 100644 tcl/tcl8.6/tzdata/America/Shiprock create mode 100644 tcl/tcl8.6/tzdata/America/Sitka create mode 100644 tcl/tcl8.6/tzdata/America/St_Barthelemy create mode 100644 tcl/tcl8.6/tzdata/America/St_Johns create mode 100644 tcl/tcl8.6/tzdata/America/St_Kitts create mode 100644 tcl/tcl8.6/tzdata/America/St_Lucia create mode 100644 tcl/tcl8.6/tzdata/America/St_Thomas create mode 100644 tcl/tcl8.6/tzdata/America/St_Vincent create mode 100644 tcl/tcl8.6/tzdata/America/Swift_Current create mode 100644 tcl/tcl8.6/tzdata/America/Tegucigalpa create mode 100644 tcl/tcl8.6/tzdata/America/Thule create mode 100644 tcl/tcl8.6/tzdata/America/Thunder_Bay create mode 100644 tcl/tcl8.6/tzdata/America/Tijuana create mode 100644 tcl/tcl8.6/tzdata/America/Toronto create mode 100644 tcl/tcl8.6/tzdata/America/Tortola create mode 100644 tcl/tcl8.6/tzdata/America/Vancouver create mode 100644 tcl/tcl8.6/tzdata/America/Virgin create mode 100644 tcl/tcl8.6/tzdata/America/Whitehorse create mode 100644 tcl/tcl8.6/tzdata/America/Winnipeg create mode 100644 tcl/tcl8.6/tzdata/America/Yakutat create mode 100644 tcl/tcl8.6/tzdata/America/Yellowknife create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Casey create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Davis create mode 100644 tcl/tcl8.6/tzdata/Antarctica/DumontDUrville create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Macquarie create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Mawson create mode 100644 tcl/tcl8.6/tzdata/Antarctica/McMurdo create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Palmer create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Rothera create mode 100644 tcl/tcl8.6/tzdata/Antarctica/South_Pole create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Syowa create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Troll create mode 100644 tcl/tcl8.6/tzdata/Antarctica/Vostok create mode 100644 tcl/tcl8.6/tzdata/Arctic/Longyearbyen create mode 100644 tcl/tcl8.6/tzdata/Asia/Aden create mode 100644 tcl/tcl8.6/tzdata/Asia/Almaty create mode 100644 tcl/tcl8.6/tzdata/Asia/Amman create mode 100644 tcl/tcl8.6/tzdata/Asia/Anadyr create mode 100644 tcl/tcl8.6/tzdata/Asia/Aqtau create mode 100644 tcl/tcl8.6/tzdata/Asia/Aqtobe create mode 100644 tcl/tcl8.6/tzdata/Asia/Ashgabat create mode 100644 tcl/tcl8.6/tzdata/Asia/Ashkhabad create mode 100644 tcl/tcl8.6/tzdata/Asia/Atyrau create mode 100644 tcl/tcl8.6/tzdata/Asia/Baghdad create mode 100644 tcl/tcl8.6/tzdata/Asia/Bahrain create mode 100644 tcl/tcl8.6/tzdata/Asia/Baku create mode 100644 tcl/tcl8.6/tzdata/Asia/Bangkok create mode 100644 tcl/tcl8.6/tzdata/Asia/Barnaul create mode 100644 tcl/tcl8.6/tzdata/Asia/Beirut create mode 100644 tcl/tcl8.6/tzdata/Asia/Bishkek create mode 100644 tcl/tcl8.6/tzdata/Asia/Brunei create mode 100644 tcl/tcl8.6/tzdata/Asia/Calcutta create mode 100644 tcl/tcl8.6/tzdata/Asia/Chita create mode 100644 tcl/tcl8.6/tzdata/Asia/Choibalsan create mode 100644 tcl/tcl8.6/tzdata/Asia/Chongqing create mode 100644 tcl/tcl8.6/tzdata/Asia/Chungking create mode 100644 tcl/tcl8.6/tzdata/Asia/Colombo create mode 100644 tcl/tcl8.6/tzdata/Asia/Dacca create mode 100644 tcl/tcl8.6/tzdata/Asia/Damascus create mode 100644 tcl/tcl8.6/tzdata/Asia/Dhaka create mode 100644 tcl/tcl8.6/tzdata/Asia/Dili create mode 100644 tcl/tcl8.6/tzdata/Asia/Dubai create mode 100644 tcl/tcl8.6/tzdata/Asia/Dushanbe create mode 100644 tcl/tcl8.6/tzdata/Asia/Famagusta create mode 100644 tcl/tcl8.6/tzdata/Asia/Gaza create mode 100644 tcl/tcl8.6/tzdata/Asia/Harbin create mode 100644 tcl/tcl8.6/tzdata/Asia/Hebron create mode 100644 tcl/tcl8.6/tzdata/Asia/Ho_Chi_Minh create mode 100644 tcl/tcl8.6/tzdata/Asia/Hong_Kong create mode 100644 tcl/tcl8.6/tzdata/Asia/Hovd create mode 100644 tcl/tcl8.6/tzdata/Asia/Irkutsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Istanbul create mode 100644 tcl/tcl8.6/tzdata/Asia/Jakarta create mode 100644 tcl/tcl8.6/tzdata/Asia/Jayapura create mode 100644 tcl/tcl8.6/tzdata/Asia/Jerusalem create mode 100644 tcl/tcl8.6/tzdata/Asia/Kabul create mode 100644 tcl/tcl8.6/tzdata/Asia/Kamchatka create mode 100644 tcl/tcl8.6/tzdata/Asia/Karachi create mode 100644 tcl/tcl8.6/tzdata/Asia/Kashgar create mode 100644 tcl/tcl8.6/tzdata/Asia/Kathmandu create mode 100644 tcl/tcl8.6/tzdata/Asia/Katmandu create mode 100644 tcl/tcl8.6/tzdata/Asia/Khandyga create mode 100644 tcl/tcl8.6/tzdata/Asia/Kolkata create mode 100644 tcl/tcl8.6/tzdata/Asia/Krasnoyarsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Kuala_Lumpur create mode 100644 tcl/tcl8.6/tzdata/Asia/Kuching create mode 100644 tcl/tcl8.6/tzdata/Asia/Kuwait create mode 100644 tcl/tcl8.6/tzdata/Asia/Macao create mode 100644 tcl/tcl8.6/tzdata/Asia/Macau create mode 100644 tcl/tcl8.6/tzdata/Asia/Magadan create mode 100644 tcl/tcl8.6/tzdata/Asia/Makassar create mode 100644 tcl/tcl8.6/tzdata/Asia/Manila create mode 100644 tcl/tcl8.6/tzdata/Asia/Muscat create mode 100644 tcl/tcl8.6/tzdata/Asia/Nicosia create mode 100644 tcl/tcl8.6/tzdata/Asia/Novokuznetsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Novosibirsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Omsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Oral create mode 100644 tcl/tcl8.6/tzdata/Asia/Phnom_Penh create mode 100644 tcl/tcl8.6/tzdata/Asia/Pontianak create mode 100644 tcl/tcl8.6/tzdata/Asia/Pyongyang create mode 100644 tcl/tcl8.6/tzdata/Asia/Qatar create mode 100644 tcl/tcl8.6/tzdata/Asia/Qyzylorda create mode 100644 tcl/tcl8.6/tzdata/Asia/Rangoon create mode 100644 tcl/tcl8.6/tzdata/Asia/Riyadh create mode 100644 tcl/tcl8.6/tzdata/Asia/Saigon create mode 100644 tcl/tcl8.6/tzdata/Asia/Sakhalin create mode 100644 tcl/tcl8.6/tzdata/Asia/Samarkand create mode 100644 tcl/tcl8.6/tzdata/Asia/Seoul create mode 100644 tcl/tcl8.6/tzdata/Asia/Shanghai create mode 100644 tcl/tcl8.6/tzdata/Asia/Singapore create mode 100644 tcl/tcl8.6/tzdata/Asia/Srednekolymsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Taipei create mode 100644 tcl/tcl8.6/tzdata/Asia/Tashkent create mode 100644 tcl/tcl8.6/tzdata/Asia/Tbilisi create mode 100644 tcl/tcl8.6/tzdata/Asia/Tehran create mode 100644 tcl/tcl8.6/tzdata/Asia/Tel_Aviv create mode 100644 tcl/tcl8.6/tzdata/Asia/Thimbu create mode 100644 tcl/tcl8.6/tzdata/Asia/Thimphu create mode 100644 tcl/tcl8.6/tzdata/Asia/Tokyo create mode 100644 tcl/tcl8.6/tzdata/Asia/Tomsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Ujung_Pandang create mode 100644 tcl/tcl8.6/tzdata/Asia/Ulaanbaatar create mode 100644 tcl/tcl8.6/tzdata/Asia/Ulan_Bator create mode 100644 tcl/tcl8.6/tzdata/Asia/Urumqi create mode 100644 tcl/tcl8.6/tzdata/Asia/Ust-Nera create mode 100644 tcl/tcl8.6/tzdata/Asia/Vientiane create mode 100644 tcl/tcl8.6/tzdata/Asia/Vladivostok create mode 100644 tcl/tcl8.6/tzdata/Asia/Yakutsk create mode 100644 tcl/tcl8.6/tzdata/Asia/Yangon create mode 100644 tcl/tcl8.6/tzdata/Asia/Yekaterinburg create mode 100644 tcl/tcl8.6/tzdata/Asia/Yerevan create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Azores create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Bermuda create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Canary create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Cape_Verde create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Faeroe create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Faroe create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Jan_Mayen create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Madeira create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Reykjavik create mode 100644 tcl/tcl8.6/tzdata/Atlantic/South_Georgia create mode 100644 tcl/tcl8.6/tzdata/Atlantic/St_Helena create mode 100644 tcl/tcl8.6/tzdata/Atlantic/Stanley create mode 100644 tcl/tcl8.6/tzdata/Australia/ACT create mode 100644 tcl/tcl8.6/tzdata/Australia/Adelaide create mode 100644 tcl/tcl8.6/tzdata/Australia/Brisbane create mode 100644 tcl/tcl8.6/tzdata/Australia/Broken_Hill create mode 100644 tcl/tcl8.6/tzdata/Australia/Canberra create mode 100644 tcl/tcl8.6/tzdata/Australia/Currie create mode 100644 tcl/tcl8.6/tzdata/Australia/Darwin create mode 100644 tcl/tcl8.6/tzdata/Australia/Eucla create mode 100644 tcl/tcl8.6/tzdata/Australia/Hobart create mode 100644 tcl/tcl8.6/tzdata/Australia/LHI create mode 100644 tcl/tcl8.6/tzdata/Australia/Lindeman create mode 100644 tcl/tcl8.6/tzdata/Australia/Lord_Howe create mode 100644 tcl/tcl8.6/tzdata/Australia/Melbourne create mode 100644 tcl/tcl8.6/tzdata/Australia/NSW create mode 100644 tcl/tcl8.6/tzdata/Australia/North create mode 100644 tcl/tcl8.6/tzdata/Australia/Perth create mode 100644 tcl/tcl8.6/tzdata/Australia/Queensland create mode 100644 tcl/tcl8.6/tzdata/Australia/South create mode 100644 tcl/tcl8.6/tzdata/Australia/Sydney create mode 100644 tcl/tcl8.6/tzdata/Australia/Tasmania create mode 100644 tcl/tcl8.6/tzdata/Australia/Victoria create mode 100644 tcl/tcl8.6/tzdata/Australia/West create mode 100644 tcl/tcl8.6/tzdata/Australia/Yancowinna create mode 100644 tcl/tcl8.6/tzdata/Brazil/Acre create mode 100644 tcl/tcl8.6/tzdata/Brazil/DeNoronha create mode 100644 tcl/tcl8.6/tzdata/Brazil/East create mode 100644 tcl/tcl8.6/tzdata/Brazil/West create mode 100644 tcl/tcl8.6/tzdata/CET create mode 100644 tcl/tcl8.6/tzdata/CST6CDT create mode 100644 tcl/tcl8.6/tzdata/Canada/Atlantic create mode 100644 tcl/tcl8.6/tzdata/Canada/Central create mode 100644 tcl/tcl8.6/tzdata/Canada/East-Saskatchewan create mode 100644 tcl/tcl8.6/tzdata/Canada/Eastern create mode 100644 tcl/tcl8.6/tzdata/Canada/Mountain create mode 100644 tcl/tcl8.6/tzdata/Canada/Newfoundland create mode 100644 tcl/tcl8.6/tzdata/Canada/Pacific create mode 100644 tcl/tcl8.6/tzdata/Canada/Saskatchewan create mode 100644 tcl/tcl8.6/tzdata/Canada/Yukon create mode 100644 tcl/tcl8.6/tzdata/Chile/Continental create mode 100644 tcl/tcl8.6/tzdata/Chile/EasterIsland create mode 100644 tcl/tcl8.6/tzdata/Cuba create mode 100644 tcl/tcl8.6/tzdata/EET create mode 100644 tcl/tcl8.6/tzdata/EST create mode 100644 tcl/tcl8.6/tzdata/EST5EDT create mode 100644 tcl/tcl8.6/tzdata/Egypt create mode 100644 tcl/tcl8.6/tzdata/Eire create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+0 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+1 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+10 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+11 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+12 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+2 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+3 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+4 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+5 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+6 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+7 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+8 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT+9 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-0 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-1 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-10 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-11 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-12 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-13 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-14 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-2 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-3 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-4 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-5 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-6 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-7 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-8 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT-9 create mode 100644 tcl/tcl8.6/tzdata/Etc/GMT0 create mode 100644 tcl/tcl8.6/tzdata/Etc/Greenwich create mode 100644 tcl/tcl8.6/tzdata/Etc/UCT create mode 100644 tcl/tcl8.6/tzdata/Etc/UTC create mode 100644 tcl/tcl8.6/tzdata/Etc/Universal create mode 100644 tcl/tcl8.6/tzdata/Etc/Zulu create mode 100644 tcl/tcl8.6/tzdata/Europe/Amsterdam create mode 100644 tcl/tcl8.6/tzdata/Europe/Andorra create mode 100644 tcl/tcl8.6/tzdata/Europe/Astrakhan create mode 100644 tcl/tcl8.6/tzdata/Europe/Athens create mode 100644 tcl/tcl8.6/tzdata/Europe/Belfast create mode 100644 tcl/tcl8.6/tzdata/Europe/Belgrade create mode 100644 tcl/tcl8.6/tzdata/Europe/Berlin create mode 100644 tcl/tcl8.6/tzdata/Europe/Bratislava create mode 100644 tcl/tcl8.6/tzdata/Europe/Brussels create mode 100644 tcl/tcl8.6/tzdata/Europe/Bucharest create mode 100644 tcl/tcl8.6/tzdata/Europe/Budapest create mode 100644 tcl/tcl8.6/tzdata/Europe/Busingen create mode 100644 tcl/tcl8.6/tzdata/Europe/Chisinau create mode 100644 tcl/tcl8.6/tzdata/Europe/Copenhagen create mode 100644 tcl/tcl8.6/tzdata/Europe/Dublin create mode 100644 tcl/tcl8.6/tzdata/Europe/Gibraltar create mode 100644 tcl/tcl8.6/tzdata/Europe/Guernsey create mode 100644 tcl/tcl8.6/tzdata/Europe/Helsinki create mode 100644 tcl/tcl8.6/tzdata/Europe/Isle_of_Man create mode 100644 tcl/tcl8.6/tzdata/Europe/Istanbul create mode 100644 tcl/tcl8.6/tzdata/Europe/Jersey create mode 100644 tcl/tcl8.6/tzdata/Europe/Kaliningrad create mode 100644 tcl/tcl8.6/tzdata/Europe/Kiev create mode 100644 tcl/tcl8.6/tzdata/Europe/Kirov create mode 100644 tcl/tcl8.6/tzdata/Europe/Lisbon create mode 100644 tcl/tcl8.6/tzdata/Europe/Ljubljana create mode 100644 tcl/tcl8.6/tzdata/Europe/London create mode 100644 tcl/tcl8.6/tzdata/Europe/Luxembourg create mode 100644 tcl/tcl8.6/tzdata/Europe/Madrid create mode 100644 tcl/tcl8.6/tzdata/Europe/Malta create mode 100644 tcl/tcl8.6/tzdata/Europe/Mariehamn create mode 100644 tcl/tcl8.6/tzdata/Europe/Minsk create mode 100644 tcl/tcl8.6/tzdata/Europe/Monaco create mode 100644 tcl/tcl8.6/tzdata/Europe/Moscow create mode 100644 tcl/tcl8.6/tzdata/Europe/Nicosia create mode 100644 tcl/tcl8.6/tzdata/Europe/Oslo create mode 100644 tcl/tcl8.6/tzdata/Europe/Paris create mode 100644 tcl/tcl8.6/tzdata/Europe/Podgorica create mode 100644 tcl/tcl8.6/tzdata/Europe/Prague create mode 100644 tcl/tcl8.6/tzdata/Europe/Riga create mode 100644 tcl/tcl8.6/tzdata/Europe/Rome create mode 100644 tcl/tcl8.6/tzdata/Europe/Samara create mode 100644 tcl/tcl8.6/tzdata/Europe/San_Marino create mode 100644 tcl/tcl8.6/tzdata/Europe/Sarajevo create mode 100644 tcl/tcl8.6/tzdata/Europe/Saratov create mode 100644 tcl/tcl8.6/tzdata/Europe/Simferopol create mode 100644 tcl/tcl8.6/tzdata/Europe/Skopje create mode 100644 tcl/tcl8.6/tzdata/Europe/Sofia create mode 100644 tcl/tcl8.6/tzdata/Europe/Stockholm create mode 100644 tcl/tcl8.6/tzdata/Europe/Tallinn create mode 100644 tcl/tcl8.6/tzdata/Europe/Tirane create mode 100644 tcl/tcl8.6/tzdata/Europe/Tiraspol create mode 100644 tcl/tcl8.6/tzdata/Europe/Ulyanovsk create mode 100644 tcl/tcl8.6/tzdata/Europe/Uzhgorod create mode 100644 tcl/tcl8.6/tzdata/Europe/Vaduz create mode 100644 tcl/tcl8.6/tzdata/Europe/Vatican create mode 100644 tcl/tcl8.6/tzdata/Europe/Vienna create mode 100644 tcl/tcl8.6/tzdata/Europe/Vilnius create mode 100644 tcl/tcl8.6/tzdata/Europe/Volgograd create mode 100644 tcl/tcl8.6/tzdata/Europe/Warsaw create mode 100644 tcl/tcl8.6/tzdata/Europe/Zagreb create mode 100644 tcl/tcl8.6/tzdata/Europe/Zaporozhye create mode 100644 tcl/tcl8.6/tzdata/Europe/Zurich create mode 100644 tcl/tcl8.6/tzdata/GB create mode 100644 tcl/tcl8.6/tzdata/GB-Eire create mode 100644 tcl/tcl8.6/tzdata/GMT create mode 100644 tcl/tcl8.6/tzdata/GMT+0 create mode 100644 tcl/tcl8.6/tzdata/GMT-0 create mode 100644 tcl/tcl8.6/tzdata/GMT0 create mode 100644 tcl/tcl8.6/tzdata/Greenwich create mode 100644 tcl/tcl8.6/tzdata/HST create mode 100644 tcl/tcl8.6/tzdata/Hongkong create mode 100644 tcl/tcl8.6/tzdata/Iceland create mode 100644 tcl/tcl8.6/tzdata/Indian/Antananarivo create mode 100644 tcl/tcl8.6/tzdata/Indian/Chagos create mode 100644 tcl/tcl8.6/tzdata/Indian/Christmas create mode 100644 tcl/tcl8.6/tzdata/Indian/Cocos create mode 100644 tcl/tcl8.6/tzdata/Indian/Comoro create mode 100644 tcl/tcl8.6/tzdata/Indian/Kerguelen create mode 100644 tcl/tcl8.6/tzdata/Indian/Mahe create mode 100644 tcl/tcl8.6/tzdata/Indian/Maldives create mode 100644 tcl/tcl8.6/tzdata/Indian/Mauritius create mode 100644 tcl/tcl8.6/tzdata/Indian/Mayotte create mode 100644 tcl/tcl8.6/tzdata/Indian/Reunion create mode 100644 tcl/tcl8.6/tzdata/Iran create mode 100644 tcl/tcl8.6/tzdata/Israel create mode 100644 tcl/tcl8.6/tzdata/Jamaica create mode 100644 tcl/tcl8.6/tzdata/Japan create mode 100644 tcl/tcl8.6/tzdata/Kwajalein create mode 100644 tcl/tcl8.6/tzdata/Libya create mode 100644 tcl/tcl8.6/tzdata/MET create mode 100644 tcl/tcl8.6/tzdata/MST create mode 100644 tcl/tcl8.6/tzdata/MST7MDT create mode 100644 tcl/tcl8.6/tzdata/Mexico/BajaNorte create mode 100644 tcl/tcl8.6/tzdata/Mexico/BajaSur create mode 100644 tcl/tcl8.6/tzdata/Mexico/General create mode 100644 tcl/tcl8.6/tzdata/NZ create mode 100644 tcl/tcl8.6/tzdata/NZ-CHAT create mode 100644 tcl/tcl8.6/tzdata/Navajo create mode 100644 tcl/tcl8.6/tzdata/PRC create mode 100644 tcl/tcl8.6/tzdata/PST8PDT create mode 100644 tcl/tcl8.6/tzdata/Pacific/Apia create mode 100644 tcl/tcl8.6/tzdata/Pacific/Auckland create mode 100644 tcl/tcl8.6/tzdata/Pacific/Bougainville create mode 100644 tcl/tcl8.6/tzdata/Pacific/Chatham create mode 100644 tcl/tcl8.6/tzdata/Pacific/Chuuk create mode 100644 tcl/tcl8.6/tzdata/Pacific/Easter create mode 100644 tcl/tcl8.6/tzdata/Pacific/Efate create mode 100644 tcl/tcl8.6/tzdata/Pacific/Enderbury create mode 100644 tcl/tcl8.6/tzdata/Pacific/Fakaofo create mode 100644 tcl/tcl8.6/tzdata/Pacific/Fiji create mode 100644 tcl/tcl8.6/tzdata/Pacific/Funafuti create mode 100644 tcl/tcl8.6/tzdata/Pacific/Galapagos create mode 100644 tcl/tcl8.6/tzdata/Pacific/Gambier create mode 100644 tcl/tcl8.6/tzdata/Pacific/Guadalcanal create mode 100644 tcl/tcl8.6/tzdata/Pacific/Guam create mode 100644 tcl/tcl8.6/tzdata/Pacific/Honolulu create mode 100644 tcl/tcl8.6/tzdata/Pacific/Johnston create mode 100644 tcl/tcl8.6/tzdata/Pacific/Kiritimati create mode 100644 tcl/tcl8.6/tzdata/Pacific/Kosrae create mode 100644 tcl/tcl8.6/tzdata/Pacific/Kwajalein create mode 100644 tcl/tcl8.6/tzdata/Pacific/Majuro create mode 100644 tcl/tcl8.6/tzdata/Pacific/Marquesas create mode 100644 tcl/tcl8.6/tzdata/Pacific/Midway create mode 100644 tcl/tcl8.6/tzdata/Pacific/Nauru create mode 100644 tcl/tcl8.6/tzdata/Pacific/Niue create mode 100644 tcl/tcl8.6/tzdata/Pacific/Norfolk create mode 100644 tcl/tcl8.6/tzdata/Pacific/Noumea create mode 100644 tcl/tcl8.6/tzdata/Pacific/Pago_Pago create mode 100644 tcl/tcl8.6/tzdata/Pacific/Palau create mode 100644 tcl/tcl8.6/tzdata/Pacific/Pitcairn create mode 100644 tcl/tcl8.6/tzdata/Pacific/Pohnpei create mode 100644 tcl/tcl8.6/tzdata/Pacific/Ponape create mode 100644 tcl/tcl8.6/tzdata/Pacific/Port_Moresby create mode 100644 tcl/tcl8.6/tzdata/Pacific/Rarotonga create mode 100644 tcl/tcl8.6/tzdata/Pacific/Saipan create mode 100644 tcl/tcl8.6/tzdata/Pacific/Samoa create mode 100644 tcl/tcl8.6/tzdata/Pacific/Tahiti create mode 100644 tcl/tcl8.6/tzdata/Pacific/Tarawa create mode 100644 tcl/tcl8.6/tzdata/Pacific/Tongatapu create mode 100644 tcl/tcl8.6/tzdata/Pacific/Truk create mode 100644 tcl/tcl8.6/tzdata/Pacific/Wake create mode 100644 tcl/tcl8.6/tzdata/Pacific/Wallis create mode 100644 tcl/tcl8.6/tzdata/Pacific/Yap create mode 100644 tcl/tcl8.6/tzdata/Poland create mode 100644 tcl/tcl8.6/tzdata/Portugal create mode 100644 tcl/tcl8.6/tzdata/ROC create mode 100644 tcl/tcl8.6/tzdata/ROK create mode 100644 tcl/tcl8.6/tzdata/Singapore create mode 100644 tcl/tcl8.6/tzdata/SystemV/AST4 create mode 100644 tcl/tcl8.6/tzdata/SystemV/AST4ADT create mode 100644 tcl/tcl8.6/tzdata/SystemV/CST6 create mode 100644 tcl/tcl8.6/tzdata/SystemV/CST6CDT create mode 100644 tcl/tcl8.6/tzdata/SystemV/EST5 create mode 100644 tcl/tcl8.6/tzdata/SystemV/EST5EDT create mode 100644 tcl/tcl8.6/tzdata/SystemV/HST10 create mode 100644 tcl/tcl8.6/tzdata/SystemV/MST7 create mode 100644 tcl/tcl8.6/tzdata/SystemV/MST7MDT create mode 100644 tcl/tcl8.6/tzdata/SystemV/PST8 create mode 100644 tcl/tcl8.6/tzdata/SystemV/PST8PDT create mode 100644 tcl/tcl8.6/tzdata/SystemV/YST9 create mode 100644 tcl/tcl8.6/tzdata/SystemV/YST9YDT create mode 100644 tcl/tcl8.6/tzdata/Turkey create mode 100644 tcl/tcl8.6/tzdata/UCT create mode 100644 tcl/tcl8.6/tzdata/US/Alaska create mode 100644 tcl/tcl8.6/tzdata/US/Aleutian create mode 100644 tcl/tcl8.6/tzdata/US/Arizona create mode 100644 tcl/tcl8.6/tzdata/US/Central create mode 100644 tcl/tcl8.6/tzdata/US/East-Indiana create mode 100644 tcl/tcl8.6/tzdata/US/Eastern create mode 100644 tcl/tcl8.6/tzdata/US/Hawaii create mode 100644 tcl/tcl8.6/tzdata/US/Indiana-Starke create mode 100644 tcl/tcl8.6/tzdata/US/Michigan create mode 100644 tcl/tcl8.6/tzdata/US/Mountain create mode 100644 tcl/tcl8.6/tzdata/US/Pacific create mode 100644 tcl/tcl8.6/tzdata/US/Pacific-New create mode 100644 tcl/tcl8.6/tzdata/US/Samoa create mode 100644 tcl/tcl8.6/tzdata/UTC create mode 100644 tcl/tcl8.6/tzdata/Universal create mode 100644 tcl/tcl8.6/tzdata/W-SU create mode 100644 tcl/tcl8.6/tzdata/WET create mode 100644 tcl/tcl8.6/tzdata/Zulu create mode 100644 tcl/tcl8.6/word.tcl create mode 100644 tcl/tk8.6/bgerror.tcl create mode 100644 tcl/tk8.6/button.tcl create mode 100644 tcl/tk8.6/choosedir.tcl create mode 100644 tcl/tk8.6/clrpick.tcl create mode 100644 tcl/tk8.6/comdlg.tcl create mode 100644 tcl/tk8.6/console.tcl create mode 100644 tcl/tk8.6/demos/README create mode 100644 tcl/tk8.6/demos/anilabel.tcl create mode 100644 tcl/tk8.6/demos/aniwave.tcl create mode 100644 tcl/tk8.6/demos/arrow.tcl create mode 100644 tcl/tk8.6/demos/bind.tcl create mode 100644 tcl/tk8.6/demos/bitmap.tcl create mode 100644 tcl/tk8.6/demos/browse create mode 100644 tcl/tk8.6/demos/button.tcl create mode 100644 tcl/tk8.6/demos/check.tcl create mode 100644 tcl/tk8.6/demos/clrpick.tcl create mode 100644 tcl/tk8.6/demos/colors.tcl create mode 100644 tcl/tk8.6/demos/combo.tcl create mode 100644 tcl/tk8.6/demos/cscroll.tcl create mode 100644 tcl/tk8.6/demos/ctext.tcl create mode 100644 tcl/tk8.6/demos/dialog1.tcl create mode 100644 tcl/tk8.6/demos/dialog2.tcl create mode 100644 tcl/tk8.6/demos/en.msg create mode 100644 tcl/tk8.6/demos/entry1.tcl create mode 100644 tcl/tk8.6/demos/entry2.tcl create mode 100644 tcl/tk8.6/demos/entry3.tcl create mode 100644 tcl/tk8.6/demos/filebox.tcl create mode 100644 tcl/tk8.6/demos/floor.tcl create mode 100644 tcl/tk8.6/demos/fontchoose.tcl create mode 100644 tcl/tk8.6/demos/form.tcl create mode 100644 tcl/tk8.6/demos/goldberg.tcl create mode 100644 tcl/tk8.6/demos/hello create mode 100644 tcl/tk8.6/demos/hscale.tcl create mode 100644 tcl/tk8.6/demos/icon.tcl create mode 100644 tcl/tk8.6/demos/image1.tcl create mode 100644 tcl/tk8.6/demos/image2.tcl create mode 100644 tcl/tk8.6/demos/images/earth.gif create mode 100644 tcl/tk8.6/demos/images/earthmenu.png create mode 100644 tcl/tk8.6/demos/images/earthris.gif create mode 100644 tcl/tk8.6/demos/images/flagdown.xbm create mode 100644 tcl/tk8.6/demos/images/flagup.xbm create mode 100644 tcl/tk8.6/demos/images/gray25.xbm create mode 100644 tcl/tk8.6/demos/images/letters.xbm create mode 100644 tcl/tk8.6/demos/images/noletter.xbm create mode 100644 tcl/tk8.6/demos/images/ouster.png create mode 100644 tcl/tk8.6/demos/images/pattern.xbm create mode 100644 tcl/tk8.6/demos/images/tcllogo.gif create mode 100644 tcl/tk8.6/demos/images/teapot.ppm create mode 100644 tcl/tk8.6/demos/items.tcl create mode 100644 tcl/tk8.6/demos/ixset create mode 100644 tcl/tk8.6/demos/knightstour.tcl create mode 100644 tcl/tk8.6/demos/label.tcl create mode 100644 tcl/tk8.6/demos/labelframe.tcl create mode 100644 tcl/tk8.6/demos/license.terms create mode 100644 tcl/tk8.6/demos/mclist.tcl create mode 100644 tcl/tk8.6/demos/menu.tcl create mode 100644 tcl/tk8.6/demos/menubu.tcl create mode 100644 tcl/tk8.6/demos/msgbox.tcl create mode 100644 tcl/tk8.6/demos/nl.msg create mode 100644 tcl/tk8.6/demos/paned1.tcl create mode 100644 tcl/tk8.6/demos/paned2.tcl create mode 100644 tcl/tk8.6/demos/pendulum.tcl create mode 100644 tcl/tk8.6/demos/plot.tcl create mode 100644 tcl/tk8.6/demos/puzzle.tcl create mode 100644 tcl/tk8.6/demos/radio.tcl create mode 100644 tcl/tk8.6/demos/rmt create mode 100644 tcl/tk8.6/demos/rolodex create mode 100644 tcl/tk8.6/demos/ruler.tcl create mode 100644 tcl/tk8.6/demos/sayings.tcl create mode 100644 tcl/tk8.6/demos/search.tcl create mode 100644 tcl/tk8.6/demos/spin.tcl create mode 100644 tcl/tk8.6/demos/square create mode 100644 tcl/tk8.6/demos/states.tcl create mode 100644 tcl/tk8.6/demos/style.tcl create mode 100644 tcl/tk8.6/demos/tclIndex create mode 100644 tcl/tk8.6/demos/tcolor create mode 100644 tcl/tk8.6/demos/text.tcl create mode 100644 tcl/tk8.6/demos/textpeer.tcl create mode 100644 tcl/tk8.6/demos/timer create mode 100644 tcl/tk8.6/demos/toolbar.tcl create mode 100644 tcl/tk8.6/demos/tree.tcl create mode 100644 tcl/tk8.6/demos/ttkbut.tcl create mode 100644 tcl/tk8.6/demos/ttkmenu.tcl create mode 100644 tcl/tk8.6/demos/ttknote.tcl create mode 100644 tcl/tk8.6/demos/ttkpane.tcl create mode 100644 tcl/tk8.6/demos/ttkprogress.tcl create mode 100644 tcl/tk8.6/demos/ttkscale.tcl create mode 100644 tcl/tk8.6/demos/twind.tcl create mode 100644 tcl/tk8.6/demos/unicodeout.tcl create mode 100644 tcl/tk8.6/demos/vscale.tcl create mode 100644 tcl/tk8.6/demos/widget create mode 100644 tcl/tk8.6/dialog.tcl create mode 100644 tcl/tk8.6/entry.tcl create mode 100644 tcl/tk8.6/focus.tcl create mode 100644 tcl/tk8.6/fontchooser.tcl create mode 100644 tcl/tk8.6/iconlist.tcl create mode 100644 tcl/tk8.6/icons.tcl create mode 100644 tcl/tk8.6/images/README create mode 100644 tcl/tk8.6/images/logo.eps create mode 100644 tcl/tk8.6/images/logo100.gif create mode 100644 tcl/tk8.6/images/logo64.gif create mode 100644 tcl/tk8.6/images/logoLarge.gif create mode 100644 tcl/tk8.6/images/logoMed.gif create mode 100644 tcl/tk8.6/images/pwrdLogo.eps create mode 100644 tcl/tk8.6/images/pwrdLogo100.gif create mode 100644 tcl/tk8.6/images/pwrdLogo150.gif create mode 100644 tcl/tk8.6/images/pwrdLogo175.gif create mode 100644 tcl/tk8.6/images/pwrdLogo200.gif create mode 100644 tcl/tk8.6/images/pwrdLogo75.gif create mode 100644 tcl/tk8.6/images/tai-ku.gif create mode 100644 tcl/tk8.6/license.terms create mode 100644 tcl/tk8.6/listbox.tcl create mode 100644 tcl/tk8.6/megawidget.tcl create mode 100644 tcl/tk8.6/menu.tcl create mode 100644 tcl/tk8.6/mkpsenc.tcl create mode 100644 tcl/tk8.6/msgbox.tcl create mode 100644 tcl/tk8.6/msgs/cs.msg create mode 100644 tcl/tk8.6/msgs/da.msg create mode 100644 tcl/tk8.6/msgs/de.msg create mode 100644 tcl/tk8.6/msgs/el.msg create mode 100644 tcl/tk8.6/msgs/en.msg create mode 100644 tcl/tk8.6/msgs/en_gb.msg create mode 100644 tcl/tk8.6/msgs/eo.msg create mode 100644 tcl/tk8.6/msgs/es.msg create mode 100644 tcl/tk8.6/msgs/fr.msg create mode 100644 tcl/tk8.6/msgs/hu.msg create mode 100644 tcl/tk8.6/msgs/it.msg create mode 100644 tcl/tk8.6/msgs/nl.msg create mode 100644 tcl/tk8.6/msgs/pl.msg create mode 100644 tcl/tk8.6/msgs/pt.msg create mode 100644 tcl/tk8.6/msgs/ru.msg create mode 100644 tcl/tk8.6/msgs/sv.msg create mode 100644 tcl/tk8.6/obsolete.tcl create mode 100644 tcl/tk8.6/optMenu.tcl create mode 100644 tcl/tk8.6/palette.tcl create mode 100644 tcl/tk8.6/panedwindow.tcl create mode 100644 tcl/tk8.6/pkgIndex.tcl create mode 100644 tcl/tk8.6/safetk.tcl create mode 100644 tcl/tk8.6/scale.tcl create mode 100644 tcl/tk8.6/scrlbar.tcl create mode 100644 tcl/tk8.6/spinbox.tcl create mode 100644 tcl/tk8.6/tclIndex create mode 100644 tcl/tk8.6/tearoff.tcl create mode 100644 tcl/tk8.6/text.tcl create mode 100644 tcl/tk8.6/tk.tcl create mode 100644 tcl/tk8.6/tkfbox.tcl create mode 100644 tcl/tk8.6/ttk/altTheme.tcl create mode 100644 tcl/tk8.6/ttk/aquaTheme.tcl create mode 100644 tcl/tk8.6/ttk/button.tcl create mode 100644 tcl/tk8.6/ttk/clamTheme.tcl create mode 100644 tcl/tk8.6/ttk/classicTheme.tcl create mode 100644 tcl/tk8.6/ttk/combobox.tcl create mode 100644 tcl/tk8.6/ttk/cursors.tcl create mode 100644 tcl/tk8.6/ttk/defaults.tcl create mode 100644 tcl/tk8.6/ttk/entry.tcl create mode 100644 tcl/tk8.6/ttk/fonts.tcl create mode 100644 tcl/tk8.6/ttk/menubutton.tcl create mode 100644 tcl/tk8.6/ttk/notebook.tcl create mode 100644 tcl/tk8.6/ttk/panedwindow.tcl create mode 100644 tcl/tk8.6/ttk/progress.tcl create mode 100644 tcl/tk8.6/ttk/scale.tcl create mode 100644 tcl/tk8.6/ttk/scrollbar.tcl create mode 100644 tcl/tk8.6/ttk/sizegrip.tcl create mode 100644 tcl/tk8.6/ttk/spinbox.tcl create mode 100644 tcl/tk8.6/ttk/treeview.tcl create mode 100644 tcl/tk8.6/ttk/ttk.tcl create mode 100644 tcl/tk8.6/ttk/utils.tcl create mode 100644 tcl/tk8.6/ttk/vistaTheme.tcl create mode 100644 tcl/tk8.6/ttk/winTheme.tcl create mode 100644 tcl/tk8.6/ttk/xpTheme.tcl create mode 100644 tcl/tk8.6/unsupported.tcl create mode 100644 tcl/tk8.6/xmfbox.tcl create mode 160000 templates diff --git a/Include/Python-ast.h b/Include/Python-ast.h new file mode 100644 index 0000000..8e0f750 --- /dev/null +++ b/Include/Python-ast.h @@ -0,0 +1,637 @@ +/* File automatically generated by Parser/asdl_c.py. */ + +#include "asdl.h" + +typedef struct _mod *mod_ty; + +typedef struct _stmt *stmt_ty; + +typedef struct _expr *expr_ty; + +typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5, + Param=6 } expr_context_ty; + +typedef struct _slice *slice_ty; + +typedef enum _boolop { And=1, Or=2 } boolop_ty; + +typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, + LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, + FloorDiv=13 } operator_ty; + +typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; + +typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, + In=9, NotIn=10 } cmpop_ty; + +typedef struct _comprehension *comprehension_ty; + +typedef struct _excepthandler *excepthandler_ty; + +typedef struct _arguments *arguments_ty; + +typedef struct _arg *arg_ty; + +typedef struct _keyword *keyword_ty; + +typedef struct _alias *alias_ty; + +typedef struct _withitem *withitem_ty; + + +enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, + Suite_kind=4}; +struct _mod { + enum _mod_kind kind; + union { + struct { + asdl_seq *body; + } Module; + + struct { + asdl_seq *body; + } Interactive; + + struct { + expr_ty body; + } Expression; + + struct { + asdl_seq *body; + } Suite; + + } v; +}; + +enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, + Return_kind=4, Delete_kind=5, Assign_kind=6, + AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, + AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, + AsyncWith_kind=14, Raise_kind=15, Try_kind=16, + Assert_kind=17, Import_kind=18, ImportFrom_kind=19, + Global_kind=20, Nonlocal_kind=21, Expr_kind=22, Pass_kind=23, + Break_kind=24, Continue_kind=25}; +struct _stmt { + enum _stmt_kind kind; + union { + struct { + identifier name; + arguments_ty args; + asdl_seq *body; + asdl_seq *decorator_list; + expr_ty returns; + } FunctionDef; + + struct { + identifier name; + arguments_ty args; + asdl_seq *body; + asdl_seq *decorator_list; + expr_ty returns; + } AsyncFunctionDef; + + struct { + identifier name; + asdl_seq *bases; + asdl_seq *keywords; + asdl_seq *body; + asdl_seq *decorator_list; + } ClassDef; + + struct { + expr_ty value; + } Return; + + struct { + asdl_seq *targets; + } Delete; + + struct { + asdl_seq *targets; + expr_ty value; + } Assign; + + struct { + expr_ty target; + operator_ty op; + expr_ty value; + } AugAssign; + + struct { + expr_ty target; + expr_ty annotation; + expr_ty value; + int simple; + } AnnAssign; + + struct { + expr_ty target; + expr_ty iter; + asdl_seq *body; + asdl_seq *orelse; + } For; + + struct { + expr_ty target; + expr_ty iter; + asdl_seq *body; + asdl_seq *orelse; + } AsyncFor; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } While; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } If; + + struct { + asdl_seq *items; + asdl_seq *body; + } With; + + struct { + asdl_seq *items; + asdl_seq *body; + } AsyncWith; + + struct { + expr_ty exc; + expr_ty cause; + } Raise; + + struct { + asdl_seq *body; + asdl_seq *handlers; + asdl_seq *orelse; + asdl_seq *finalbody; + } Try; + + struct { + expr_ty test; + expr_ty msg; + } Assert; + + struct { + asdl_seq *names; + } Import; + + struct { + identifier module; + asdl_seq *names; + int level; + } ImportFrom; + + struct { + asdl_seq *names; + } Global; + + struct { + asdl_seq *names; + } Nonlocal; + + struct { + expr_ty value; + } Expr; + + } v; + int lineno; + int col_offset; +}; + +enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4, + IfExp_kind=5, Dict_kind=6, Set_kind=7, ListComp_kind=8, + SetComp_kind=9, DictComp_kind=10, GeneratorExp_kind=11, + Await_kind=12, Yield_kind=13, YieldFrom_kind=14, + Compare_kind=15, Call_kind=16, Num_kind=17, Str_kind=18, + FormattedValue_kind=19, JoinedStr_kind=20, Bytes_kind=21, + NameConstant_kind=22, Ellipsis_kind=23, Constant_kind=24, + Attribute_kind=25, Subscript_kind=26, Starred_kind=27, + Name_kind=28, List_kind=29, Tuple_kind=30}; +struct _expr { + enum _expr_kind kind; + union { + struct { + boolop_ty op; + asdl_seq *values; + } BoolOp; + + struct { + expr_ty left; + operator_ty op; + expr_ty right; + } BinOp; + + struct { + unaryop_ty op; + expr_ty operand; + } UnaryOp; + + struct { + arguments_ty args; + expr_ty body; + } Lambda; + + struct { + expr_ty test; + expr_ty body; + expr_ty orelse; + } IfExp; + + struct { + asdl_seq *keys; + asdl_seq *values; + } Dict; + + struct { + asdl_seq *elts; + } Set; + + struct { + expr_ty elt; + asdl_seq *generators; + } ListComp; + + struct { + expr_ty elt; + asdl_seq *generators; + } SetComp; + + struct { + expr_ty key; + expr_ty value; + asdl_seq *generators; + } DictComp; + + struct { + expr_ty elt; + asdl_seq *generators; + } GeneratorExp; + + struct { + expr_ty value; + } Await; + + struct { + expr_ty value; + } Yield; + + struct { + expr_ty value; + } YieldFrom; + + struct { + expr_ty left; + asdl_int_seq *ops; + asdl_seq *comparators; + } Compare; + + struct { + expr_ty func; + asdl_seq *args; + asdl_seq *keywords; + } Call; + + struct { + object n; + } Num; + + struct { + string s; + } Str; + + struct { + expr_ty value; + int conversion; + expr_ty format_spec; + } FormattedValue; + + struct { + asdl_seq *values; + } JoinedStr; + + struct { + bytes s; + } Bytes; + + struct { + singleton value; + } NameConstant; + + struct { + constant value; + } Constant; + + struct { + expr_ty value; + identifier attr; + expr_context_ty ctx; + } Attribute; + + struct { + expr_ty value; + slice_ty slice; + expr_context_ty ctx; + } Subscript; + + struct { + expr_ty value; + expr_context_ty ctx; + } Starred; + + struct { + identifier id; + expr_context_ty ctx; + } Name; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } List; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } Tuple; + + } v; + int lineno; + int col_offset; +}; + +enum _slice_kind {Slice_kind=1, ExtSlice_kind=2, Index_kind=3}; +struct _slice { + enum _slice_kind kind; + union { + struct { + expr_ty lower; + expr_ty upper; + expr_ty step; + } Slice; + + struct { + asdl_seq *dims; + } ExtSlice; + + struct { + expr_ty value; + } Index; + + } v; +}; + +struct _comprehension { + expr_ty target; + expr_ty iter; + asdl_seq *ifs; + int is_async; +}; + +enum _excepthandler_kind {ExceptHandler_kind=1}; +struct _excepthandler { + enum _excepthandler_kind kind; + union { + struct { + expr_ty type; + identifier name; + asdl_seq *body; + } ExceptHandler; + + } v; + int lineno; + int col_offset; +}; + +struct _arguments { + asdl_seq *args; + arg_ty vararg; + asdl_seq *kwonlyargs; + asdl_seq *kw_defaults; + arg_ty kwarg; + asdl_seq *defaults; +}; + +struct _arg { + identifier arg; + expr_ty annotation; + int lineno; + int col_offset; +}; + +struct _keyword { + identifier arg; + expr_ty value; +}; + +struct _alias { + identifier name; + identifier asname; +}; + +struct _withitem { + expr_ty context_expr; + expr_ty optional_vars; +}; + + +#define Module(a0, a1) _Py_Module(a0, a1) +mod_ty _Py_Module(asdl_seq * body, PyArena *arena); +#define Interactive(a0, a1) _Py_Interactive(a0, a1) +mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena); +#define Expression(a0, a1) _Py_Expression(a0, a1) +mod_ty _Py_Expression(expr_ty body, PyArena *arena); +#define Suite(a0, a1) _Py_Suite(a0, a1) +mod_ty _Py_Suite(asdl_seq * body, PyArena *arena); +#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, + asdl_seq * decorator_list, expr_ty returns, int lineno, + int col_offset, PyArena *arena); +#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * + body, asdl_seq * decorator_list, expr_ty returns, + int lineno, int col_offset, PyArena *arena); +#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, + asdl_seq * body, asdl_seq * decorator_list, int lineno, + int col_offset, PyArena *arena); +#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3) +stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3) +stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, PyArena + *arena); +#define Assign(a0, a1, a2, a3, a4) _Py_Assign(a0, a1, a2, a3, a4) +stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int + col_offset, PyArena *arena); +#define AugAssign(a0, a1, a2, a3, a4, a5) _Py_AugAssign(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int + lineno, int col_offset, PyArena *arena); +#define AnnAssign(a0, a1, a2, a3, a4, a5, a6) _Py_AnnAssign(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int + simple, int lineno, int col_offset, PyArena *arena); +#define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, int lineno, int col_offset, PyArena *arena); +#define AsyncFor(a0, a1, a2, a3, a4, a5, a6) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, int lineno, int col_offset, PyArena *arena); +#define While(a0, a1, a2, a3, a4, a5) _Py_While(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define If(a0, a1, a2, a3, a4, a5) _Py_If(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define With(a0, a1, a2, a3, a4) _Py_With(a0, a1, a2, a3, a4) +stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, + PyArena *arena); +#define AsyncWith(a0, a1, a2, a3, a4) _Py_AsyncWith(a0, a1, a2, a3, a4) +stmt_ty _Py_AsyncWith(asdl_seq * items, asdl_seq * body, int lineno, int + col_offset, PyArena *arena); +#define Raise(a0, a1, a2, a3, a4) _Py_Raise(a0, a1, a2, a3, a4) +stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, + PyArena *arena); +#define Try(a0, a1, a2, a3, a4, a5, a6) _Py_Try(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, + asdl_seq * finalbody, int lineno, int col_offset, PyArena + *arena); +#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4) +stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, + PyArena *arena); +#define Import(a0, a1, a2, a3) _Py_Import(a0, a1, a2, a3) +stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define ImportFrom(a0, a1, a2, a3, a4, a5) _Py_ImportFrom(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int + lineno, int col_offset, PyArena *arena); +#define Global(a0, a1, a2, a3) _Py_Global(a0, a1, a2, a3) +stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define Nonlocal(a0, a1, a2, a3) _Py_Nonlocal(a0, a1, a2, a3) +stmt_ty _Py_Nonlocal(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define Expr(a0, a1, a2, a3) _Py_Expr(a0, a1, a2, a3) +stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Pass(a0, a1, a2) _Py_Pass(a0, a1, a2) +stmt_ty _Py_Pass(int lineno, int col_offset, PyArena *arena); +#define Break(a0, a1, a2) _Py_Break(a0, a1, a2) +stmt_ty _Py_Break(int lineno, int col_offset, PyArena *arena); +#define Continue(a0, a1, a2) _Py_Continue(a0, a1, a2) +stmt_ty _Py_Continue(int lineno, int col_offset, PyArena *arena); +#define BoolOp(a0, a1, a2, a3, a4) _Py_BoolOp(a0, a1, a2, a3, a4) +expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, + PyArena *arena); +#define BinOp(a0, a1, a2, a3, a4, a5) _Py_BinOp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int + col_offset, PyArena *arena); +#define UnaryOp(a0, a1, a2, a3, a4) _Py_UnaryOp(a0, a1, a2, a3, a4) +expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, + PyArena *arena); +#define Lambda(a0, a1, a2, a3, a4) _Py_Lambda(a0, a1, a2, a3, a4) +expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, + PyArena *arena); +#define IfExp(a0, a1, a2, a3, a4, a5) _Py_IfExp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int + col_offset, PyArena *arena); +#define Dict(a0, a1, a2, a3, a4) _Py_Dict(a0, a1, a2, a3, a4) +expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int + col_offset, PyArena *arena); +#define Set(a0, a1, a2, a3) _Py_Set(a0, a1, a2, a3) +expr_ty _Py_Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena); +#define ListComp(a0, a1, a2, a3, a4) _Py_ListComp(a0, a1, a2, a3, a4) +expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define SetComp(a0, a1, a2, a3, a4) _Py_SetComp(a0, a1, a2, a3, a4) +expr_ty _Py_SetComp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define DictComp(a0, a1, a2, a3, a4, a5) _Py_DictComp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int + lineno, int col_offset, PyArena *arena); +#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4) +expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define Await(a0, a1, a2, a3) _Py_Await(a0, a1, a2, a3) +expr_ty _Py_Await(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3) +expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define YieldFrom(a0, a1, a2, a3) _Py_YieldFrom(a0, a1, a2, a3) +expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, PyArena + *arena); +#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, + int lineno, int col_offset, PyArena *arena); +#define Call(a0, a1, a2, a3, a4, a5) _Py_Call(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int + lineno, int col_offset, PyArena *arena); +#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3) +expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena); +#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3) +expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena); +#define FormattedValue(a0, a1, a2, a3, a4, a5) _Py_FormattedValue(a0, a1, a2, a3, a4, a5) +expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, + int lineno, int col_offset, PyArena *arena); +#define JoinedStr(a0, a1, a2, a3) _Py_JoinedStr(a0, a1, a2, a3) +expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, PyArena + *arena); +#define Bytes(a0, a1, a2, a3) _Py_Bytes(a0, a1, a2, a3) +expr_ty _Py_Bytes(bytes s, int lineno, int col_offset, PyArena *arena); +#define NameConstant(a0, a1, a2, a3) _Py_NameConstant(a0, a1, a2, a3) +expr_ty _Py_NameConstant(singleton value, int lineno, int col_offset, PyArena + *arena); +#define Ellipsis(a0, a1, a2) _Py_Ellipsis(a0, a1, a2) +expr_ty _Py_Ellipsis(int lineno, int col_offset, PyArena *arena); +#define Constant(a0, a1, a2, a3) _Py_Constant(a0, a1, a2, a3) +expr_ty _Py_Constant(constant value, int lineno, int col_offset, PyArena + *arena); +#define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Subscript(a0, a1, a2, a3, a4, a5) _Py_Subscript(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Starred(a0, a1, a2, a3, a4) _Py_Starred(a0, a1, a2, a3, a4) +expr_ty _Py_Starred(expr_ty value, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Name(a0, a1, a2, a3, a4) _Py_Name(a0, a1, a2, a3, a4) +expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define List(a0, a1, a2, a3, a4) _Py_List(a0, a1, a2, a3, a4) +expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Tuple(a0, a1, a2, a3, a4) _Py_Tuple(a0, a1, a2, a3, a4) +expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Slice(a0, a1, a2, a3) _Py_Slice(a0, a1, a2, a3) +slice_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena); +#define ExtSlice(a0, a1) _Py_ExtSlice(a0, a1) +slice_ty _Py_ExtSlice(asdl_seq * dims, PyArena *arena); +#define Index(a0, a1) _Py_Index(a0, a1) +slice_ty _Py_Index(expr_ty value, PyArena *arena); +#define comprehension(a0, a1, a2, a3, a4) _Py_comprehension(a0, a1, a2, a3, a4) +comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq * + ifs, int is_async, PyArena *arena); +#define ExceptHandler(a0, a1, a2, a3, a4, a5) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5) +excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq * + body, int lineno, int col_offset, PyArena + *arena); +#define arguments(a0, a1, a2, a3, a4, a5, a6) _Py_arguments(a0, a1, a2, a3, a4, a5, a6) +arguments_ty _Py_arguments(asdl_seq * args, arg_ty vararg, asdl_seq * + kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, + asdl_seq * defaults, PyArena *arena); +#define arg(a0, a1, a2, a3, a4) _Py_arg(a0, a1, a2, a3, a4) +arg_ty _Py_arg(identifier arg, expr_ty annotation, int lineno, int col_offset, + PyArena *arena); +#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) +keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); +#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) +alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); +#define withitem(a0, a1, a2) _Py_withitem(a0, a1, a2) +withitem_ty _Py_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena + *arena); + +PyObject* PyAST_mod2obj(mod_ty t); +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); +int PyAST_Check(PyObject* obj); diff --git a/Include/Python.h b/Include/Python.h new file mode 100644 index 0000000..1feb153 --- /dev/null +++ b/Include/Python.h @@ -0,0 +1,140 @@ +#ifndef Py_PYTHON_H +#define Py_PYTHON_H +/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ + +/* Include nearly all Python header files */ + +#include "patchlevel.h" +#include "pyconfig.h" +#include "pymacconfig.h" + +#include + +#ifndef UCHAR_MAX +#error "Something's broken. UCHAR_MAX should be defined in limits.h." +#endif + +#if UCHAR_MAX != 255 +#error "Python's source code assumes C's unsigned char is an 8-bit type." +#endif + +#if defined(__sgi) && !defined(_SGI_MP_SOURCE) +#define _SGI_MP_SOURCE +#endif + +#include +#ifndef NULL +# error "Python.h requires that stdio.h define NULL." +#endif + +#include +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_CRYPT_H +#include +#endif + +/* For size_t? */ +#ifdef HAVE_STDDEF_H +#include +#endif + +/* CAUTION: Build setups should ensure that NDEBUG is defined on the + * compiler command line when building Python in release mode; else + * assert() calls won't be removed. + */ +#include + +#include "pyport.h" +#include "pymacro.h" + +#include "pyatomic.h" + +/* Debug-mode build with pymalloc implies PYMALLOC_DEBUG. + * PYMALLOC_DEBUG is in error if pymalloc is not in use. + */ +#if defined(Py_DEBUG) && defined(WITH_PYMALLOC) && !defined(PYMALLOC_DEBUG) +#define PYMALLOC_DEBUG +#endif +#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC) +#error "PYMALLOC_DEBUG requires WITH_PYMALLOC" +#endif +#include "pymath.h" +#include "pytime.h" +#include "pymem.h" + +#include "object.h" +#include "objimpl.h" +#include "typeslots.h" +#include "pyhash.h" + +#include "pydebug.h" + +#include "bytearrayobject.h" +#include "bytesobject.h" +#include "unicodeobject.h" +#include "longobject.h" +#include "longintrepr.h" +#include "boolobject.h" +#include "floatobject.h" +#include "complexobject.h" +#include "rangeobject.h" +#include "memoryobject.h" +#include "tupleobject.h" +#include "listobject.h" +#include "dictobject.h" +#include "odictobject.h" +#include "enumobject.h" +#include "setobject.h" +#include "methodobject.h" +#include "moduleobject.h" +#include "funcobject.h" +#include "classobject.h" +#include "fileobject.h" +#include "pycapsule.h" +#include "traceback.h" +#include "sliceobject.h" +#include "cellobject.h" +#include "iterobject.h" +#include "genobject.h" +#include "descrobject.h" +#include "warnings.h" +#include "weakrefobject.h" +#include "structseq.h" +#include "namespaceobject.h" + +#include "codecs.h" +#include "pyerrors.h" + +#include "pystate.h" +#include "context.h" + +#include "pyarena.h" +#include "modsupport.h" +#include "compile.h" +#include "pythonrun.h" +#include "pylifecycle.h" +#include "ceval.h" +#include "sysmodule.h" +#include "osmodule.h" +#include "intrcheck.h" +#include "import.h" + +#include "abstract.h" +#include "bltinmodule.h" + +#include "eval.h" + +#include "pyctype.h" +#include "pystrtod.h" +#include "pystrcmp.h" +#include "dtoa.h" +#include "fileutils.h" +#include "pyfpe.h" + +#endif /* !Py_PYTHON_H */ diff --git a/Include/abstract.h b/Include/abstract.h new file mode 100644 index 0000000..4088f75 --- /dev/null +++ b/Include/abstract.h @@ -0,0 +1,1109 @@ +/* Abstract Object Interface (many thanks to Jim Fulton) */ + +#ifndef Py_ABSTRACTOBJECT_H +#define Py_ABSTRACTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* === Object Protocol ================================================== */ + +/* Implemented elsewhere: + + int PyObject_Print(PyObject *o, FILE *fp, int flags); + + Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument + is used to enable certain printing options. The only option currently + supported is Py_Print_RAW. + + (What should be said about Py_Print_RAW?). */ + + +/* Implemented elsewhere: + + int PyObject_HasAttrString(PyObject *o, const char *attr_name); + + Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise. + + This is equivalent to the Python expression: hasattr(o,attr_name). + + This function always succeeds. */ + + +/* Implemented elsewhere: + + PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name); + + Retrieve an attributed named attr_name form object o. + Returns the attribute value on success, or NULL on failure. + + This is the equivalent of the Python expression: o.attr_name. */ + + +/* Implemented elsewhere: + + int PyObject_HasAttr(PyObject *o, PyObject *attr_name); + + Returns 1 if o has the attribute attr_name, and 0 otherwise. + + This is equivalent to the Python expression: hasattr(o,attr_name). + + This function always succeeds. */ + +/* Implemented elsewhere: + + PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name); + + Retrieve an attributed named 'attr_name' form object 'o'. + Returns the attribute value on success, or NULL on failure. + + This is the equivalent of the Python expression: o.attr_name. */ + + +/* Implemented elsewhere: + + int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object 'o', + to the value 'v'. Raise an exception and return -1 on failure; return 0 on + success. + + This is the equivalent of the Python statement o.attr_name=v. */ + + +/* Implemented elsewhere: + + int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object 'o', to the value + 'v'. an exception and return -1 on failure; return 0 on success. + + This is the equivalent of the Python statement o.attr_name=v. */ + +/* Implemented as a macro: + + int PyObject_DelAttrString(PyObject *o, const char *attr_name); + + Delete attribute named attr_name, for object o. Returns + -1 on failure. + + This is the equivalent of the Python statement: del o.attr_name. */ +#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A), NULL) + + +/* Implemented as a macro: + + int PyObject_DelAttr(PyObject *o, PyObject *attr_name); + + Delete attribute named attr_name, for object o. Returns -1 + on failure. This is the equivalent of the Python + statement: del o.attr_name. */ +#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A), NULL) + + +/* Implemented elsewhere: + + PyObject *PyObject_Repr(PyObject *o); + + Compute the string representation of object 'o'. Returns the + string representation on success, NULL on failure. + + This is the equivalent of the Python expression: repr(o). + + Called by the repr() built-in function. */ + + +/* Implemented elsewhere: + + PyObject *PyObject_Str(PyObject *o); + + Compute the string representation of object, o. Returns the + string representation on success, NULL on failure. + + This is the equivalent of the Python expression: str(o). + + Called by the str() and print() built-in functions. */ + + +/* Declared elsewhere + + PyAPI_FUNC(int) PyCallable_Check(PyObject *o); + + Determine if the object, o, is callable. Return 1 if the object is callable + and 0 otherwise. + + This function always succeeds. */ + + +#ifdef PY_SSIZE_T_CLEAN +# define PyObject_CallFunction _PyObject_CallFunction_SizeT +# define PyObject_CallMethod _PyObject_CallMethod_SizeT +# ifndef Py_LIMITED_API +# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT +# endif /* !Py_LIMITED_API */ +#endif + + +/* Call a callable Python object 'callable' with arguments given by the + tuple 'args' and keywords arguments given by the dictionary 'kwargs'. + + 'args' must not be *NULL*, use an empty tuple if no arguments are + needed. If no named arguments are needed, 'kwargs' can be NULL. + + This is the equivalent of the Python expression: + callable(*args, **kwargs). */ +PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable, + PyObject *args, PyObject *kwargs); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) _PyStack_AsTuple( + PyObject *const *stack, + Py_ssize_t nargs); + +PyAPI_FUNC(PyObject*) _PyStack_AsTupleSlice( + PyObject *const *stack, + Py_ssize_t nargs, + Py_ssize_t start, + Py_ssize_t end); + +/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) + format to a Python dictionary ("kwargs" dict). + + The type of kwnames keys is not checked. The final function getting + arguments is responsible to check if all keys are strings, for example using + PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). + + Duplicate keys are merged using the last value. If duplicate keys must raise + an exception, the caller is responsible to implement an explicit keys on + kwnames. */ +PyAPI_FUNC(PyObject *) _PyStack_AsDict( + PyObject *const *values, + PyObject *kwnames); + +/* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple). + + Return 0 on success, raise an exception and return -1 on error. + + Write the new stack into *p_stack. If *p_stack is differen than args, it + must be released by PyMem_Free(). + + The stack uses borrowed references. + + The type of keyword keys is not checked, these checks should be done + later (ex: _PyArg_ParseStackAndKeywords). */ +PyAPI_FUNC(int) _PyStack_UnpackDict( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs, + PyObject *const **p_stack, + PyObject **p_kwnames); + +/* Suggested size (number of positional arguments) for arrays of PyObject* + allocated on a C stack to avoid allocating memory on the heap memory. Such + array is used to pass positional arguments to call functions of the + _PyObject_FastCall() family. + + The size is chosen to not abuse the C stack and so limit the risk of stack + overflow. The size is also chosen to allow using the small stack for most + function calls of the Python standard library. On 64-bit CPU, it allocates + 40 bytes on the stack. */ +#define _PY_FASTCALL_SMALL_STACK 5 + +/* Return 1 if callable supports FASTCALL calling convention for positional + arguments: see _PyObject_FastCallDict() and _PyObject_FastCallKeywords() */ +PyAPI_FUNC(int) _PyObject_HasFastCall(PyObject *callable); + +/* Call the callable object 'callable' with the "fast call" calling convention: + args is a C array for positional arguments (nargs is the number of + positional arguments), kwargs is a dictionary for keyword arguments. + + If nargs is equal to zero, args can be NULL. kwargs can be NULL. + nargs must be greater or equal to zero. + + Return the result on success. Raise an exception on return NULL on + error. */ +PyAPI_FUNC(PyObject *) _PyObject_FastCallDict( + PyObject *callable, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs); + +/* Call the callable object 'callable' with the "fast call" calling convention: + args is a C array for positional arguments followed by values of + keyword arguments. Keys of keyword arguments are stored as a tuple + of strings in kwnames. nargs is the number of positional parameters at + the beginning of stack. The size of kwnames gives the number of keyword + values in the stack after positional arguments. + + kwnames must only contains str strings, no subclass, and all keys must + be unique. + + If nargs is equal to zero and there is no keyword argument (kwnames is + NULL or its size is zero), args can be NULL. + + Return the result on success. Raise an exception and return NULL on + error. */ +PyAPI_FUNC(PyObject *) _PyObject_FastCallKeywords( + PyObject *callable, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames); + +#define _PyObject_FastCall(func, args, nargs) \ + _PyObject_FastCallDict((func), (args), (nargs), NULL) + +#define _PyObject_CallNoArg(func) \ + _PyObject_FastCallDict((func), NULL, 0, NULL) + +PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( + PyObject *callable, + PyObject *obj, + PyObject *args, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyObject_FastCall_Prepend( + PyObject *callable, + PyObject *obj, + PyObject *const *args, + Py_ssize_t nargs); + +PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable, + PyObject *result, + const char *where); +#endif /* Py_LIMITED_API */ + + +/* Call a callable Python object 'callable', with arguments given by the + tuple 'args'. If no arguments are needed, then 'args' can be *NULL*. + + Returns the result of the call on success, or *NULL* on failure. + + This is the equivalent of the Python expression: + callable(*args). */ +PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable, + PyObject *args); + +/* Call a callable Python object, callable, with a variable number of C + arguments. The C arguments are described using a mkvalue-style format + string. + + The format may be NULL, indicating that no arguments are provided. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: + callable(arg1, arg2, ...). */ +PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable, + const char *format, ...); + +/* Call the method named 'name' of object 'obj' with a variable number of + C arguments. The C arguments are described by a mkvalue format string. + + The format can be NULL, indicating that no arguments are provided. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: + obj.name(arg1, arg2, ...). */ +PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj, + const char *name, + const char *format, ...); + +#ifndef Py_LIMITED_API +/* Like PyObject_CallMethod(), but expect a _Py_Identifier* + as the method name. */ +PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, + _Py_Identifier *name, + const char *format, ...); +#endif /* !Py_LIMITED_API */ + +PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable, + const char *format, + ...); + +PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj, + const char *name, + const char *format, + ...); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, + _Py_Identifier *name, + const char *format, + ...); +#endif /* !Py_LIMITED_API */ + +/* Call a callable Python object 'callable' with a variable number of C + arguments. The C arguments are provided as PyObject* values, terminated + by a NULL. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: + callable(arg1, arg2, ...). */ +PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, + ...); + +/* Call the method named 'name' of object 'obj' with a variable number of + C arguments. The C arguments are provided as PyObject* values, terminated + by NULL. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: obj.name(*args). */ + +PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs( + PyObject *obj, + PyObject *name, + ...); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( + PyObject *obj, + struct _Py_Identifier *name, + ...); +#endif /* !Py_LIMITED_API */ + + +/* Implemented elsewhere: + + Py_hash_t PyObject_Hash(PyObject *o); + + Compute and return the hash, hash_value, of an object, o. On + failure, return -1. + + This is the equivalent of the Python expression: hash(o). */ + + +/* Implemented elsewhere: + + int PyObject_IsTrue(PyObject *o); + + Returns 1 if the object, o, is considered to be true, 0 if o is + considered to be false and -1 on failure. + + This is equivalent to the Python expression: not not o. */ + + +/* Implemented elsewhere: + + int PyObject_Not(PyObject *o); + + Returns 0 if the object, o, is considered to be true, 1 if o is + considered to be false and -1 on failure. + + This is equivalent to the Python expression: not o. */ + + +/* Get the type of an object. + + On success, returns a type object corresponding to the object type of object + 'o'. On failure, returns NULL. + + This is equivalent to the Python expression: type(o) */ +PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o); + + +/* Return the size of object 'o'. If the object 'o' provides both sequence and + mapping protocols, the sequence size is returned. + + On error, -1 is returned. + + This is the equivalent to the Python expression: len(o) */ +PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o); + + +/* For DLL compatibility */ +#undef PyObject_Length +PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); +#define PyObject_Length PyObject_Size + + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); + +/* Guess the size of object 'o' using len(o) or o.__length_hint__(). + If neither of those return a non-negative value, then return the default + value. If one of the calls fails, this function returns -1. */ +PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); +#endif + +/* Return element of 'o' corresponding to the object 'key'. Return NULL + on failure. + + This is the equivalent of the Python expression: o[key] */ +PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key); + + +/* Map the object 'key' to the value 'v' into 'o'. + + Raise an exception and return -1 on failure; return 0 on success. + + This is the equivalent of the Python statement: o[key]=v. */ +PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v); + +/* Remove the mapping for the string 'key' from the object 'o'. + Returns -1 on failure. + + This is equivalent to the Python statement: del o[key]. */ +PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key); + +/* Delete the mapping for the object 'key' from the object 'o'. + Returns -1 on failure. + + This is the equivalent of the Python statement: del o[key]. */ +PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key); + + +/* === Old Buffer API ============================================ */ + +/* FIXME: usage of these should all be replaced in Python itself + but for backwards compatibility we will implement them. + Their usage without a corresponding "unlock" mechanism + may create issues (but they would already be there). */ + +/* Takes an arbitrary object which must support the (character, single segment) + buffer interface and returns a pointer to a read-only memory location + useable as character based input for subsequent processing. + + Return 0 on success. buffer and buffer_len are only set in case no error + occurs. Otherwise, -1 is returned and an exception set. */ +PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj, + const char **buffer, + Py_ssize_t *buffer_len) + Py_DEPRECATED(3.0); + +/* Checks whether an arbitrary object supports the (character, single segment) + buffer interface. + + Returns 1 on success, 0 on failure. */ +PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj) + Py_DEPRECATED(3.0); + +/* Same as PyObject_AsCharBuffer() except that this API expects (readable, + single segment) buffer interface and returns a pointer to a read-only memory + location which can contain arbitrary data. + + 0 is returned on success. buffer and buffer_len are only set in case no + error occurs. Otherwise, -1 is returned and an exception set. */ +PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj, + const void **buffer, + Py_ssize_t *buffer_len) + Py_DEPRECATED(3.0); + +/* Takes an arbitrary object which must support the (writable, single segment) + buffer interface and returns a pointer to a writable memory location in + buffer of size 'buffer_len'. + + Return 0 on success. buffer and buffer_len are only set in case no error + occurs. Otherwise, -1 is returned and an exception set. */ +PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj, + void **buffer, + Py_ssize_t *buffer_len) + Py_DEPRECATED(3.0); + + +/* === New Buffer API ============================================ */ + +#ifndef Py_LIMITED_API + +/* Return 1 if the getbuffer function is available, otherwise return 0. */ +#define PyObject_CheckBuffer(obj) \ + (((obj)->ob_type->tp_as_buffer != NULL) && \ + ((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL)) + +/* This is a C-API version of the getbuffer function call. It checks + to make sure object has the required function pointer and issues the + call. + + Returns -1 and raises an error on failure and returns 0 on success. */ +PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, + int flags); + +/* Get the memory area pointed to by the indices for the buffer given. + Note that view->ndim is the assumed size of indices. */ +PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); + +/* Return the implied itemsize of the data-format area from a + struct-style description. */ +PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *); + +/* Implementation in memoryobject.c */ +PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view, + Py_ssize_t len, char order); + +PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf, + Py_ssize_t len, char order); + +/* Copy len bytes of data from the contiguous chunk of memory + pointed to by buf into the buffer exported by obj. Return + 0 on success and return -1 and raise a PyBuffer_Error on + error (i.e. the object does not have a buffer interface or + it is not working). + + If fort is 'F', then if the object is multi-dimensional, + then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If + fort is 'C', then the data will be copied into the array + in C-style (last dimension varies the fastest). If fort + is 'A', then it does not matter and the copy will be made + in whatever way is more efficient. */ +PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); + +/* Copy the data from the src buffer to the buffer of destination. */ +PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort); + +/*Fill the strides array with byte-strides of a contiguous + (Fortran-style if fort is 'F' or C-style otherwise) + array of the given shape with the given number of bytes + per element. */ +PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, + Py_ssize_t *shape, + Py_ssize_t *strides, + int itemsize, + char fort); + +/* Fills in a buffer-info structure correctly for an exporter + that can only share a contiguous chunk of memory of + "unsigned bytes" of the given length. + + Returns 0 on success and -1 (with raising an error) on error. */ +PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, + Py_ssize_t len, int readonly, + int flags); + +/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ +PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); + +#endif /* Py_LIMITED_API */ + +/* Takes an arbitrary object and returns the result of calling + obj.__format__(format_spec). */ +PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj, + PyObject *format_spec); + + +/* ==== Iterators ================================================ */ + +/* Takes an object and returns an iterator for it. + This is typically a new iterator but if the argument is an iterator, this + returns itself. */ +PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); + +#define PyIter_Check(obj) \ + ((obj)->ob_type->tp_iternext != NULL && \ + (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented) + +/* Takes an iterator object and calls its tp_iternext slot, + returning the next value. + + If the iterator is exhausted, this returns NULL without setting an + exception. + + NULL with an exception means an error occurred. */ +PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); + + +/* === Number Protocol ================================================== */ + +/* Returns 1 if the object 'o' provides numeric protocols, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyNumber_Check(PyObject *o); + +/* Returns the result of adding o1 and o2, or NULL on failure. + + This is the equivalent of the Python expression: o1 + o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2); + +/* Returns the result of subtracting o2 from o1, or NULL on failure. + + This is the equivalent of the Python expression: o1 - o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2); + +/* Returns the result of multiplying o1 and o2, or NULL on failure. + + This is the equivalent of the Python expression: o1 * o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* This is the equivalent of the Python expression: o1 @ o2. */ +PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2); +#endif + +/* Returns the result of dividing o1 by o2 giving an integral result, + or NULL on failure. + + This is the equivalent of the Python expression: o1 // o2. */ +PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); + +/* Returns the result of dividing o1 by o2 giving a float result, or NULL on + failure. + + This is the equivalent of the Python expression: o1 / o2. */ +PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2); + +/* Returns the remainder of dividing o1 by o2, or NULL on failure. + + This is the equivalent of the Python expression: o1 % o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2); + +/* See the built-in function divmod. + + Returns NULL on failure. + + This is the equivalent of the Python expression: divmod(o1, o2). */ +PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2); + +/* See the built-in function pow. Returns NULL on failure. + + This is the equivalent of the Python expression: pow(o1, o2, o3), + where o3 is optional. */ +PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2, + PyObject *o3); + +/* Returns the negation of o on success, or NULL on failure. + + This is the equivalent of the Python expression: -o. */ +PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o); + +/* Returns the positive of o on success, or NULL on failure. + + This is the equivalent of the Python expression: +o. */ +PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o); + +/* Returns the absolute value of 'o', or NULL on failure. + + This is the equivalent of the Python expression: abs(o). */ +PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o); + +/* Returns the bitwise negation of 'o' on success, or NULL on failure. + + This is the equivalent of the Python expression: ~o. */ +PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o); + +/* Returns the result of left shifting o1 by o2 on success, or NULL on failure. + + This is the equivalent of the Python expression: o1 << o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2); + +/* Returns the result of right shifting o1 by o2 on success, or NULL on + failure. + + This is the equivalent of the Python expression: o1 >> o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise and of o1 and o2 on success, or NULL on + failure. + + This is the equivalent of the Python expression: o1 & o2. */ +PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2); + +/* Returns the bitwise exclusive or of o1 by o2 on success, or NULL on failure. + + This is the equivalent of the Python expression: o1 ^ o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise or on o1 and o2 on success, or NULL on + failure. + + This is the equivalent of the Python expression: o1 | o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2); + +#define PyIndex_Check(obj) \ + ((obj)->ob_type->tp_as_number != NULL && \ + (obj)->ob_type->tp_as_number->nb_index != NULL) + +/* Returns the object 'o' converted to a Python int, or NULL with an exception + raised on failure. */ +PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o); + +/* Returns the object 'o' converted to Py_ssize_t by going through + PyNumber_Index() first. + + If an overflow error occurs while converting the int to Py_ssize_t, then the + second argument 'exc' is the error-type to return. If it is NULL, then the + overflow error is cleared and the value is clipped. */ +PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc); + +/* Returns the object 'o' converted to an integer object on success, or NULL + on failure. + + This is the equivalent of the Python expression: int(o). */ +PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o); + +/* Returns the object 'o' converted to a float object on success, or NULL + on failure. + + This is the equivalent of the Python expression: float(o). */ +PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o); + + +/* --- In-place variants of (some of) the above number protocol functions -- */ + +/* Returns the result of adding o2 to o1, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 += o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2); + +/* Returns the result of subtracting o2 from o1, possibly in-place or + NULL on failure. + + This is the equivalent of the Python expression: o1 -= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2); + +/* Returns the result of multiplying o1 by o2, possibly in-place, or NULL on + failure. + + This is the equivalent of the Python expression: o1 *= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* This is the equivalent of the Python expression: o1 @= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2); +#endif + +/* Returns the result of dividing o1 by o2 giving an integral result, possibly + in-place, or NULL on failure. + + This is the equivalent of the Python expression: o1 /= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, + PyObject *o2); + +/* Returns the result of dividing o1 by o2 giving a float result, possibly + in-place, or null on failure. + + This is the equivalent of the Python expression: o1 /= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1, + PyObject *o2); + +/* Returns the remainder of dividing o1 by o2, possibly in-place, or NULL on + failure. + + This is the equivalent of the Python expression: o1 %= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2); + +/* Returns the result of raising o1 to the power of o2, possibly in-place, + or NULL on failure. + + This is the equivalent of the Python expression: o1 **= o2, + or o1 = pow(o1, o2, o3) if o3 is present. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2, + PyObject *o3); + +/* Returns the result of left shifting o1 by o2, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 <<= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2); + +/* Returns the result of right shifting o1 by o2, possibly in-place or NULL + on failure. + + This is the equivalent of the Python expression: o1 >>= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise and of o1 and o2, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 &= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2); + +/* Returns the bitwise exclusive or of o1 by o2, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 ^= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise or of o1 and o2, possibly in-place, + or NULL on failure. + + This is the equivalent of the Python expression: o1 |= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2); + +/* Returns the integer n converted to a string with a base, with a base + marker of 0b, 0o or 0x prefixed if applicable. + + If n is not an int object, it is converted with PyNumber_Index first. */ +PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base); + + +/* === Sequence protocol ================================================ */ + +/* Return 1 if the object provides sequence protocol, and zero + otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PySequence_Check(PyObject *o); + +/* Return the size of sequence object o, or -1 on failure. */ +PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o); + +/* For DLL compatibility */ +#undef PySequence_Length +PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o); +#define PySequence_Length PySequence_Size + + +/* Return the concatenation of o1 and o2 on success, and NULL on failure. + + This is the equivalent of the Python expression: o1 + o2. */ +PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2); + +/* Return the result of repeating sequence object 'o' 'count' times, + or NULL on failure. + + This is the equivalent of the Python expression: o * count. */ +PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count); + +/* Return the ith element of o, or NULL on failure. + + This is the equivalent of the Python expression: o[i]. */ +PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i); + +/* Return the slice of sequence object o between i1 and i2, or NULL on failure. + + This is the equivalent of the Python expression: o[i1:i2]. */ +PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + +/* Assign object 'v' to the ith element of the sequence 'o'. Raise an exception + and return -1 on failure; return 0 on success. + + This is the equivalent of the Python statement o[i] = v. */ +PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v); + +/* Delete the 'i'-th element of the sequence 'v'. Returns -1 on failure. + + This is the equivalent of the Python statement: del o[i]. */ +PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i); + +/* Assign the sequence object 'v' to the slice in sequence object 'o', + from 'i1' to 'i2'. Returns -1 on failure. + + This is the equivalent of the Python statement: o[i1:i2] = v. */ +PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, + PyObject *v); + +/* Delete the slice in sequence object 'o' from 'i1' to 'i2'. + Returns -1 on failure. + + This is the equivalent of the Python statement: del o[i1:i2]. */ +PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + +/* Returns the sequence 'o' as a tuple on success, and NULL on failure. + + This is equivalent to the Python expression: tuple(o). */ +PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o); + +/* Returns the sequence 'o' as a list on success, and NULL on failure. + This is equivalent to the Python expression: list(o) */ +PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o); + +/* Return the sequence 'o' as a list, unless it's already a tuple or list. + + Use PySequence_Fast_GET_ITEM to access the members of this list, and + PySequence_Fast_GET_SIZE to get its length. + + Returns NULL on failure. If the object does not support iteration, raises a + TypeError exception with 'm' as the message text. */ +PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); + +/* Return the size of the sequence 'o', assuming that 'o' was returned by + PySequence_Fast and is not NULL. */ +#define PySequence_Fast_GET_SIZE(o) \ + (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o)) + +/* Return the 'i'-th element of the sequence 'o', assuming that o was returned + by PySequence_Fast, and that i is within bounds. */ +#define PySequence_Fast_GET_ITEM(o, i)\ + (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) + +/* Assume tp_as_sequence and sq_item exist and that 'i' does not + need to be corrected for a negative index. */ +#define PySequence_ITEM(o, i)\ + ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) + +/* Return a pointer to the underlying item array for + an object retured by PySequence_Fast */ +#define PySequence_Fast_ITEMS(sf) \ + (PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \ + : ((PyTupleObject *)(sf))->ob_item) + +/* Return the number of occurrences on value on 'o', that is, return + the number of keys for which o[key] == value. + + On failure, return -1. This is equivalent to the Python expression: + o.count(value). */ +PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value); + +/* Return 1 if 'ob' is in the sequence 'seq'; 0 if 'ob' is not in the sequence + 'seq'; -1 on error. + + Use __contains__ if possible, else _PySequence_IterSearch(). */ +PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob); + +#ifndef Py_LIMITED_API +#define PY_ITERSEARCH_COUNT 1 +#define PY_ITERSEARCH_INDEX 2 +#define PY_ITERSEARCH_CONTAINS 3 + +/* Iterate over seq. + + Result depends on the operation: + + PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if + error. + PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of + obj in seq; set ValueError and return -1 if none found; + also return -1 on error. + PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on + error. */ +PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, + PyObject *obj, int operation); +#endif + + +/* For DLL-level backwards compatibility */ +#undef PySequence_In +/* Determine if the sequence 'o' contains 'value'. If an item in 'o' is equal + to 'value', return 1, otherwise return 0. On error, return -1. + + This is equivalent to the Python expression: value in o. */ +PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value); + +/* For source-level backwards compatibility */ +#define PySequence_In PySequence_Contains + + +/* Return the first index for which o[i] == value. + On error, return -1. + + This is equivalent to the Python expression: o.index(value). */ +PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value); + + +/* --- In-place versions of some of the above Sequence functions --- */ + +/* Append sequence 'o2' to sequence 'o1', in-place when possible. Return the + resulting object, which could be 'o1', or NULL on failure. + + This is the equivalent of the Python expression: o1 += o2. */ +PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2); + +/* Repeat sequence 'o' by 'count', in-place when possible. Return the resulting + object, which could be 'o', or NULL on failure. + + This is the equivalent of the Python expression: o1 *= count. */ +PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count); + + +/* === Mapping protocol ================================================= */ + +/* Return 1 if the object provides mapping protocol, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyMapping_Check(PyObject *o); + +/* Returns the number of keys in mapping object 'o' on success, and -1 on + failure. This is equivalent to the Python expression: len(o). */ +PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o); + +/* For DLL compatibility */ +#undef PyMapping_Length +PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); +#define PyMapping_Length PyMapping_Size + + +/* Implemented as a macro: + + int PyMapping_DelItemString(PyObject *o, const char *key); + + Remove the mapping for the string 'key' from the mapping 'o'. Returns -1 on + failure. + + This is equivalent to the Python statement: del o[key]. */ +#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) + +/* Implemented as a macro: + + int PyMapping_DelItem(PyObject *o, PyObject *key); + + Remove the mapping for the object 'key' from the mapping object 'o'. + Returns -1 on failure. + + This is equivalent to the Python statement: del o[key]. */ +#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) + +/* On success, return 1 if the mapping object 'o' has the key 'key', + and 0 otherwise. + + This is equivalent to the Python expression: key in o. + + This function always succeeds. */ +PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, const char *key); + +/* Return 1 if the mapping object has the key 'key', and 0 otherwise. + + This is equivalent to the Python expression: key in o. + + This function always succeeds. */ +PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key); + +/* On success, return a list or tuple of the keys in mapping object 'o'. + On failure, return NULL. */ +PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o); + +/* On success, return a list or tuple of the values in mapping object 'o'. + On failure, return NULL. */ +PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o); + +/* On success, return a list or tuple of the items in mapping object 'o', + where each item is a tuple containing a key-value pair. On failure, return + NULL. */ +PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o); + +/* Return element of 'o' corresponding to the string 'key' or NULL on failure. + + This is the equivalent of the Python expression: o[key]. */ +PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o, + const char *key); + +/* Map the string 'key' to the value 'v' in the mapping 'o'. + Returns -1 on failure. + + This is the equivalent of the Python statement: o[key]=v. */ +PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, const char *key, + PyObject *value); + +/* isinstance(object, typeorclass) */ +PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass); + +/* issubclass(object, typeorclass) */ +PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass); + + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); + +PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); + +PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self); + +PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]); + +/* For internal use by buffer API functions */ +PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); +PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); + +/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ +PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); +#endif /* !Py_LIMITED_API */ + + +#ifdef __cplusplus +} +#endif +#endif /* Py_ABSTRACTOBJECT_H */ diff --git a/Include/accu.h b/Include/accu.h new file mode 100644 index 0000000..3636ea6 --- /dev/null +++ b/Include/accu.h @@ -0,0 +1,37 @@ +#ifndef Py_LIMITED_API +#ifndef Py_ACCU_H +#define Py_ACCU_H + +/*** This is a private API for use by the interpreter and the stdlib. + *** Its definition may be changed or removed at any moment. + ***/ + +/* + * A two-level accumulator of unicode objects that avoids both the overhead + * of keeping a huge number of small separate objects, and the quadratic + * behaviour of using a naive repeated concatenation scheme. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#undef small /* defined by some Windows headers */ + +typedef struct { + PyObject *large; /* A list of previously accumulated large strings */ + PyObject *small; /* Pending small strings */ +} _PyAccu; + +PyAPI_FUNC(int) _PyAccu_Init(_PyAccu *acc); +PyAPI_FUNC(int) _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode); +PyAPI_FUNC(PyObject *) _PyAccu_FinishAsList(_PyAccu *acc); +PyAPI_FUNC(PyObject *) _PyAccu_Finish(_PyAccu *acc); +PyAPI_FUNC(void) _PyAccu_Destroy(_PyAccu *acc); + +#ifdef __cplusplus +} +#endif + +#endif /* Py_ACCU_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/asdl.h b/Include/asdl.h new file mode 100644 index 0000000..35e9fa1 --- /dev/null +++ b/Include/asdl.h @@ -0,0 +1,46 @@ +#ifndef Py_ASDL_H +#define Py_ASDL_H + +typedef PyObject * identifier; +typedef PyObject * string; +typedef PyObject * bytes; +typedef PyObject * object; +typedef PyObject * singleton; +typedef PyObject * constant; + +/* It would be nice if the code generated by asdl_c.py was completely + independent of Python, but it is a goal the requires too much work + at this stage. So, for example, I'll represent identifiers as + interned Python strings. +*/ + +/* XXX A sequence should be typed so that its use can be typechecked. */ + +typedef struct { + Py_ssize_t size; + void *elements[1]; +} asdl_seq; + +typedef struct { + Py_ssize_t size; + int elements[1]; +} asdl_int_seq; + +asdl_seq *_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena); +asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena); + +#define asdl_seq_GET(S, I) (S)->elements[(I)] +#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) +#ifdef Py_DEBUG +#define asdl_seq_SET(S, I, V) \ + do { \ + Py_ssize_t _asdl_i = (I); \ + assert((S) != NULL); \ + assert(_asdl_i < (S)->size); \ + (S)->elements[_asdl_i] = (V); \ + } while (0) +#else +#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V) +#endif + +#endif /* !Py_ASDL_H */ diff --git a/Include/ast.h b/Include/ast.h new file mode 100644 index 0000000..5bc2b05 --- /dev/null +++ b/Include/ast.h @@ -0,0 +1,29 @@ +#ifndef Py_AST_H +#define Py_AST_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyAST_Validate(mod_ty); +PyAPI_FUNC(mod_ty) PyAST_FromNode( + const node *n, + PyCompilerFlags *flags, + const char *filename, /* decoded from the filesystem encoding */ + PyArena *arena); +PyAPI_FUNC(mod_ty) PyAST_FromNodeObject( + const node *n, + PyCompilerFlags *flags, + PyObject *filename, + PyArena *arena); + +#ifndef Py_LIMITED_API + +/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */ +PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(expr_ty); + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_AST_H */ diff --git a/Include/bitset.h b/Include/bitset.h new file mode 100644 index 0000000..b22fa77 --- /dev/null +++ b/Include/bitset.h @@ -0,0 +1,32 @@ + +#ifndef Py_BITSET_H +#define Py_BITSET_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Bitset interface */ + +#define BYTE char + +typedef BYTE *bitset; + +bitset newbitset(int nbits); +void delbitset(bitset bs); +#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0) +int addbit(bitset bs, int ibit); /* Returns 0 if already set */ +int samebitset(bitset bs1, bitset bs2, int nbits); +void mergebitset(bitset bs1, bitset bs2, int nbits); + +#define BITSPERBYTE (8*sizeof(BYTE)) +#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE) + +#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE) +#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE) +#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit)) +#define BYTE2BIT(ibyte) ((ibyte) * BITSPERBYTE) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BITSET_H */ diff --git a/Include/bltinmodule.h b/Include/bltinmodule.h new file mode 100644 index 0000000..868c9e6 --- /dev/null +++ b/Include/bltinmodule.h @@ -0,0 +1,14 @@ +#ifndef Py_BLTINMODULE_H +#define Py_BLTINMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyFilter_Type; +PyAPI_DATA(PyTypeObject) PyMap_Type; +PyAPI_DATA(PyTypeObject) PyZip_Type; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BLTINMODULE_H */ diff --git a/Include/boolobject.h b/Include/boolobject.h new file mode 100644 index 0000000..7cc2f1f --- /dev/null +++ b/Include/boolobject.h @@ -0,0 +1,34 @@ +/* Boolean object interface */ + +#ifndef Py_BOOLOBJECT_H +#define Py_BOOLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_DATA(PyTypeObject) PyBool_Type; + +#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) + +/* Py_False and Py_True are the only two bools in existence. +Don't forget to apply Py_INCREF() when returning either!!! */ + +/* Don't use these directly */ +PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct; + +/* Use these macros */ +#define Py_False ((PyObject *) &_Py_FalseStruct) +#define Py_True ((PyObject *) &_Py_TrueStruct) + +/* Macros for returning Py_True or Py_False, respectively */ +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False + +/* Function to return a bool from a C long */ +PyAPI_FUNC(PyObject *) PyBool_FromLong(long); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BOOLOBJECT_H */ diff --git a/Include/bytearrayobject.h b/Include/bytearrayobject.h new file mode 100644 index 0000000..a757b88 --- /dev/null +++ b/Include/bytearrayobject.h @@ -0,0 +1,62 @@ +/* ByteArray object interface */ + +#ifndef Py_BYTEARRAYOBJECT_H +#define Py_BYTEARRAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Type PyByteArrayObject represents a mutable array of bytes. + * The Python API is that of a sequence; + * the bytes are mapped to ints in [0, 256). + * Bytes are not characters; they may be used to encode characters. + * The only way to go between bytes and str/unicode is via encoding + * and decoding. + * For the convenience of C programmers, the bytes type is considered + * to contain a char pointer, not an unsigned char pointer. + */ + +/* Object layout */ +#ifndef Py_LIMITED_API +typedef struct { + PyObject_VAR_HEAD + Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */ + char *ob_bytes; /* Physical backing buffer */ + char *ob_start; /* Logical start inside ob_bytes */ + /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */ + int ob_exports; /* How many buffer exports */ +} PyByteArrayObject; +#endif + +/* Type object */ +PyAPI_DATA(PyTypeObject) PyByteArray_Type; +PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; + +/* Type check macros */ +#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) +#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) + +/* Direct API functions */ +PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *); +PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); +PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); + +/* Macros, trading safety for speed */ +#ifndef Py_LIMITED_API +#define PyByteArray_AS_STRING(self) \ + (assert(PyByteArray_Check(self)), \ + Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string) +#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self)) + +PyAPI_DATA(char) _PyByteArray_empty_string[]; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BYTEARRAYOBJECT_H */ diff --git a/Include/bytes_methods.h b/Include/bytes_methods.h new file mode 100644 index 0000000..8434a50 --- /dev/null +++ b/Include/bytes_methods.h @@ -0,0 +1,69 @@ +#ifndef Py_LIMITED_API +#ifndef Py_BYTES_CTYPE_H +#define Py_BYTES_CTYPE_H + +/* + * The internal implementation behind PyBytes (bytes) and PyByteArray (bytearray) + * methods of the given names, they operate on ASCII byte strings. + */ +extern PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isascii(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len); + +/* These store their len sized answer in the given preallocated *result arg. */ +extern void _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len); +extern void _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len); +extern void _Py_bytes_title(char *result, const char *s, Py_ssize_t len); +extern void _Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len); +extern void _Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len); + +extern PyObject *_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args); +extern int _Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg); +extern PyObject *_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args); + +/* The maketrans() static method. */ +extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to); + +/* Shared __doc__ strings. */ +extern const char _Py_isspace__doc__[]; +extern const char _Py_isalpha__doc__[]; +extern const char _Py_isalnum__doc__[]; +extern const char _Py_isascii__doc__[]; +extern const char _Py_isdigit__doc__[]; +extern const char _Py_islower__doc__[]; +extern const char _Py_isupper__doc__[]; +extern const char _Py_istitle__doc__[]; +extern const char _Py_lower__doc__[]; +extern const char _Py_upper__doc__[]; +extern const char _Py_title__doc__[]; +extern const char _Py_capitalize__doc__[]; +extern const char _Py_swapcase__doc__[]; +extern const char _Py_count__doc__[]; +extern const char _Py_find__doc__[]; +extern const char _Py_index__doc__[]; +extern const char _Py_rfind__doc__[]; +extern const char _Py_rindex__doc__[]; +extern const char _Py_startswith__doc__[]; +extern const char _Py_endswith__doc__[]; +extern const char _Py_maketrans__doc__[]; +extern const char _Py_expandtabs__doc__[]; +extern const char _Py_ljust__doc__[]; +extern const char _Py_rjust__doc__[]; +extern const char _Py_center__doc__[]; +extern const char _Py_zfill__doc__[]; + +/* this is needed because some docs are shared from the .o, not static */ +#define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str) + +#endif /* !Py_BYTES_CTYPE_H */ +#endif /* !Py_LIMITED_API */ diff --git a/Include/bytesobject.h b/Include/bytesobject.h new file mode 100644 index 0000000..3fde4a2 --- /dev/null +++ b/Include/bytesobject.h @@ -0,0 +1,224 @@ + +/* Bytes (String) object interface */ + +#ifndef Py_BYTESOBJECT_H +#define Py_BYTESOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* +Type PyBytesObject represents a character string. An extra zero byte is +reserved at the end to ensure it is zero-terminated, but a size is +present so strings with null bytes in them can be represented. This +is an immutable object type. + +There are functions to create new string objects, to test +an object for string-ness, and to get the +string value. The latter function returns a null pointer +if the object is not of the proper type. +There is a variant that takes an explicit size as well as a +variant that assumes a zero-terminated string. Note that none of the +functions should be applied to nil objects. +*/ + +/* Caching the hash (ob_shash) saves recalculation of a string's hash value. + This significantly speeds up dict lookups. */ + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_VAR_HEAD + Py_hash_t ob_shash; + char ob_sval[1]; + + /* Invariants: + * ob_sval contains space for 'ob_size+1' elements. + * ob_sval[ob_size] == 0. + * ob_shash is the hash of the string or -1 if not computed yet. + */ +} PyBytesObject; +#endif + +PyAPI_DATA(PyTypeObject) PyBytes_Type; +PyAPI_DATA(PyTypeObject) PyBytesIter_Type; + +#define PyBytes_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) +#define PyBytes_CheckExact(op) (Py_TYPE(op) == &PyBytes_Type) + +PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); +PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *); +PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list) + Py_GCC_ATTRIBUTE((format(printf, 1, 0))); +PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *); +PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); +PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); +PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *); +PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject*) _PyBytes_FormatEx( + const char *format, + Py_ssize_t format_len, + PyObject *args, + int use_bytearray); +PyAPI_FUNC(PyObject*) _PyBytes_FromHex( + PyObject *string, + int use_bytearray); +#endif +PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, Py_ssize_t, + const char *); +#ifndef Py_LIMITED_API +/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ +PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, Py_ssize_t, + const char *, + const char **); +#endif + +/* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API +#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \ + (((PyBytesObject *)(op))->ob_sval)) +#define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op)) +#endif + +/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, + x must be an iterable object. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); +#endif + +/* Provides access to the internal data buffer and size of a string + object or the default encoded version of a Unicode object. Passing + NULL as *len parameter will force the string buffer to be + 0-terminated (passing a string with embedded NULL characters will + cause an exception). */ +PyAPI_FUNC(int) PyBytes_AsStringAndSize( + PyObject *obj, /* string or Unicode object */ + char **s, /* pointer to buffer variable */ + Py_ssize_t *len /* pointer to length variable or NULL + (only possible for 0-terminated + strings) */ + ); + +/* Using the current locale, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGroupingLocale(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width); + +/* Using explicit passed-in values, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); +#endif + +/* Flags used by string formatting */ +#define F_LJUST (1<<0) +#define F_SIGN (1<<1) +#define F_BLANK (1<<2) +#define F_ALT (1<<3) +#define F_ZERO (1<<4) + +#ifndef Py_LIMITED_API +/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer". + A _PyBytesWriter variable must be declared at the end of variables in a + function to optimize the memory allocation on the stack. */ +typedef struct { + /* bytes, bytearray or NULL (when the small buffer is used) */ + PyObject *buffer; + + /* Number of allocated size. */ + Py_ssize_t allocated; + + /* Minimum number of allocated bytes, + incremented by _PyBytesWriter_Prepare() */ + Py_ssize_t min_size; + + /* If non-zero, use a bytearray instead of a bytes object for buffer. */ + int use_bytearray; + + /* If non-zero, overallocate the buffer (default: 0). + This flag must be zero if use_bytearray is non-zero. */ + int overallocate; + + /* Stack buffer */ + int use_small_buffer; + char small_buffer[512]; +} _PyBytesWriter; + +/* Initialize a bytes writer + + By default, the overallocation is disabled. Set the overallocate attribute + to control the allocation of the buffer. */ +PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer); + +/* Get the buffer content and reset the writer. + Return a bytes object, or a bytearray object if use_bytearray is non-zero. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer, + void *str); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer); + +/* Allocate the buffer to write size bytes. + Return the pointer to the beginning of buffer data. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer, + Py_ssize_t size); + +/* Ensure that the buffer is large enough to write *size* bytes. + Add size to the writer minimum size (min_size attribute). + + str is the current pointer inside the buffer. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Resize the buffer to make it larger. + The new buffer may be larger than size bytes because of overallocation. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. + + Note: size must be greater than the number of allocated bytes in the writer. + + This function doesn't use the writer minimum size (min_size attribute). + + See also _PyBytesWriter_Prepare(). + */ +PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Write bytes. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, + void *str, + const void *bytes, + Py_ssize_t size); +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BYTESOBJECT_H */ diff --git a/Include/cellobject.h b/Include/cellobject.h new file mode 100644 index 0000000..2f9b5b7 --- /dev/null +++ b/Include/cellobject.h @@ -0,0 +1,29 @@ +/* Cell object interface */ +#ifndef Py_LIMITED_API +#ifndef Py_CELLOBJECT_H +#define Py_CELLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *ob_ref; /* Content of the cell or NULL when empty */ +} PyCellObject; + +PyAPI_DATA(PyTypeObject) PyCell_Type; + +#define PyCell_Check(op) (Py_TYPE(op) == &PyCell_Type) + +PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); +PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); +PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); + +#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref) +#define PyCell_SET(op, v) (((PyCellObject *)(op))->ob_ref = v) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/ceval.h b/Include/ceval.h new file mode 100644 index 0000000..bce8a0b --- /dev/null +++ b/Include/ceval.h @@ -0,0 +1,237 @@ +#ifndef Py_CEVAL_H +#define Py_CEVAL_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to random parts in ceval.c */ + +/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction + * and PyEval_CallMethod are kept for backward compatibility: PyObject_Call(), + * PyObject_CallFunction() and PyObject_CallMethod() are recommended to call + * a callable object. + */ + +PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( + PyObject *callable, + PyObject *args, + PyObject *kwargs); + +/* Inline this */ +#define PyEval_CallObject(callable, arg) \ + PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL) + +PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *callable, + const char *format, ...); +PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, + const char *name, + const char *format, ...); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth(int new_depth); +PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); +PyAPI_FUNC(void) _PyEval_SetCoroutineWrapper(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetCoroutineWrapper(void); +PyAPI_FUNC(void) _PyEval_SetAsyncGenFirstiter(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); +PyAPI_FUNC(void) _PyEval_SetAsyncGenFinalizer(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void); +#endif + +struct _frame; /* Avoid including frameobject.h */ + +PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); +PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); +PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); +PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); + +/* Look at the current frame's (if any) code's co_flags, and turn on + the corresponding compiler flags in cf->cf_flags. Return 1 if any + flag was set, else return 0. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); +#endif + +PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); +PyAPI_FUNC(void) _PyEval_SignalReceived(void); +PyAPI_FUNC(int) Py_MakePendingCalls(void); + +/* Protection against deeply nested recursive calls + + In Python 3.0, this protection has two levels: + * normal anti-recursion protection is triggered when the recursion level + exceeds the current recursion limit. It raises a RecursionError, and sets + the "overflowed" flag in the thread state structure. This flag + temporarily *disables* the normal protection; this allows cleanup code + to potentially outgrow the recursion limit while processing the + RecursionError. + * "last chance" anti-recursion protection is triggered when the recursion + level exceeds "current recursion limit + 50". By construction, this + protection can only be triggered when the "overflowed" flag is set. It + means the cleanup code has itself gone into an infinite loop, or the + RecursionError has been mistakingly ignored. When this protection is + triggered, the interpreter aborts with a Fatal Error. + + In addition, the "overflowed" flag is automatically reset when the + recursion level drops below "current recursion limit - 50". This heuristic + is meant to ensure that the normal anti-recursion protection doesn't get + disabled too long. + + Please note: this scheme has its own limitations. See: + http://mail.python.org/pipermail/python-dev/2008-August/082106.html + for some observations. +*/ +PyAPI_FUNC(void) Py_SetRecursionLimit(int); +PyAPI_FUNC(int) Py_GetRecursionLimit(void); + +#define Py_EnterRecursiveCall(where) \ + (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ + _Py_CheckRecursiveCall(where)) +#define Py_LeaveRecursiveCall() \ + do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ + PyThreadState_GET()->overflowed = 0; \ + } while(0) +PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); + +/* Due to the macros in which it's used, _Py_CheckRecursionLimit is in + the stable ABI. It should be removed therefrom when possible. +*/ +PyAPI_DATA(int) _Py_CheckRecursionLimit; + +#ifdef USE_STACKCHECK +/* With USE_STACKCHECK, trigger stack checks in _Py_CheckRecursiveCall() + on every 64th call to Py_EnterRecursiveCall. +*/ +# define _Py_MakeRecCheck(x) \ + (++(x) > _Py_CheckRecursionLimit || \ + ++(PyThreadState_GET()->stackcheck_counter) > 64) +#else +# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) +#endif + +/* Compute the "lower-water mark" for a recursion limit. When + * Py_LeaveRecursiveCall() is called with a recursion depth below this mark, + * the overflowed flag is reset to 0. */ +#define _Py_RecursionLimitLowerWaterMark(limit) \ + (((limit) > 200) \ + ? ((limit) - 50) \ + : (3 * ((limit) >> 2))) + +#define _Py_MakeEndRecCheck(x) \ + (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) + +#define Py_ALLOW_RECURSION \ + do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ + PyThreadState_GET()->recursion_critical = 1; + +#define Py_END_ALLOW_RECURSION \ + PyThreadState_GET()->recursion_critical = _old; \ + } while(0); + +PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); +PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); +PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(struct _frame *f, int exc); +#endif + +/* Interface for threads. + + A module that plans to do a blocking system call (or something else + that lasts a long time and doesn't touch Python data) can allow other + threads to run as follows: + + ...preparations here... + Py_BEGIN_ALLOW_THREADS + ...blocking system call here... + Py_END_ALLOW_THREADS + ...interpret result here... + + The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a + {}-surrounded block. + To leave the block in the middle (e.g., with return), you must insert + a line containing Py_BLOCK_THREADS before the return, e.g. + + if (...premature_exit...) { + Py_BLOCK_THREADS + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + An alternative is: + + Py_BLOCK_THREADS + if (...premature_exit...) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_UNBLOCK_THREADS + + For convenience, that the value of 'errno' is restored across + Py_END_ALLOW_THREADS and Py_BLOCK_THREADS. + + WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND + Py_END_ALLOW_THREADS!!! + + The function PyEval_InitThreads() should be called only from + init_thread() in "_threadmodule.c". + + Note that not yet all candidates have been converted to use this + mechanism! +*/ + +PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); +PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); + +PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); +PyAPI_FUNC(void) PyEval_InitThreads(void); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyEval_FiniThreads(void); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(void) PyEval_AcquireLock(void) Py_DEPRECATED(3.2); +PyAPI_FUNC(void) PyEval_ReleaseLock(void) /* Py_DEPRECATED(3.2) */; +PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); +PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); +PyAPI_FUNC(void) PyEval_ReInitThreads(void); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); +PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); +#endif + +#define Py_BEGIN_ALLOW_THREADS { \ + PyThreadState *_save; \ + _save = PyEval_SaveThread(); +#define Py_BLOCK_THREADS PyEval_RestoreThread(_save); +#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); +#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ + } + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); +PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void); +#endif + +/* Masks and values used by FORMAT_VALUE opcode. */ +#define FVC_MASK 0x3 +#define FVC_NONE 0x0 +#define FVC_STR 0x1 +#define FVC_REPR 0x2 +#define FVC_ASCII 0x3 +#define FVS_MASK 0x4 +#define FVS_HAVE_SPEC 0x4 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CEVAL_H */ diff --git a/Include/classobject.h b/Include/classobject.h new file mode 100644 index 0000000..209f0f4 --- /dev/null +++ b/Include/classobject.h @@ -0,0 +1,58 @@ +/* Former class object interface -- now only bound methods are here */ + +/* Revealing some structures (not for general use) */ + +#ifndef Py_LIMITED_API +#ifndef Py_CLASSOBJECT_H +#define Py_CLASSOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *im_func; /* The callable object implementing the method */ + PyObject *im_self; /* The instance it is bound to */ + PyObject *im_weakreflist; /* List of weak references */ +} PyMethodObject; + +PyAPI_DATA(PyTypeObject) PyMethod_Type; + +#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type) + +PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyMethod_GET_FUNCTION(meth) \ + (((PyMethodObject *)meth) -> im_func) +#define PyMethod_GET_SELF(meth) \ + (((PyMethodObject *)meth) -> im_self) + +PyAPI_FUNC(int) PyMethod_ClearFreeList(void); + +typedef struct { + PyObject_HEAD + PyObject *func; +} PyInstanceMethodObject; + +PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; + +#define PyInstanceMethod_Check(op) ((op)->ob_type == &PyInstanceMethod_Type) + +PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyInstanceMethod_GET_FUNCTION(meth) \ + (((PyInstanceMethodObject *)meth) -> func) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CLASSOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/code.h b/Include/code.h new file mode 100644 index 0000000..2e661e8 --- /dev/null +++ b/Include/code.h @@ -0,0 +1,157 @@ +/* Definitions for bytecode */ + +#ifndef Py_LIMITED_API +#ifndef Py_CODE_H +#define Py_CODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint16_t _Py_CODEUNIT; + +#ifdef WORDS_BIGENDIAN +# define _Py_OPCODE(word) ((word) >> 8) +# define _Py_OPARG(word) ((word) & 255) +#else +# define _Py_OPCODE(word) ((word) & 255) +# define _Py_OPARG(word) ((word) >> 8) +#endif + +/* Bytecode object */ +typedef struct { + PyObject_HEAD + int co_argcount; /* #arguments, except *args */ + int co_kwonlyargcount; /* #keyword only arguments */ + int co_nlocals; /* #local variables */ + int co_stacksize; /* #entries needed for evaluation stack */ + int co_flags; /* CO_..., see below */ + int co_firstlineno; /* first source line number */ + PyObject *co_code; /* instruction opcodes */ + PyObject *co_consts; /* list (constants used) */ + PyObject *co_names; /* list of strings (names used) */ + PyObject *co_varnames; /* tuple of strings (local variable names) */ + PyObject *co_freevars; /* tuple of strings (free variable names) */ + PyObject *co_cellvars; /* tuple of strings (cell variable names) */ + /* The rest aren't used in either hash or comparisons, except for co_name, + used in both. This is done to preserve the name and line number + for tracebacks and debuggers; otherwise, constant de-duplication + would collapse identical functions/lambdas defined on different lines. + */ + Py_ssize_t *co_cell2arg; /* Maps cell vars which are arguments. */ + PyObject *co_filename; /* unicode (where it was loaded from) */ + PyObject *co_name; /* unicode (name, for reference) */ + PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See + Objects/lnotab_notes.txt for details. */ + void *co_zombieframe; /* for optimization only (see frameobject.c) */ + PyObject *co_weakreflist; /* to support weakrefs to code objects */ + /* Scratch space for extra data relating to the code object. + Type is a void* to keep the format private in codeobject.c to force + people to go through the proper APIs. */ + void *co_extra; +} PyCodeObject; + +/* Masks for co_flags above */ +#define CO_OPTIMIZED 0x0001 +#define CO_NEWLOCALS 0x0002 +#define CO_VARARGS 0x0004 +#define CO_VARKEYWORDS 0x0008 +#define CO_NESTED 0x0010 +#define CO_GENERATOR 0x0020 +/* The CO_NOFREE flag is set if there are no free or cell variables. + This information is redundant, but it allows a single flag test + to determine whether there is any extra work to be done when the + call frame it setup. +*/ +#define CO_NOFREE 0x0040 + +/* The CO_COROUTINE flag is set for coroutine functions (defined with + ``async def`` keywords) */ +#define CO_COROUTINE 0x0080 +#define CO_ITERABLE_COROUTINE 0x0100 +#define CO_ASYNC_GENERATOR 0x0200 + +/* These are no longer used. */ +#if 0 +#define CO_GENERATOR_ALLOWED 0x1000 +#endif +#define CO_FUTURE_DIVISION 0x2000 +#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */ +#define CO_FUTURE_WITH_STATEMENT 0x8000 +#define CO_FUTURE_PRINT_FUNCTION 0x10000 +#define CO_FUTURE_UNICODE_LITERALS 0x20000 + +#define CO_FUTURE_BARRY_AS_BDFL 0x40000 +#define CO_FUTURE_GENERATOR_STOP 0x80000 +#define CO_FUTURE_ANNOTATIONS 0x100000 + +/* This value is found in the co_cell2arg array when the associated cell + variable does not correspond to an argument. */ +#define CO_CELL_NOT_AN_ARG (-1) + +/* This should be defined if a future statement modifies the syntax. + For example, when a keyword is added. +*/ +#define PY_PARSER_REQUIRES_FUTURE_KEYWORD + +#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ + +PyAPI_DATA(PyTypeObject) PyCode_Type; + +#define PyCode_Check(op) (Py_TYPE(op) == &PyCode_Type) +#define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars)) + +/* Public interface */ +PyAPI_FUNC(PyCodeObject *) PyCode_New( + int, int, int, int, int, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, PyObject *, + PyObject *, PyObject *, int, PyObject *); + /* same as struct above */ + +/* Creates a new empty code object with the specified source location. */ +PyAPI_FUNC(PyCodeObject *) +PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno); + +/* Return the line number associated with the specified bytecode index + in this code object. If you just need the line number of a frame, + use PyFrame_GetLineNumber() instead. */ +PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); + +/* for internal use only */ +typedef struct _addr_pair { + int ap_lower; + int ap_upper; +} PyAddrPair; + +#ifndef Py_LIMITED_API +/* Update *bounds to describe the first and one-past-the-last instructions in the + same line as lasti. Return the number of that line. +*/ +PyAPI_FUNC(int) _PyCode_CheckLineNumber(PyCodeObject* co, + int lasti, PyAddrPair *bounds); + +/* Create a comparable key used to compare constants taking in account the + * object type. It is used to make sure types are not coerced (e.g., float and + * complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms + * + * Return (type(obj), obj, ...): a tuple with variable size (at least 2 items) + * depending on the type and the value. The type is the first item to not + * compare bytes and str which can raise a BytesWarning exception. */ +PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj); +#endif + +PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, + PyObject *names, PyObject *lnotab); + + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index, + void **extra); +PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, + void *extra); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODE_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/codecs.h b/Include/codecs.h new file mode 100644 index 0000000..3ad0f2b --- /dev/null +++ b/Include/codecs.h @@ -0,0 +1,240 @@ +#ifndef Py_CODECREGISTRY_H +#define Py_CODECREGISTRY_H +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------------ + + Python Codec Registry and support functions + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +Copyright (c) Corporation for National Research Initiatives. + + ------------------------------------------------------------------------ */ + +/* Register a new codec search function. + + As side effect, this tries to load the encodings package, if not + yet done, to make sure that it is always first in the list of + search functions. + + The search_function's refcount is incremented by this function. */ + +PyAPI_FUNC(int) PyCodec_Register( + PyObject *search_function + ); + +/* Codec registry lookup API. + + Looks up the given encoding and returns a CodecInfo object with + function attributes which implement the different aspects of + processing the encoding. + + The encoding string is looked up converted to all lower-case + characters. This makes encodings looked up through this mechanism + effectively case-insensitive. + + If no codec is found, a KeyError is set and NULL returned. + + As side effect, this tries to load the encodings package, if not + yet done. This is part of the lazy load strategy for the encodings + package. + + */ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyCodec_Lookup( + const char *encoding + ); + +PyAPI_FUNC(int) _PyCodec_Forget( + const char *encoding + ); +#endif + +/* Codec registry encoding check API. + + Returns 1/0 depending on whether there is a registered codec for + the given encoding. + +*/ + +PyAPI_FUNC(int) PyCodec_KnownEncoding( + const char *encoding + ); + +/* Generic codec based encoding API. + + object is passed through the encoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Encode( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* Generic codec based decoding API. + + object is passed through the decoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Decode( + PyObject *object, + const char *encoding, + const char *errors + ); + +#ifndef Py_LIMITED_API +/* Text codec specific encoding and decoding API. + + Checks the encoding against a list of codecs which do not + implement a str<->bytes encoding before attempting the + operation. + + Please note that these APIs are internal and should not + be used in Python C extensions. + + XXX (ncoghlan): should we make these, or something like them, public + in Python 3.5+? + + */ +PyAPI_FUNC(PyObject *) _PyCodec_LookupTextEncoding( + const char *encoding, + const char *alternate_command + ); + +PyAPI_FUNC(PyObject *) _PyCodec_EncodeText( + PyObject *object, + const char *encoding, + const char *errors + ); + +PyAPI_FUNC(PyObject *) _PyCodec_DecodeText( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* These two aren't actually text encoding specific, but _io.TextIOWrapper + * is the only current API consumer. + */ +PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalDecoder( + PyObject *codec_info, + const char *errors + ); + +PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalEncoder( + PyObject *codec_info, + const char *errors + ); +#endif + + + +/* --- Codec Lookup APIs -------------------------------------------------- + + All APIs return a codec object with incremented refcount and are + based on _PyCodec_Lookup(). The same comments w/r to the encoding + name also apply to these APIs. + +*/ + +/* Get an encoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Encoder( + const char *encoding + ); + +/* Get a decoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Decoder( + const char *encoding + ); + +/* Get an IncrementalEncoder object for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( + const char *encoding, + const char *errors + ); + +/* Get an IncrementalDecoder object function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( + const char *encoding, + const char *errors + ); + +/* Get a StreamReader factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamReader( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Get a StreamWriter factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamWriter( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Unicode encoding error handling callback registry API */ + +/* Register the error handling callback function error under the given + name. This function will be called by the codec when it encounters + unencodable characters/undecodable bytes and doesn't know the + callback name, when name is specified as the error parameter + in the call to the encode/decode function. + Return 0 on success, -1 on error */ +PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error); + +/* Lookup the error handling callback function registered under the given + name. As a special case NULL can be passed, in which case + the error handling callback for "strict" will be returned. */ +PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name); + +/* raise exc as an exception */ +PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc); + +/* ignore the unicode error, skipping the faulty input */ +PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc); + +/* replace the unicode encode error with ? or U+FFFD */ +PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with XML character references */ +PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with backslash escapes (\x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc); +#endif + +#ifndef Py_LIMITED_API +PyAPI_DATA(const char *) Py_hexdigits; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODECREGISTRY_H */ diff --git a/Include/compile.h b/Include/compile.h new file mode 100644 index 0000000..edb961f --- /dev/null +++ b/Include/compile.h @@ -0,0 +1,93 @@ +#ifndef Py_COMPILE_H +#define Py_COMPILE_H + +#ifndef Py_LIMITED_API +#include "code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public interface */ +struct _node; /* Declare the existence of this type */ +PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); +/* XXX (ncoghlan): Unprefixed type name in a public API! */ + +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ + CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ + CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) +#define PyCF_MASK_OBSOLETE (CO_NESTED) +#define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 +#define PyCF_IGNORE_COOKIE 0x0800 + +#ifndef Py_LIMITED_API +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ +} PyCompilerFlags; +#endif + +/* Future feature support */ + +typedef struct { + int ff_features; /* flags set by future statements */ + int ff_lineno; /* line number of last future statement */ +} PyFutureFeatures; + +#define FUTURE_NESTED_SCOPES "nested_scopes" +#define FUTURE_GENERATORS "generators" +#define FUTURE_DIVISION "division" +#define FUTURE_ABSOLUTE_IMPORT "absolute_import" +#define FUTURE_WITH_STATEMENT "with_statement" +#define FUTURE_PRINT_FUNCTION "print_function" +#define FUTURE_UNICODE_LITERALS "unicode_literals" +#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" +#define FUTURE_GENERATOR_STOP "generator_stop" +#define FUTURE_ANNOTATIONS "annotations" + +struct _mod; /* Declare the existence of this type */ +#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar) +PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx( + struct _mod *mod, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags, + int optimize, + PyArena *arena); +PyAPI_FUNC(PyCodeObject *) PyAST_CompileObject( + struct _mod *mod, + PyObject *filename, + PyCompilerFlags *flags, + int optimize, + PyArena *arena); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST( + struct _mod * mod, + const char *filename /* decoded from the filesystem encoding */ + ); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromASTObject( + struct _mod * mod, + PyObject *filename + ); + +/* _Py_Mangle is defined in compile.c */ +PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); + +#define PY_INVALID_STACK_EFFECT INT_MAX +PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); + +PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, int optimize); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_LIMITED_API */ + +/* These definitions must match corresponding definitions in graminit.h. + There's code in compile.c that checks that they are the same. */ +#define Py_single_input 256 +#define Py_file_input 257 +#define Py_eval_input 258 + +#endif /* !Py_COMPILE_H */ diff --git a/Include/complexobject.h b/Include/complexobject.h new file mode 100644 index 0000000..cb8c52c --- /dev/null +++ b/Include/complexobject.h @@ -0,0 +1,69 @@ +/* Complex number structure */ + +#ifndef Py_COMPLEXOBJECT_H +#define Py_COMPLEXOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +typedef struct { + double real; + double imag; +} Py_complex; + +/* Operations on complex numbers from complexmodule.c */ + +PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); +PyAPI_FUNC(double) _Py_c_abs(Py_complex); +#endif + +/* Complex object interface */ + +/* +PyComplexObject represents a complex number with double-precision +real and imaginary parts. +*/ +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + Py_complex cval; +} PyComplexObject; +#endif + +PyAPI_DATA(PyTypeObject) PyComplex_Type; + +#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) +#define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type) + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); +#endif +PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); + +PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); +PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); +#endif + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyComplex_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COMPLEXOBJECT_H */ diff --git a/Include/context.h b/Include/context.h new file mode 100644 index 0000000..8b9f129 --- /dev/null +++ b/Include/context.h @@ -0,0 +1,86 @@ +#ifndef Py_CONTEXT_H +#define Py_CONTEXT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + + +PyAPI_DATA(PyTypeObject) PyContext_Type; +typedef struct _pycontextobject PyContext; + +PyAPI_DATA(PyTypeObject) PyContextVar_Type; +typedef struct _pycontextvarobject PyContextVar; + +PyAPI_DATA(PyTypeObject) PyContextToken_Type; +typedef struct _pycontexttokenobject PyContextToken; + + +#define PyContext_CheckExact(o) (Py_TYPE(o) == &PyContext_Type) +#define PyContextVar_CheckExact(o) (Py_TYPE(o) == &PyContextVar_Type) +#define PyContextToken_CheckExact(o) (Py_TYPE(o) == &PyContextToken_Type) + + +PyAPI_FUNC(PyContext *) PyContext_New(void); +PyAPI_FUNC(PyContext *) PyContext_Copy(PyContext *); +PyAPI_FUNC(PyContext *) PyContext_CopyCurrent(void); + +PyAPI_FUNC(int) PyContext_Enter(PyContext *); +PyAPI_FUNC(int) PyContext_Exit(PyContext *); + + +/* Create a new context variable. + + default_value can be NULL. +*/ +PyAPI_FUNC(PyContextVar *) PyContextVar_New( + const char *name, PyObject *default_value); + + +/* Get a value for the variable. + + Returns -1 if an error occurred during lookup. + + Returns 0 if value either was or was not found. + + If value was found, *value will point to it. + If not, it will point to: + + - default_value, if not NULL; + - the default value of "var", if not NULL; + - NULL. + + '*value' will be a new ref, if not NULL. +*/ +PyAPI_FUNC(int) PyContextVar_Get( + PyContextVar *var, PyObject *default_value, PyObject **value); + + +/* Set a new value for the variable. + Returns NULL if an error occurs. +*/ +PyAPI_FUNC(PyContextToken *) PyContextVar_Set( + PyContextVar *var, PyObject *value); + + +/* Reset a variable to its previous value. + Returns 0 on success, -1 on error. +*/ +PyAPI_FUNC(int) PyContextVar_Reset( + PyContextVar *var, PyContextToken *token); + + +/* This method is exposed only for CPython tests. Don not use it. */ +PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void); + + +PyAPI_FUNC(int) PyContext_ClearFreeList(void); + + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CONTEXT_H */ diff --git a/Include/datetime.h b/Include/datetime.h new file mode 100644 index 0000000..059d5ec --- /dev/null +++ b/Include/datetime.h @@ -0,0 +1,273 @@ +/* datetime.h + */ +#ifndef Py_LIMITED_API +#ifndef DATETIME_H +#define DATETIME_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Fields are packed into successive bytes, each viewed as unsigned and + * big-endian, unless otherwise noted: + * + * byte offset + * 0 year 2 bytes, 1-9999 + * 2 month 1 byte, 1-12 + * 3 day 1 byte, 1-31 + * 4 hour 1 byte, 0-23 + * 5 minute 1 byte, 0-59 + * 6 second 1 byte, 0-59 + * 7 usecond 3 bytes, 0-999999 + * 10 + */ + +/* # of bytes for year, month, and day. */ +#define _PyDateTime_DATE_DATASIZE 4 + +/* # of bytes for hour, minute, second, and usecond. */ +#define _PyDateTime_TIME_DATASIZE 6 + +/* # of bytes for year, month, day, hour, minute, second, and usecond. */ +#define _PyDateTime_DATETIME_DATASIZE 10 + + +typedef struct +{ + PyObject_HEAD + Py_hash_t hashcode; /* -1 when unknown */ + int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ + int seconds; /* 0 <= seconds < 24*3600 is invariant */ + int microseconds; /* 0 <= microseconds < 1000000 is invariant */ +} PyDateTime_Delta; + +typedef struct +{ + PyObject_HEAD /* a pure abstract base class */ +} PyDateTime_TZInfo; + + +/* The datetime and time types have hashcodes, and an optional tzinfo member, + * present if and only if hastzinfo is true. + */ +#define _PyTZINFO_HEAD \ + PyObject_HEAD \ + Py_hash_t hashcode; \ + char hastzinfo; /* boolean flag */ + +/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something + * convenient to cast to, when getting at the hastzinfo member of objects + * starting with _PyTZINFO_HEAD. + */ +typedef struct +{ + _PyTZINFO_HEAD +} _PyDateTime_BaseTZInfo; + +/* All time objects are of PyDateTime_TimeType, but that can be allocated + * in two ways, with or without a tzinfo member. Without is the same as + * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an + * internal struct used to allocate the right amount of space for the + * "without" case. + */ +#define _PyDateTime_TIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_TIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_TIMEHEAD +} _PyDateTime_BaseTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_TIMEHEAD + unsigned char fold; + PyObject *tzinfo; +} PyDateTime_Time; /* hastzinfo true */ + + +/* All datetime objects are of PyDateTime_DateTimeType, but that can be + * allocated in two ways too, just like for time objects above. In addition, + * the plain date type is a base class for datetime, so it must also have + * a hastzinfo member (although it's unused there). + */ +typedef struct +{ + _PyTZINFO_HEAD + unsigned char data[_PyDateTime_DATE_DATASIZE]; +} PyDateTime_Date; + +#define _PyDateTime_DATETIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_DATETIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_DATETIMEHEAD +} _PyDateTime_BaseDateTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_DATETIMEHEAD + unsigned char fold; + PyObject *tzinfo; +} PyDateTime_DateTime; /* hastzinfo true */ + + +/* Apply for date and datetime instances. */ +#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ + ((PyDateTime_Date*)o)->data[1]) +#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) +#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3]) + +#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4]) +#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) +#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6]) +#define PyDateTime_DATE_GET_MICROSECOND(o) \ + ((((PyDateTime_DateTime*)o)->data[7] << 16) | \ + (((PyDateTime_DateTime*)o)->data[8] << 8) | \ + ((PyDateTime_DateTime*)o)->data[9]) +#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold) + +/* Apply for time instances. */ +#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) +#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) +#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) +#define PyDateTime_TIME_GET_MICROSECOND(o) \ + ((((PyDateTime_Time*)o)->data[3] << 16) | \ + (((PyDateTime_Time*)o)->data[4] << 8) | \ + ((PyDateTime_Time*)o)->data[5]) +#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold) + +/* Apply for time delta instances */ +#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) +#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) +#define PyDateTime_DELTA_GET_MICROSECONDS(o) \ + (((PyDateTime_Delta*)o)->microseconds) + + +/* Define structure for C API. */ +typedef struct { + /* type objects */ + PyTypeObject *DateType; + PyTypeObject *DateTimeType; + PyTypeObject *TimeType; + PyTypeObject *DeltaType; + PyTypeObject *TZInfoType; + + /* singletons */ + PyObject *TimeZone_UTC; + + /* constructors */ + PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*); + PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, + PyObject*, PyTypeObject*); + PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); + PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + PyObject *(*TimeZone_FromTimeZone)(PyObject *offset, PyObject *name); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); + + /* PEP 495 constructors */ + PyObject *(*DateTime_FromDateAndTimeAndFold)(int, int, int, int, int, int, int, + PyObject*, int, PyTypeObject*); + PyObject *(*Time_FromTimeAndFold)(int, int, int, int, PyObject*, int, PyTypeObject*); + +} PyDateTime_CAPI; + +#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI" + + +#ifdef Py_BUILD_CORE + +/* Macros for type checking when building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) +#define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) +#define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) +#define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) +#define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) +#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType) + +#else + +/* Define global variable for the C API and a macro for setting it. */ +static PyDateTime_CAPI *PyDateTimeAPI = NULL; + +#define PyDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) + +/* Macro for access to the UTC singleton */ +#define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC + +/* Macros for type checking when not building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType) + +/* Macros for accessing constructors in a simplified fashion. */ +#define PyDate_FromDate(year, month, day) \ + PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) + +#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ + PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ + min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) + +#define PyDateTime_FromDateAndTimeAndFold(year, month, day, hour, min, sec, usec, fold) \ + PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, \ + min, sec, usec, Py_None, fold, PyDateTimeAPI->DateTimeType) + +#define PyTime_FromTime(hour, minute, second, usecond) \ + PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ + Py_None, PyDateTimeAPI->TimeType) + +#define PyTime_FromTimeAndFold(hour, minute, second, usecond, fold) \ + PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, usecond, \ + Py_None, fold, PyDateTimeAPI->TimeType) + +#define PyDelta_FromDSU(days, seconds, useconds) \ + PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ + PyDateTimeAPI->DeltaType) + +#define PyTimeZone_FromOffset(offset) \ + PyDateTimeAPI->TimeZone_FromTimeZone(offset, NULL) + +#define PyTimeZone_FromOffsetAndName(offset, name) \ + PyDateTimeAPI->TimeZone_FromTimeZone(offset, name) + +/* Macros supporting the DB API. */ +#define PyDateTime_FromTimestamp(args) \ + PyDateTimeAPI->DateTime_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) + +#define PyDate_FromTimestamp(args) \ + PyDateTimeAPI->Date_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateType), args) + +#endif /* Py_BUILD_CORE */ + +#ifdef __cplusplus +} +#endif +#endif +#endif /* !Py_LIMITED_API */ diff --git a/Include/descrobject.h b/Include/descrobject.h new file mode 100644 index 0000000..73bbb3f --- /dev/null +++ b/Include/descrobject.h @@ -0,0 +1,110 @@ +/* Descriptors */ +#ifndef Py_DESCROBJECT_H +#define Py_DESCROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef PyObject *(*getter)(PyObject *, void *); +typedef int (*setter)(PyObject *, PyObject *, void *); + +typedef struct PyGetSetDef { + const char *name; + getter get; + setter set; + const char *doc; + void *closure; +} PyGetSetDef; + +#ifndef Py_LIMITED_API +typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, + void *wrapped); + +typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, + void *wrapped, PyObject *kwds); + +struct wrapperbase { + const char *name; + int offset; + void *function; + wrapperfunc wrapper; + const char *doc; + int flags; + PyObject *name_strobj; +}; + +/* Flags for above struct */ +#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ + +/* Various kinds of descriptor objects */ + +typedef struct { + PyObject_HEAD + PyTypeObject *d_type; + PyObject *d_name; + PyObject *d_qualname; +} PyDescrObject; + +#define PyDescr_COMMON PyDescrObject d_common + +#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) +#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) + +typedef struct { + PyDescr_COMMON; + PyMethodDef *d_method; +} PyMethodDescrObject; + +typedef struct { + PyDescr_COMMON; + struct PyMemberDef *d_member; +} PyMemberDescrObject; + +typedef struct { + PyDescr_COMMON; + PyGetSetDef *d_getset; +} PyGetSetDescrObject; + +typedef struct { + PyDescr_COMMON; + struct wrapperbase *d_base; + void *d_wrapped; /* This can be any function pointer */ +} PyWrapperDescrObject; +#endif /* Py_LIMITED_API */ + +PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type; +PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; +PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; +PyAPI_DATA(PyTypeObject) PyMethodDescr_Type; +PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; +PyAPI_DATA(PyTypeObject) PyDictProxy_Type; +#ifndef Py_LIMITED_API +PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type; +#endif /* Py_LIMITED_API */ + +PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); +struct PyMemberDef; /* forward declaration for following prototype */ +PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, + struct PyMemberDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, + struct PyGetSetDef *); +#ifndef Py_LIMITED_API + +PyAPI_FUNC(PyObject *) _PyMethodDescr_FastCallKeywords( + PyObject *descrobj, PyObject *const *stack, Py_ssize_t nargs, PyObject *kwnames); +PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, + struct wrapperbase *, void *); +#define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL) +#endif + +PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); +PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); + + +PyAPI_DATA(PyTypeObject) PyProperty_Type; +#ifdef __cplusplus +} +#endif +#endif /* !Py_DESCROBJECT_H */ + diff --git a/Include/dictobject.h b/Include/dictobject.h new file mode 100644 index 0000000..28930f4 --- /dev/null +++ b/Include/dictobject.h @@ -0,0 +1,179 @@ +#ifndef Py_DICTOBJECT_H +#define Py_DICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Dictionary object type -- mapping from hashable object to object */ + +/* The distribution includes a separate file, Objects/dictnotes.txt, + describing explorations into dictionary design and optimization. + It covers typical dictionary use patterns, the parameters for + tuning dictionaries, and several ideas for possible optimizations. +*/ + +#ifndef Py_LIMITED_API + +typedef struct _dictkeysobject PyDictKeysObject; + +/* The ma_values pointer is NULL for a combined table + * or points to an array of PyObject* for a split table + */ +typedef struct { + PyObject_HEAD + + /* Number of items in the dictionary */ + Py_ssize_t ma_used; + + /* Dictionary version: globally unique, value change each time + the dictionary is modified */ + uint64_t ma_version_tag; + + PyDictKeysObject *ma_keys; + + /* If ma_values is NULL, the table is "combined": keys and values + are stored in ma_keys. + + If ma_values is not NULL, the table is splitted: + keys are stored in ma_keys and values are stored in ma_values */ + PyObject **ma_values; +} PyDictObject; + +typedef struct { + PyObject_HEAD + PyDictObject *dv_dict; +} _PyDictViewObject; + +#endif /* Py_LIMITED_API */ + +PyAPI_DATA(PyTypeObject) PyDict_Type; +PyAPI_DATA(PyTypeObject) PyDictIterKey_Type; +PyAPI_DATA(PyTypeObject) PyDictIterValue_Type; +PyAPI_DATA(PyTypeObject) PyDictIterItem_Type; +PyAPI_DATA(PyTypeObject) PyDictKeys_Type; +PyAPI_DATA(PyTypeObject) PyDictItems_Type; +PyAPI_DATA(PyTypeObject) PyDictValues_Type; + +#define PyDict_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) +#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) +#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type) +#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type) +#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type) +/* This excludes Values, since they are not sets. */ +# define PyDictViewSet_Check(op) \ + (PyDictKeys_Check(op) || PyDictItems_Check(op)) + + +PyAPI_FUNC(PyObject *) PyDict_New(void); +PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +#endif +PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, + struct _Py_Identifier *key); +PyAPI_FUNC(PyObject *) PyDict_SetDefault( + PyObject *mp, PyObject *key, PyObject *defaultobj); +#endif +PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, + PyObject *item, Py_hash_t hash); +#endif +PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, + int (*predicate)(PyObject *value)); +#endif +PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); +PyAPI_FUNC(int) PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); +#ifndef Py_LIMITED_API +PyDictKeysObject *_PyDict_NewKeysForClass(void); +PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *); +PyAPI_FUNC(int) _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); +PyObject *_PyDictView_New(PyObject *, PyTypeObject *); +#endif +PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); +PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); +PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API +/* Get the number of items of a dictionary. */ +#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used) +PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash); +PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); +PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); +PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); +Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); +PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); +PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *); +PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); +PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); +#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) + +PyAPI_FUNC(int) PyDict_ClearFreeList(void); +#endif + +/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ +PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); + +/* PyDict_Merge updates/merges from a mapping object (an object that + supports PyMapping_Keys() and PyObject_GetItem()). If override is true, + the last occurrence of a key wins, else the first. The Python + dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). +*/ +PyAPI_FUNC(int) PyDict_Merge(PyObject *mp, + PyObject *other, + int override); + +#ifndef Py_LIMITED_API +/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0, + the first occurrence of a key wins, if override is 1, the last occurrence + of a key wins, if override is 2, a KeyError with conflicting key as + argument is raised. +*/ +PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); +PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); +#endif + +/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing + iterable objects of length 2. If override is true, the last occurrence + of a key wins, else the first. The Python dict constructor dict(seq2) + is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). +*/ +PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, + PyObject *seq2, + int override); + +PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key); +PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); + +int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); +PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_DICTOBJECT_H */ diff --git a/Include/dtoa.h b/Include/dtoa.h new file mode 100644 index 0000000..9bfb625 --- /dev/null +++ b/Include/dtoa.h @@ -0,0 +1,19 @@ +#ifndef Py_LIMITED_API +#ifndef PY_NO_SHORT_FLOAT_REPR +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); +PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); +PyAPI_FUNC(double) _Py_dg_stdnan(int sign); +PyAPI_FUNC(double) _Py_dg_infinity(int sign); + + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/Include/dynamic_annotations.h b/Include/dynamic_annotations.h new file mode 100644 index 0000000..0bd1a83 --- /dev/null +++ b/Include/dynamic_annotations.h @@ -0,0 +1,499 @@ +/* Copyright (c) 2008-2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * --- + * Author: Kostya Serebryany + * Copied to CPython by Jeffrey Yasskin, with all macros renamed to + * start with _Py_ to avoid colliding with users embedding Python, and + * with deprecated macros removed. + */ + +/* This file defines dynamic annotations for use with dynamic analysis + tool such as valgrind, PIN, etc. + + Dynamic annotation is a source code annotation that affects + the generated code (that is, the annotation is not a comment). + Each such annotation is attached to a particular + instruction and/or to a particular object (address) in the program. + + The annotations that should be used by users are macros in all upper-case + (e.g., _Py_ANNOTATE_NEW_MEMORY). + + Actual implementation of these macros may differ depending on the + dynamic analysis tool being used. + + See http://code.google.com/p/data-race-test/ for more information. + + This file supports the following dynamic analysis tools: + - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). + Macros are defined empty. + - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). + Macros are defined as calls to non-inlinable empty functions + that are intercepted by Valgrind. */ + +#ifndef __DYNAMIC_ANNOTATIONS_H__ +#define __DYNAMIC_ANNOTATIONS_H__ + +#ifndef DYNAMIC_ANNOTATIONS_ENABLED +# define DYNAMIC_ANNOTATIONS_ENABLED 0 +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 + + /* ------------------------------------------------------------- + Annotations useful when implementing condition variables such as CondVar, + using conditional critical sections (Await/LockWhen) and when constructing + user-defined synchronization mechanisms. + + The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and + _Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in + user-defined synchronization mechanisms: the race detector will infer an + arc from the former to the latter when they share the same argument + pointer. + + Example 1 (reference counting): + + void Unref() { + _Py_ANNOTATE_HAPPENS_BEFORE(&refcount_); + if (AtomicDecrementByOne(&refcount_) == 0) { + _Py_ANNOTATE_HAPPENS_AFTER(&refcount_); + delete this; + } + } + + Example 2 (message queue): + + void MyQueue::Put(Type *e) { + MutexLock lock(&mu_); + _Py_ANNOTATE_HAPPENS_BEFORE(e); + PutElementIntoMyQueue(e); + } + + Type *MyQueue::Get() { + MutexLock lock(&mu_); + Type *e = GetElementFromMyQueue(); + _Py_ANNOTATE_HAPPENS_AFTER(e); + return e; + } + + Note: when possible, please use the existing reference counting and message + queue implementations instead of inventing new ones. */ + + /* Report that wait on the condition variable at address "cv" has succeeded + and the lock at address "lock" is held. */ +#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ + AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) + + /* Report that wait on the condition variable at "cv" has succeeded. Variant + w/o lock. */ +#define _Py_ANNOTATE_CONDVAR_WAIT(cv) \ + AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) + + /* Report that we are about to signal on the condition variable at address + "cv". */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \ + AnnotateCondVarSignal(__FILE__, __LINE__, cv) + + /* Report that we are about to signal_all on the condition variable at "cv". */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ + AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) + + /* Annotations for user-defined synchronization mechanisms. */ +#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj) +#define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj) + + /* Report that the bytes in the range [pointer, pointer+size) are about + to be published safely. The race checker will create a happens-before + arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to + subsequent accesses to this memory. + Note: this annotation may not work properly if the race detector uses + sampling, i.e. does not observe all memory accesses. + */ +#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ + AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) + + /* Instruct the tool to create a happens-before arc between mu->Unlock() and + mu->Lock(). This annotation may slow down the race detector and hide real + races. Normally it is used only when it would be difficult to annotate each + of the mutex's critical sections individually using the annotations above. + This annotation makes sense only for hybrid race detectors. For pure + happens-before detectors this is a no-op. For more details see + http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ +#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ + AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) + + /* ------------------------------------------------------------- + Annotations useful when defining memory allocators, or when memory that + was protected in one way starts to be protected in another. */ + + /* Report that a new memory at "address" of size "size" has been allocated. + This might be used when the memory has been retrieved from a free list and + is about to be reused, or when the locking discipline for a variable + changes. */ +#define _Py_ANNOTATE_NEW_MEMORY(address, size) \ + AnnotateNewMemory(__FILE__, __LINE__, address, size) + + /* ------------------------------------------------------------- + Annotations useful when defining FIFO queues that transfer data between + threads. */ + + /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at + address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should + be used only for FIFO queues. For non-FIFO queues use + _Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for + get). */ +#define _Py_ANNOTATE_PCQ_CREATE(pcq) \ + AnnotatePCQCreate(__FILE__, __LINE__, pcq) + + /* Report that the queue at address "pcq" is about to be destroyed. */ +#define _Py_ANNOTATE_PCQ_DESTROY(pcq) \ + AnnotatePCQDestroy(__FILE__, __LINE__, pcq) + + /* Report that we are about to put an element into a FIFO queue at address + "pcq". */ +#define _Py_ANNOTATE_PCQ_PUT(pcq) \ + AnnotatePCQPut(__FILE__, __LINE__, pcq) + + /* Report that we've just got an element from a FIFO queue at address "pcq". */ +#define _Py_ANNOTATE_PCQ_GET(pcq) \ + AnnotatePCQGet(__FILE__, __LINE__, pcq) + + /* ------------------------------------------------------------- + Annotations that suppress errors. It is usually better to express the + program's synchronization using the other annotations, but these can + be used when all else fails. */ + + /* Report that we may have a benign race at "pointer", with size + "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the + point where "pointer" has been allocated, preferably close to the point + where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */ +#define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ + sizeof(*(pointer)), description) + + /* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to + the memory range [address, address+size). */ +#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) + + /* Request the analysis tool to ignore all reads in the current thread + until _Py_ANNOTATE_IGNORE_READS_END is called. + Useful to ignore intentional racey reads, while still checking + other reads and all writes. + See also _Py_ANNOTATE_UNPROTECTED_READ. */ +#define _Py_ANNOTATE_IGNORE_READS_BEGIN() \ + AnnotateIgnoreReadsBegin(__FILE__, __LINE__) + + /* Stop ignoring reads. */ +#define _Py_ANNOTATE_IGNORE_READS_END() \ + AnnotateIgnoreReadsEnd(__FILE__, __LINE__) + + /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ +#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \ + AnnotateIgnoreWritesBegin(__FILE__, __LINE__) + + /* Stop ignoring writes. */ +#define _Py_ANNOTATE_IGNORE_WRITES_END() \ + AnnotateIgnoreWritesEnd(__FILE__, __LINE__) + + /* Start ignoring all memory accesses (reads and writes). */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ + do {\ + _Py_ANNOTATE_IGNORE_READS_BEGIN();\ + _Py_ANNOTATE_IGNORE_WRITES_BEGIN();\ + }while(0)\ + + /* Stop ignoring all memory accesses. */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ + do {\ + _Py_ANNOTATE_IGNORE_WRITES_END();\ + _Py_ANNOTATE_IGNORE_READS_END();\ + }while(0)\ + + /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: + RWLOCK* and CONDVAR*. */ +#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \ + AnnotateIgnoreSyncBegin(__FILE__, __LINE__) + + /* Stop ignoring sync events. */ +#define _Py_ANNOTATE_IGNORE_SYNC_END() \ + AnnotateIgnoreSyncEnd(__FILE__, __LINE__) + + + /* Enable (enable!=0) or disable (enable==0) race detection for all threads. + This annotation could be useful if you want to skip expensive race analysis + during some period of program execution, e.g. during initialization. */ +#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ + AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) + + /* ------------------------------------------------------------- + Annotations useful for debugging. */ + + /* Request to trace every access to "address". */ +#define _Py_ANNOTATE_TRACE_MEMORY(address) \ + AnnotateTraceMemory(__FILE__, __LINE__, address) + + /* Report the current thread name to a race detector. */ +#define _Py_ANNOTATE_THREAD_NAME(name) \ + AnnotateThreadName(__FILE__, __LINE__, name) + + /* ------------------------------------------------------------- + Annotations useful when implementing locks. They are not + normally needed by modules that merely use locks. + The "lock" argument is a pointer to the lock object. */ + + /* Report that a lock has been created at address "lock". */ +#define _Py_ANNOTATE_RWLOCK_CREATE(lock) \ + AnnotateRWLockCreate(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" is about to be destroyed. */ +#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \ + AnnotateRWLockDestroy(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" has been acquired. + is_w=1 for writer lock, is_w=0 for reader lock. */ +#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ + AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) + + /* Report that the lock at address "lock" is about to be released. */ +#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ + AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) + + /* ------------------------------------------------------------- + Annotations useful when implementing barriers. They are not + normally needed by modules that merely use barriers. + The "barrier" argument is a pointer to the barrier object. */ + + /* Report that the "barrier" has been initialized with initial "count". + If 'reinitialization_allowed' is true, initialization is allowed to happen + multiple times w/o calling barrier_destroy() */ +#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ + AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \ + reinitialization_allowed) + + /* Report that we are about to enter barrier_wait("barrier"). */ +#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ + AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) + + /* Report that we just exited barrier_wait("barrier"). */ +#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ + AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) + + /* Report that the "barrier" has been destroyed. */ +#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \ + AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) + + /* ------------------------------------------------------------- + Annotations useful for testing race detectors. */ + + /* Report that we expect a race on the variable at "address". + Use only in unit tests for a race detector. */ +#define _Py_ANNOTATE_EXPECT_RACE(address, description) \ + AnnotateExpectRace(__FILE__, __LINE__, address, description) + + /* A no-op. Insert where you like to test the interceptors. */ +#define _Py_ANNOTATE_NO_OP(arg) \ + AnnotateNoOp(__FILE__, __LINE__, arg) + + /* Force the race detector to flush its state. The actual effect depends on + * the implementation of the detector. */ +#define _Py_ANNOTATE_FLUSH_STATE() \ + AnnotateFlushState(__FILE__, __LINE__) + + +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + +#define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */ +#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ +#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ +#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ +#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ +#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ +#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ +#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ +#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ +#define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ +#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ +#define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */ +#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ +#define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ +#define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ +#define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */ +#define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */ +#define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */ +#define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */ +#define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */ +#define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */ +#define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */ +#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ +#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ +#define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ +#define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */ +#define _Py_ANNOTATE_THREAD_NAME(name) /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_END() /* empty */ +#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ +#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */ +#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ +#define _Py_ANNOTATE_NO_OP(arg) /* empty */ +#define _Py_ANNOTATE_FLUSH_STATE() /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +/* Use the macros above rather than using these functions directly. */ +#ifdef __cplusplus +extern "C" { +#endif +void AnnotateRWLockCreate(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockDestroy(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockAcquired(const char *file, int line, + const volatile void *lock, long is_w); +void AnnotateRWLockReleased(const char *file, int line, + const volatile void *lock, long is_w); +void AnnotateBarrierInit(const char *file, int line, + const volatile void *barrier, long count, + long reinitialization_allowed); +void AnnotateBarrierWaitBefore(const char *file, int line, + const volatile void *barrier); +void AnnotateBarrierWaitAfter(const char *file, int line, + const volatile void *barrier); +void AnnotateBarrierDestroy(const char *file, int line, + const volatile void *barrier); +void AnnotateCondVarWait(const char *file, int line, + const volatile void *cv, + const volatile void *lock); +void AnnotateCondVarSignal(const char *file, int line, + const volatile void *cv); +void AnnotateCondVarSignalAll(const char *file, int line, + const volatile void *cv); +void AnnotatePublishMemoryRange(const char *file, int line, + const volatile void *address, + long size); +void AnnotateUnpublishMemoryRange(const char *file, int line, + const volatile void *address, + long size); +void AnnotatePCQCreate(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQDestroy(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQPut(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQGet(const char *file, int line, + const volatile void *pcq); +void AnnotateNewMemory(const char *file, int line, + const volatile void *address, + long size); +void AnnotateExpectRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRaceSized(const char *file, int line, + const volatile void *address, + long size, + const char *description); +void AnnotateMutexIsUsedAsCondVar(const char *file, int line, + const volatile void *mu); +void AnnotateTraceMemory(const char *file, int line, + const volatile void *arg); +void AnnotateThreadName(const char *file, int line, + const char *name); +void AnnotateIgnoreReadsBegin(const char *file, int line); +void AnnotateIgnoreReadsEnd(const char *file, int line); +void AnnotateIgnoreWritesBegin(const char *file, int line); +void AnnotateIgnoreWritesEnd(const char *file, int line); +void AnnotateEnableRaceDetection(const char *file, int line, int enable); +void AnnotateNoOp(const char *file, int line, + const volatile void *arg); +void AnnotateFlushState(const char *file, int line); + +/* Return non-zero value if running under valgrind. + + If "valgrind.h" is included into dynamic_annotations.c, + the regular valgrind mechanism will be used. + See http://valgrind.org/docs/manual/manual-core-adv.html about + RUNNING_ON_VALGRIND and other valgrind "client requests". + The file "valgrind.h" may be obtained by doing + svn co svn://svn.valgrind.org/valgrind/trunk/include + + If for some reason you can't use "valgrind.h" or want to fake valgrind, + there are two ways to make this function return non-zero: + - Use environment variable: export RUNNING_ON_VALGRIND=1 + - Make your tool intercept the function RunningOnValgrind() and + change its return value. + */ +int RunningOnValgrind(void); + +#ifdef __cplusplus +} +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) + + /* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. + + Instead of doing + _Py_ANNOTATE_IGNORE_READS_BEGIN(); + ... = x; + _Py_ANNOTATE_IGNORE_READS_END(); + one can use + ... = _Py_ANNOTATE_UNPROTECTED_READ(x); */ + template + inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) { + _Py_ANNOTATE_IGNORE_READS_BEGIN(); + T res = x; + _Py_ANNOTATE_IGNORE_READS_END(); + return res; + } + /* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ +#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ + namespace { \ + class static_var ## _annotator { \ + public: \ + static_var ## _annotator() { \ + _Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ + sizeof(static_var), \ + # static_var ": " description); \ + } \ + }; \ + static static_var ## _annotator the ## static_var ## _annotator;\ + } +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + +#define _Py_ANNOTATE_UNPROTECTED_READ(x) (x) +#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +#endif /* __DYNAMIC_ANNOTATIONS_H__ */ diff --git a/Include/enumobject.h b/Include/enumobject.h new file mode 100644 index 0000000..c14dbfc --- /dev/null +++ b/Include/enumobject.h @@ -0,0 +1,17 @@ +#ifndef Py_ENUMOBJECT_H +#define Py_ENUMOBJECT_H + +/* Enumerate Object */ + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyEnum_Type; +PyAPI_DATA(PyTypeObject) PyReversed_Type; + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_ENUMOBJECT_H */ diff --git a/Include/errcode.h b/Include/errcode.h new file mode 100644 index 0000000..b37cd26 --- /dev/null +++ b/Include/errcode.h @@ -0,0 +1,38 @@ +#ifndef Py_ERRCODE_H +#define Py_ERRCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Error codes passed around between file input, tokenizer, parser and + interpreter. This is necessary so we can turn them into Python + exceptions at a higher level. Note that some errors have a + slightly different meaning when passed from the tokenizer to the + parser than when passed from the parser to the interpreter; e.g. + the parser only returns E_EOF when it hits EOF immediately, and it + never returns E_OK. */ + +#define E_OK 10 /* No error */ +#define E_EOF 11 /* End Of File */ +#define E_INTR 12 /* Interrupted */ +#define E_TOKEN 13 /* Bad token */ +#define E_SYNTAX 14 /* Syntax error */ +#define E_NOMEM 15 /* Ran out of memory */ +#define E_DONE 16 /* Parsing complete */ +#define E_ERROR 17 /* Execution error */ +#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ +#define E_OVERFLOW 19 /* Node had too many children */ +#define E_TOODEEP 20 /* Too many indentation levels */ +#define E_DEDENT 21 /* No matching outer block for dedent */ +#define E_DECODE 22 /* Error in decoding into Unicode */ +#define E_EOFS 23 /* EOF in triple-quoted string */ +#define E_EOLS 24 /* EOL in single-quoted string */ +#define E_LINECONT 25 /* Unexpected characters after a line continuation */ +#define E_IDENTIFIER 26 /* Invalid characters in identifier */ +#define E_BADSINGLE 27 /* Ill-formed single statement input */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRCODE_H */ diff --git a/Include/eval.h b/Include/eval.h new file mode 100644 index 0000000..2c1c2d0 --- /dev/null +++ b/Include/eval.h @@ -0,0 +1,37 @@ + +/* Interface to execute compiled code */ + +#ifndef Py_EVAL_H +#define Py_EVAL_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co, + PyObject *globals, + PyObject *locals, + PyObject *const *args, int argc, + PyObject *const *kwds, int kwdc, + PyObject *const *defs, int defc, + PyObject *kwdefs, PyObject *closure); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyEval_EvalCodeWithName( + PyObject *co, + PyObject *globals, PyObject *locals, + PyObject *const *args, Py_ssize_t argcount, + PyObject *const *kwnames, PyObject *const *kwargs, + Py_ssize_t kwcount, int kwstep, + PyObject *const *defs, Py_ssize_t defcount, + PyObject *kwdefs, PyObject *closure, + PyObject *name, PyObject *qualname); + +PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_EVAL_H */ diff --git a/Include/fileobject.h b/Include/fileobject.h new file mode 100644 index 0000000..89e8dd6 --- /dev/null +++ b/Include/fileobject.h @@ -0,0 +1,55 @@ +/* File object interface (what's left of it -- see io.py) */ + +#ifndef Py_FILEOBJECT_H +#define Py_FILEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#define PY_STDIOTEXTMODE "b" + +PyAPI_FUNC(PyObject *) PyFile_FromFd(int, const char *, const char *, int, + const char *, const char *, + const char *, int); +PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); +PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); +#endif + +/* The default encoding used by the platform file system APIs + If non-NULL, this is different than the default encoding for strings +*/ +PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; +#endif +PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_DATA(int) Py_UTF8Mode; +#endif + +/* Internal API + + The std printer acts as a preliminary sys.stderr until the new io + infrastructure is in place. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); +PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; +#endif /* Py_LIMITED_API */ + +/* A routine to check if a file descriptor can be select()-ed. */ +#ifdef _MSC_VER + /* On Windows, any socket fd can be select()-ed, no matter how high */ + #define _PyIsSelectable_fd(FD) (1) +#else + #define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FILEOBJECT_H */ diff --git a/Include/fileutils.h b/Include/fileutils.h new file mode 100644 index 0000000..e4bf6d4 --- /dev/null +++ b/Include/fileutils.h @@ -0,0 +1,177 @@ +#ifndef Py_FILEUTILS_H +#define Py_FILEUTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(wchar_t *) Py_DecodeLocale( + const char *arg, + size_t *size); + +PyAPI_FUNC(char*) Py_EncodeLocale( + const wchar_t *text, + size_t *error_pos); + +PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( + const wchar_t *text, + size_t *error_pos); +#endif + +#ifdef Py_BUILD_CORE +PyAPI_FUNC(int) _Py_DecodeUTF8Ex( + const char *arg, + Py_ssize_t arglen, + wchar_t **wstr, + size_t *wlen, + const char **reason, + int surrogateescape); + +PyAPI_FUNC(int) _Py_EncodeUTF8Ex( + const wchar_t *text, + char **str, + size_t *error_pos, + const char **reason, + int raw_malloc, + int surrogateescape); + +PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape( + const char *arg, + Py_ssize_t arglen); + +PyAPI_FUNC(int) _Py_DecodeLocaleEx( + const char *arg, + wchar_t **wstr, + size_t *wlen, + const char **reason, + int current_locale, + int surrogateescape); + +PyAPI_FUNC(int) _Py_EncodeLocaleEx( + const wchar_t *text, + char **str, + size_t *error_pos, + const char **reason, + int current_locale, + int surrogateescape); +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _Py_device_encoding(int); + +#ifdef MS_WINDOWS +struct _Py_stat_struct { + unsigned long st_dev; + uint64_t st_ino; + unsigned short st_mode; + int st_nlink; + int st_uid; + int st_gid; + unsigned long st_rdev; + __int64 st_size; + time_t st_atime; + int st_atime_nsec; + time_t st_mtime; + int st_mtime_nsec; + time_t st_ctime; + int st_ctime_nsec; + unsigned long st_file_attributes; +}; +#else +# define _Py_stat_struct stat +#endif + +PyAPI_FUNC(int) _Py_fstat( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_fstat_noraise( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_stat( + PyObject *path, + struct stat *status); + +PyAPI_FUNC(int) _Py_open( + const char *pathname, + int flags); + +PyAPI_FUNC(int) _Py_open_noraise( + const char *pathname, + int flags); + +PyAPI_FUNC(FILE *) _Py_wfopen( + const wchar_t *path, + const wchar_t *mode); + +PyAPI_FUNC(FILE*) _Py_fopen( + const char *pathname, + const char *mode); + +PyAPI_FUNC(FILE*) _Py_fopen_obj( + PyObject *path, + const char *mode); + +PyAPI_FUNC(Py_ssize_t) _Py_read( + int fd, + void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write( + int fd, + const void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( + int fd, + const void *buf, + size_t count); + +#ifdef HAVE_READLINK +PyAPI_FUNC(int) _Py_wreadlink( + const wchar_t *path, + wchar_t *buf, + size_t bufsiz); +#endif + +#ifdef HAVE_REALPATH +PyAPI_FUNC(wchar_t*) _Py_wrealpath( + const wchar_t *path, + wchar_t *resolved_path, + size_t resolved_path_size); +#endif + +PyAPI_FUNC(wchar_t*) _Py_wgetcwd( + wchar_t *buf, + size_t size); + +PyAPI_FUNC(int) _Py_get_inheritable(int fd); + +PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_dup(int fd); + +#ifndef MS_WINDOWS +PyAPI_FUNC(int) _Py_get_blocking(int fd); + +PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); +#endif /* !MS_WINDOWS */ + +PyAPI_FUNC(int) _Py_GetLocaleconvNumeric( + PyObject **decimal_point, + PyObject **thousands_sep, + const char **grouping); + +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_FILEUTILS_H */ diff --git a/Include/floatobject.h b/Include/floatobject.h new file mode 100644 index 0000000..f1044d6 --- /dev/null +++ b/Include/floatobject.h @@ -0,0 +1,130 @@ + +/* Float object interface */ + +/* +PyFloatObject represents a (double precision) floating point number. +*/ + +#ifndef Py_FLOATOBJECT_H +#define Py_FLOATOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + double ob_fval; +} PyFloatObject; +#endif + +PyAPI_DATA(PyTypeObject) PyFloat_Type; + +#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) +#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type) + +#ifdef Py_NAN +#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) +#endif + +#define Py_RETURN_INF(sign) do \ + if (copysign(1., sign) == 1.) { \ + return PyFloat_FromDouble(Py_HUGE_VAL); \ + } else { \ + return PyFloat_FromDouble(-Py_HUGE_VAL); \ + } while(0) + +PyAPI_FUNC(double) PyFloat_GetMax(void); +PyAPI_FUNC(double) PyFloat_GetMin(void); +PyAPI_FUNC(PyObject *) PyFloat_GetInfo(void); + +/* Return Python float from string PyObject. */ +PyAPI_FUNC(PyObject *) PyFloat_FromString(PyObject*); + +/* Return Python float from C double. */ +PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double); + +/* Extract C double from Python float. The macro version trades safety for + speed. */ +PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *); +#ifndef Py_LIMITED_API +#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) +#endif + +#ifndef Py_LIMITED_API +/* _PyFloat_{Pack,Unpack}{4,8} + * + * The struct and pickle (at least) modules need an efficient platform- + * independent way to store floating-point values as byte strings. + * The Pack routines produce a string from a C double, and the Unpack + * routines produce a C double from such a string. The suffix (4 or 8) + * specifies the number of bytes in the string. + * + * On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats + * these functions work by copying bits. On other platforms, the formats the + * 4- byte format is identical to the IEEE-754 single precision format, and + * the 8-byte format to the IEEE-754 double precision format, although the + * packing of INFs and NaNs (if such things exist on the platform) isn't + * handled correctly, and attempting to unpack a string containing an IEEE + * INF or NaN will raise an exception. + * + * On non-IEEE platforms with more precision, or larger dynamic range, than + * 754 supports, not all values can be packed; on non-IEEE platforms with less + * precision, or smaller dynamic range, not all values can be unpacked. What + * happens in such cases is partly accidental (alas). + */ + +/* The pack routines write 2, 4 or 8 bytes, starting at p. le is a bool + * argument, true if you want the string in little-endian format (exponent + * last, at p+1, p+3 or p+7), false if you want big-endian format (exponent + * first, at p). + * Return value: 0 if all is OK, -1 if error (and an exception is + * set, most likely OverflowError). + * There are two problems on non-IEEE platforms: + * 1): What this does is undefined if x is a NaN or infinity. + * 2): -0.0 and +0.0 produce the same string. + */ +PyAPI_FUNC(int) _PyFloat_Pack2(double x, unsigned char *p, int le); +PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le); +PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le); + +/* Needed for the old way for marshal to store a floating point number. + Returns the string length copied into p, -1 on error. + */ +PyAPI_FUNC(int) _PyFloat_Repr(double x, char *p, size_t len); + +/* Used to get the important decimal digits of a double */ +PyAPI_FUNC(int) _PyFloat_Digits(char *buf, double v, int *signum); +PyAPI_FUNC(void) _PyFloat_DigitsInit(void); + +/* The unpack routines read 2, 4 or 8 bytes, starting at p. le is a bool + * argument, true if the string is in little-endian format (exponent + * last, at p+1, p+3 or p+7), false if big-endian (exponent first, at p). + * Return value: The unpacked double. On error, this is -1.0 and + * PyErr_Occurred() is true (and an exception is set, most likely + * OverflowError). Note that on a non-IEEE platform this will refuse + * to unpack a string that represents a NaN or infinity. + */ +PyAPI_FUNC(double) _PyFloat_Unpack2(const unsigned char *p, int le); +PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); +PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); + +/* free list api */ +PyAPI_FUNC(int) PyFloat_ClearFreeList(void); + +PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(int) _PyFloat_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FLOATOBJECT_H */ diff --git a/Include/frameobject.h b/Include/frameobject.h new file mode 100644 index 0000000..a95baf8 --- /dev/null +++ b/Include/frameobject.h @@ -0,0 +1,93 @@ + +/* Frame object interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_FRAMEOBJECT_H +#define Py_FRAMEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int b_type; /* what kind of block this is */ + int b_handler; /* where to jump to find handler */ + int b_level; /* value stack level to pop to */ +} PyTryBlock; + +typedef struct _frame { + PyObject_VAR_HEAD + struct _frame *f_back; /* previous frame, or NULL */ + PyCodeObject *f_code; /* code segment */ + PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ + PyObject *f_globals; /* global symbol table (PyDictObject) */ + PyObject *f_locals; /* local symbol table (any mapping) */ + PyObject **f_valuestack; /* points after the last local */ + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; + PyObject *f_trace; /* Trace function */ + char f_trace_lines; /* Emit per-line trace events? */ + char f_trace_opcodes; /* Emit per-opcode trace events? */ + + /* Borrowed reference to a generator, or NULL */ + PyObject *f_gen; + + int f_lasti; /* Last instruction if called */ + /* Call PyFrame_GetLineNumber() instead of reading this field + directly. As of 2.3 f_lineno is only valid when tracing is + active (i.e. when f_trace is set). At other times we use + PyCode_Addr2Line to calculate the line from the current + bytecode index. */ + int f_lineno; /* Current line number */ + int f_iblock; /* index in f_blockstack */ + char f_executing; /* whether the frame is still executing */ + PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ + PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ +} PyFrameObject; + + +/* Standard object interface */ + +PyAPI_DATA(PyTypeObject) PyFrame_Type; + +#define PyFrame_Check(op) (Py_TYPE(op) == &PyFrame_Type) + +PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, + PyObject *, PyObject *); + +/* only internal use */ +PyFrameObject* _PyFrame_New_NoTrack(PyThreadState *, PyCodeObject *, + PyObject *, PyObject *); + + +/* The rest of the interface is specific for frame objects */ + +/* Block management functions */ + +PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int); +PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *); + +/* Extend the value stack */ + +PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int); + +/* Conversions between "fast locals" and locals in dictionary */ + +PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); + +PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); +PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); + +PyAPI_FUNC(int) PyFrame_ClearFreeList(void); + +PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); + +/* Return the line of code the frame is currently executing. */ +PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FRAMEOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/funcobject.h b/Include/funcobject.h new file mode 100644 index 0000000..86674ac --- /dev/null +++ b/Include/funcobject.h @@ -0,0 +1,103 @@ + +/* Function object interface */ +#ifndef Py_LIMITED_API +#ifndef Py_FUNCOBJECT_H +#define Py_FUNCOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Function objects and code objects should not be confused with each other: + * + * Function objects are created by the execution of the 'def' statement. + * They reference a code object in their __code__ attribute, which is a + * purely syntactic object, i.e. nothing more than a compiled version of some + * source code lines. There is one code object per source code "fragment", + * but each code object can be referenced by zero or many function objects + * depending only on how many times the 'def' statement in the source was + * executed so far. + */ + +typedef struct { + PyObject_HEAD + PyObject *func_code; /* A code object, the __code__ attribute */ + PyObject *func_globals; /* A dictionary (other mappings won't do) */ + PyObject *func_defaults; /* NULL or a tuple */ + PyObject *func_kwdefaults; /* NULL or a dict */ + PyObject *func_closure; /* NULL or a tuple of cell objects */ + PyObject *func_doc; /* The __doc__ attribute, can be anything */ + PyObject *func_name; /* The __name__ attribute, a string object */ + PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */ + PyObject *func_weakreflist; /* List of weak references */ + PyObject *func_module; /* The __module__ attribute, can be anything */ + PyObject *func_annotations; /* Annotations, a dict or NULL */ + PyObject *func_qualname; /* The qualified name */ + + /* Invariant: + * func_closure contains the bindings for func_code->co_freevars, so + * PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code) + * (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0). + */ +} PyFunctionObject; + +PyAPI_DATA(PyTypeObject) PyFunction_Type; + +#define PyFunction_Check(op) (Py_TYPE(op) == &PyFunction_Type) + +PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); +PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *); +PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyFunction_FastCallDict( + PyObject *func, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyFunction_FastCallKeywords( + PyObject *func, + PyObject *const *stack, + Py_ssize_t nargs, + PyObject *kwnames); +#endif + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyFunction_GET_CODE(func) \ + (((PyFunctionObject *)func) -> func_code) +#define PyFunction_GET_GLOBALS(func) \ + (((PyFunctionObject *)func) -> func_globals) +#define PyFunction_GET_MODULE(func) \ + (((PyFunctionObject *)func) -> func_module) +#define PyFunction_GET_DEFAULTS(func) \ + (((PyFunctionObject *)func) -> func_defaults) +#define PyFunction_GET_KW_DEFAULTS(func) \ + (((PyFunctionObject *)func) -> func_kwdefaults) +#define PyFunction_GET_CLOSURE(func) \ + (((PyFunctionObject *)func) -> func_closure) +#define PyFunction_GET_ANNOTATIONS(func) \ + (((PyFunctionObject *)func) -> func_annotations) + +/* The classmethod and staticmethod types lives here, too */ +PyAPI_DATA(PyTypeObject) PyClassMethod_Type; +PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; + +PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FUNCOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/genobject.h b/Include/genobject.h new file mode 100644 index 0000000..16b9833 --- /dev/null +++ b/Include/genobject.h @@ -0,0 +1,105 @@ + +/* Generator object interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_GENOBJECT_H +#define Py_GENOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +struct _frame; /* Avoid including frameobject.h */ + +/* _PyGenObject_HEAD defines the initial segment of generator + and coroutine objects. */ +#define _PyGenObject_HEAD(prefix) \ + PyObject_HEAD \ + /* Note: gi_frame can be NULL if the generator is "finished" */ \ + struct _frame *prefix##_frame; \ + /* True if generator is being executed. */ \ + char prefix##_running; \ + /* The code object backing the generator */ \ + PyObject *prefix##_code; \ + /* List of weak reference. */ \ + PyObject *prefix##_weakreflist; \ + /* Name of the generator. */ \ + PyObject *prefix##_name; \ + /* Qualified name of the generator. */ \ + PyObject *prefix##_qualname; \ + _PyErr_StackItem prefix##_exc_state; + +typedef struct { + /* The gi_ prefix is intended to remind of generator-iterator. */ + _PyGenObject_HEAD(gi) +} PyGenObject; + +PyAPI_DATA(PyTypeObject) PyGen_Type; + +#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) +#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type) + +PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); +PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *, + PyObject *name, PyObject *qualname); +PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *); +PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); +PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); +PyAPI_FUNC(PyObject *) _PyGen_Send(PyGenObject *, PyObject *); +PyObject *_PyGen_yf(PyGenObject *); +PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); + +#ifndef Py_LIMITED_API +typedef struct { + _PyGenObject_HEAD(cr) + PyObject *cr_origin; +} PyCoroObject; + +PyAPI_DATA(PyTypeObject) PyCoro_Type; +PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; + +PyAPI_DATA(PyTypeObject) _PyAIterWrapper_Type; + +#define PyCoro_CheckExact(op) (Py_TYPE(op) == &PyCoro_Type) +PyObject *_PyCoro_GetAwaitableIter(PyObject *o); +PyAPI_FUNC(PyObject *) PyCoro_New(struct _frame *, + PyObject *name, PyObject *qualname); + +/* Asynchronous Generators */ + +typedef struct { + _PyGenObject_HEAD(ag) + PyObject *ag_finalizer; + + /* Flag is set to 1 when hooks set up by sys.set_asyncgen_hooks + were called on the generator, to avoid calling them more + than once. */ + int ag_hooks_inited; + + /* Flag is set to 1 when aclose() is called for the first time, or + when a StopAsyncIteration exception is raised. */ + int ag_closed; +} PyAsyncGenObject; + +PyAPI_DATA(PyTypeObject) PyAsyncGen_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; + +PyAPI_FUNC(PyObject *) PyAsyncGen_New(struct _frame *, + PyObject *name, PyObject *qualname); + +#define PyAsyncGen_CheckExact(op) (Py_TYPE(op) == &PyAsyncGen_Type) + +PyObject *_PyAsyncGenValueWrapperNew(PyObject *); + +int PyAsyncGen_ClearFreeLists(void); + +#endif + +#undef _PyGenObject_HEAD + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GENOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/graminit.h b/Include/graminit.h new file mode 100644 index 0000000..bdfe821 --- /dev/null +++ b/Include/graminit.h @@ -0,0 +1,89 @@ +/* Generated by Parser/pgen */ + +#define single_input 256 +#define file_input 257 +#define eval_input 258 +#define decorator 259 +#define decorators 260 +#define decorated 261 +#define async_funcdef 262 +#define funcdef 263 +#define parameters 264 +#define typedargslist 265 +#define tfpdef 266 +#define varargslist 267 +#define vfpdef 268 +#define stmt 269 +#define simple_stmt 270 +#define small_stmt 271 +#define expr_stmt 272 +#define annassign 273 +#define testlist_star_expr 274 +#define augassign 275 +#define del_stmt 276 +#define pass_stmt 277 +#define flow_stmt 278 +#define break_stmt 279 +#define continue_stmt 280 +#define return_stmt 281 +#define yield_stmt 282 +#define raise_stmt 283 +#define import_stmt 284 +#define import_name 285 +#define import_from 286 +#define import_as_name 287 +#define dotted_as_name 288 +#define import_as_names 289 +#define dotted_as_names 290 +#define dotted_name 291 +#define global_stmt 292 +#define nonlocal_stmt 293 +#define assert_stmt 294 +#define compound_stmt 295 +#define async_stmt 296 +#define if_stmt 297 +#define while_stmt 298 +#define for_stmt 299 +#define try_stmt 300 +#define with_stmt 301 +#define with_item 302 +#define except_clause 303 +#define suite 304 +#define test 305 +#define test_nocond 306 +#define lambdef 307 +#define lambdef_nocond 308 +#define or_test 309 +#define and_test 310 +#define not_test 311 +#define comparison 312 +#define comp_op 313 +#define star_expr 314 +#define expr 315 +#define xor_expr 316 +#define and_expr 317 +#define shift_expr 318 +#define arith_expr 319 +#define term 320 +#define factor 321 +#define power 322 +#define atom_expr 323 +#define atom 324 +#define testlist_comp 325 +#define trailer 326 +#define subscriptlist 327 +#define subscript 328 +#define sliceop 329 +#define exprlist 330 +#define testlist 331 +#define dictorsetmaker 332 +#define classdef 333 +#define arglist 334 +#define argument 335 +#define comp_iter 336 +#define sync_comp_for 337 +#define comp_for 338 +#define comp_if 339 +#define encoding_decl 340 +#define yield_expr 341 +#define yield_arg 342 diff --git a/Include/grammar.h b/Include/grammar.h new file mode 100644 index 0000000..e1703f4 --- /dev/null +++ b/Include/grammar.h @@ -0,0 +1,94 @@ + +/* Grammar interface */ + +#ifndef Py_GRAMMAR_H +#define Py_GRAMMAR_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "bitset.h" /* Sigh... */ + +/* A label of an arc */ + +typedef struct { + int lb_type; + char *lb_str; +} label; + +#define EMPTY 0 /* Label number 0 is by definition the empty label */ + +/* A list of labels */ + +typedef struct { + int ll_nlabels; + label *ll_label; +} labellist; + +/* An arc from one state to another */ + +typedef struct { + short a_lbl; /* Label of this arc */ + short a_arrow; /* State where this arc goes to */ +} arc; + +/* A state in a DFA */ + +typedef struct { + int s_narcs; + arc *s_arc; /* Array of arcs */ + + /* Optional accelerators */ + int s_lower; /* Lowest label index */ + int s_upper; /* Highest label index */ + int *s_accel; /* Accelerator */ + int s_accept; /* Nonzero for accepting state */ +} state; + +/* A DFA */ + +typedef struct { + int d_type; /* Non-terminal this represents */ + char *d_name; /* For printing */ + int d_initial; /* Initial state */ + int d_nstates; + state *d_state; /* Array of states */ + bitset d_first; +} dfa; + +/* A grammar */ + +typedef struct { + int g_ndfas; + dfa *g_dfa; /* Array of DFAs */ + labellist g_ll; + int g_start; /* Start symbol of the grammar */ + int g_accel; /* Set if accelerators present */ +} grammar; + +/* FUNCTIONS */ + +grammar *newgrammar(int start); +void freegrammar(grammar *g); +dfa *adddfa(grammar *g, int type, const char *name); +int addstate(dfa *d); +void addarc(dfa *d, int from, int to, int lbl); +dfa *PyGrammar_FindDFA(grammar *g, int type); + +int addlabel(labellist *ll, int type, const char *str); +int findlabel(labellist *ll, int type, const char *str); +const char *PyGrammar_LabelRepr(label *lb); +void translatelabels(grammar *g); + +void addfirstsets(grammar *g); + +void PyGrammar_AddAccelerators(grammar *g); +void PyGrammar_RemoveAccelerators(grammar *); + +void printgrammar(grammar *g, FILE *fp); +void printnonterminals(grammar *g, FILE *fp); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GRAMMAR_H */ diff --git a/Include/import.h b/Include/import.h new file mode 100644 index 0000000..13f32a1 --- /dev/null +++ b/Include/import.h @@ -0,0 +1,154 @@ + +/* Module definition and import interface */ + +#ifndef Py_IMPORT_H +#define Py_IMPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(_PyInitError) _PyImportZip_Init(void); + +PyMODINIT_FUNC PyInit__imp(void); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(long) PyImport_GetMagicNumber(void); +PyAPI_FUNC(const char *) PyImport_GetMagicTag(void); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule( + const char *name, /* UTF-8 encoded string */ + PyObject *co + ); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx( + const char *name, /* UTF-8 encoded string */ + PyObject *co, + const char *pathname /* decoded from the filesystem encoding */ + ); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleWithPathnames( + const char *name, /* UTF-8 encoded string */ + PyObject *co, + const char *pathname, /* decoded from the filesystem encoding */ + const char *cpathname /* decoded from the filesystem encoding */ + ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject( + PyObject *name, + PyObject *co, + PyObject *pathname, + PyObject *cpathname + ); +#endif +PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_FUNC(PyObject *) PyImport_GetModule(PyObject *name); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); +PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(struct _Py_Identifier *name); +PyAPI_FUNC(PyObject *) _PyImport_AddModuleObject(PyObject *name, + PyObject *modules); +PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); +PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyImport_AddModuleObject( + PyObject *name + ); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyImport_AddModuleObject(PyObject *, PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyImport_AddModule( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyImport_ImportModule( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel( + const char *name, /* UTF-8 encoded string */ + PyObject *globals, + PyObject *locals, + PyObject *fromlist, + int level + ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject( + PyObject *name, + PyObject *globals, + PyObject *locals, + PyObject *fromlist, + int level + ); +#endif + +#define PyImport_ImportModuleEx(n, g, l, f) \ + PyImport_ImportModuleLevel(n, g, l, f, 0) + +PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); +PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); +PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); +PyAPI_FUNC(void) PyImport_Cleanup(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(int) PyImport_ImportFrozenModuleObject( + PyObject *name + ); +#endif +PyAPI_FUNC(int) PyImport_ImportFrozenModule( + const char *name /* UTF-8 encoded string */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyImport_AcquireLock(void); +PyAPI_FUNC(int) _PyImport_ReleaseLock(void); + +PyAPI_FUNC(void) _PyImport_ReInitLock(void); + +PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( + const char *name, /* UTF-8 encoded string */ + PyObject *modules + ); +PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObjectEx(PyObject *, PyObject *, + PyObject *); +PyAPI_FUNC(int) _PyImport_FixupBuiltin( + PyObject *mod, + const char *name, /* UTF-8 encoded string */ + PyObject *modules + ); +PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *, + PyObject *, PyObject *); + +struct _inittab { + const char *name; /* ASCII encoded string */ + PyObject* (*initfunc)(void); +}; +PyAPI_DATA(struct _inittab *) PyImport_Inittab; +PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); +#endif /* Py_LIMITED_API */ + +PyAPI_DATA(PyTypeObject) PyNullImporter_Type; + +PyAPI_FUNC(int) PyImport_AppendInittab( + const char *name, /* ASCII encoded string */ + PyObject* (*initfunc)(void) + ); + +#ifndef Py_LIMITED_API +struct _frozen { + const char *name; /* ASCII encoded string */ + const unsigned char *code; + int size; +}; + +/* Embedding apps may change this pointer to point to their favorite + collection of frozen modules: */ + +PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_IMPORT_H */ diff --git a/Include/intrcheck.h b/Include/intrcheck.h new file mode 100644 index 0000000..2e17336 --- /dev/null +++ b/Include/intrcheck.h @@ -0,0 +1,33 @@ + +#ifndef Py_INTRCHECK_H +#define Py_INTRCHECK_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyOS_InterruptOccurred(void); +PyAPI_FUNC(void) PyOS_InitInterrupts(void); +#ifdef HAVE_FORK +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_FUNC(void) PyOS_BeforeFork(void); +PyAPI_FUNC(void) PyOS_AfterFork_Parent(void); +PyAPI_FUNC(void) PyOS_AfterFork_Child(void); +#endif +#endif +/* Deprecated, please use PyOS_AfterFork_Child() instead */ +PyAPI_FUNC(void) PyOS_AfterFork(void) Py_DEPRECATED(3.7); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyOS_IsMainThread(void); +PyAPI_FUNC(void) _PySignal_AfterFork(void); + +#ifdef MS_WINDOWS +/* windows.h is not included by Python.h so use void* instead of HANDLE */ +PyAPI_FUNC(void*) _PyOS_SigintEvent(void); +#endif +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTRCHECK_H */ diff --git a/Include/iterobject.h b/Include/iterobject.h new file mode 100644 index 0000000..f61726f --- /dev/null +++ b/Include/iterobject.h @@ -0,0 +1,25 @@ +#ifndef Py_ITEROBJECT_H +#define Py_ITEROBJECT_H +/* Iterators (the basic kind, over a sequence) */ +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PySeqIter_Type; +PyAPI_DATA(PyTypeObject) PyCallIter_Type; +PyAPI_DATA(PyTypeObject) PyCmpWrapper_Type; + +#define PySeqIter_Check(op) (Py_TYPE(op) == &PySeqIter_Type) + +PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); + + +#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type) + +PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ITEROBJECT_H */ + diff --git a/Include/listobject.h b/Include/listobject.h new file mode 100644 index 0000000..6057279 --- /dev/null +++ b/Include/listobject.h @@ -0,0 +1,81 @@ + +/* List object interface */ + +/* +Another generally useful object type is a list of object pointers. +This is a mutable type: the list items can be changed, and items can be +added or removed. Out-of-range indices or non-list objects are ignored. + +*** WARNING *** PyList_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the list. Similarly, PyList_GetItem does not increment the +returned item's reference count. +*/ + +#ifndef Py_LISTOBJECT_H +#define Py_LISTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_VAR_HEAD + /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ + PyObject **ob_item; + + /* ob_item contains space for 'allocated' elements. The number + * currently in use is ob_size. + * Invariants: + * 0 <= ob_size <= allocated + * len(list) == ob_size + * ob_item == NULL implies ob_size == allocated == 0 + * list.sort() temporarily sets allocated to -1 to detect mutations. + * + * Items must normally not be NULL, except during construction when + * the list is not yet visible outside the function that builds it. + */ + Py_ssize_t allocated; +} PyListObject; +#endif + +PyAPI_DATA(PyTypeObject) PyList_Type; +PyAPI_DATA(PyTypeObject) PyListIter_Type; +PyAPI_DATA(PyTypeObject) PyListRevIter_Type; +PyAPI_DATA(PyTypeObject) PySortWrapper_Type; + +#define PyList_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) +#define PyList_CheckExact(op) (Py_TYPE(op) == &PyList_Type) + +PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Sort(PyObject *); +PyAPI_FUNC(int) PyList_Reverse(PyObject *); +PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); + +PyAPI_FUNC(int) PyList_ClearFreeList(void); +PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); +#endif + +/* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API +#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) +#define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) +#define PyList_GET_SIZE(op) (assert(PyList_Check(op)),Py_SIZE(op)) +#define _PyList_ITEMS(op) (((PyListObject *)(op))->ob_item) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LISTOBJECT_H */ diff --git a/Include/longintrepr.h b/Include/longintrepr.h new file mode 100644 index 0000000..ff4155f --- /dev/null +++ b/Include/longintrepr.h @@ -0,0 +1,99 @@ +#ifndef Py_LIMITED_API +#ifndef Py_LONGINTREPR_H +#define Py_LONGINTREPR_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is published for the benefit of "friends" marshal.c and _decimal.c. */ + +/* Parameters of the integer representation. There are two different + sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit + integer type, and one set for 15-bit digits with each digit stored in an + unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at + configure time or in pyport.h, is used to decide which digit size to use. + + Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits' + should be an unsigned integer type able to hold all integers up to + PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type, + and that overflow is handled by taking the result modulo 2**N for some N > + PyLong_SHIFT. The majority of the code doesn't care about the precise + value of PyLong_SHIFT, but there are some notable exceptions: + + - long_pow() requires that PyLong_SHIFT be divisible by 5 + + - PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8 + + - long_hash() requires that PyLong_SHIFT is *strictly* less than the number + of bits in an unsigned long, as do the PyLong <-> long (or unsigned long) + conversion functions + + - the Python int <-> size_t/Py_ssize_t conversion functions expect that + PyLong_SHIFT is strictly less than the number of bits in a size_t + + - the marshal code currently expects that PyLong_SHIFT is a multiple of 15 + + - NSMALLNEGINTS and NSMALLPOSINTS should be small enough to fit in a single + digit; with the current values this forces PyLong_SHIFT >= 9 + + The values 15 and 30 should fit all of the above requirements, on any + platform. +*/ + +#if PYLONG_BITS_IN_DIGIT == 30 +typedef uint32_t digit; +typedef int32_t sdigit; /* signed variant of digit */ +typedef uint64_t twodigits; +typedef int64_t stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 30 +#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */ +#elif PYLONG_BITS_IN_DIGIT == 15 +typedef unsigned short digit; +typedef short sdigit; /* signed variant of digit */ +typedef unsigned long twodigits; +typedef long stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 15 +#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */ +#else +#error "PYLONG_BITS_IN_DIGIT should be 15 or 30" +#endif +#define PyLong_BASE ((digit)1 << PyLong_SHIFT) +#define PyLong_MASK ((digit)(PyLong_BASE - 1)) + +#if PyLong_SHIFT % 5 != 0 +#error "longobject.c requires that PyLong_SHIFT be divisible by 5" +#endif + +/* Long integer representation. + The absolute value of a number is equal to + SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) + Negative numbers are represented with ob_size < 0; + zero is represented by ob_size == 0. + In a normalized number, ob_digit[abs(ob_size)-1] (the most significant + digit) is never zero. Also, in all cases, for all valid i, + 0 <= ob_digit[i] <= MASK. + The allocation function takes care of allocating extra memory + so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. + + CAUTION: Generic code manipulating subtypes of PyVarObject has to + aware that ints abuse ob_size's sign bit. +*/ + +struct _longobject { + PyObject_VAR_HEAD + digit ob_digit[1]; +}; + +PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); + +/* Return a copy of src. */ +PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGINTREPR_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/longobject.h b/Include/longobject.h new file mode 100644 index 0000000..7bdd047 --- /dev/null +++ b/Include/longobject.h @@ -0,0 +1,220 @@ +#ifndef Py_LONGOBJECT_H +#define Py_LONGOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Long (arbitrary precision) integer object interface */ + +typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ + +PyAPI_DATA(PyTypeObject) PyLong_Type; + +#define PyLong_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) +#define PyLong_CheckExact(op) (Py_TYPE(op) == &PyLong_Type) + +PyAPI_FUNC(PyObject *) PyLong_FromLong(long); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); +PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); +PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); +PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); +PyAPI_FUNC(long) PyLong_AsLong(PyObject *); +PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); +PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); +PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); + +/* It may be useful in the future. I've added it in the PyInt -> PyLong + cleanup to keep the extra information. [CH] */ +#define PyLong_AS_LONG(op) PyLong_AsLong(op) + +/* Issue #1983: pid_t can be longer than a C long on some systems */ +#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT +#define _Py_PARSE_PID "i" +#define PyLong_FromPid PyLong_FromLong +#define PyLong_AsPid PyLong_AsLong +#elif SIZEOF_PID_T == SIZEOF_LONG +#define _Py_PARSE_PID "l" +#define PyLong_FromPid PyLong_FromLong +#define PyLong_AsPid PyLong_AsLong +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG +#define _Py_PARSE_PID "L" +#define PyLong_FromPid PyLong_FromLongLong +#define PyLong_AsPid PyLong_AsLongLong +#else +#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" +#endif /* SIZEOF_PID_T */ + +#if SIZEOF_VOID_P == SIZEOF_INT +# define _Py_PARSE_INTPTR "i" +# define _Py_PARSE_UINTPTR "I" +#elif SIZEOF_VOID_P == SIZEOF_LONG +# define _Py_PARSE_INTPTR "l" +# define _Py_PARSE_UINTPTR "k" +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_VOID_P == SIZEOF_LONG_LONG +# define _Py_PARSE_INTPTR "L" +# define _Py_PARSE_UINTPTR "K" +#else +# error "void* different in size from int, long and long long" +#endif /* SIZEOF_VOID_P */ + +/* Used by Python/mystrtoul.c, _PyBytes_FromHex(), + _PyBytes_DecodeEscapeRecode(), etc. */ +#ifndef Py_LIMITED_API +PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; +#endif + +/* _PyLong_Frexp returns a double x and an exponent e such that the + true value is approximately equal to x * 2**e. e is >= 0. x is + 0.0 if and only if the input is 0 (in which case, e and x are both + zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is + possible if the number of bits doesn't fit into a Py_ssize_t, sets + OverflowError and returns -1.0 for x, 0 for e. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); +#endif + +PyAPI_FUNC(double) PyLong_AsDouble(PyObject *); +PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *); +PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *); + +PyAPI_FUNC(PyObject *) PyLong_FromLongLong(long long); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned long long); +PyAPI_FUNC(long long) PyLong_AsLongLong(PyObject *); +PyAPI_FUNC(unsigned long long) PyLong_AsUnsignedLongLong(PyObject *); +PyAPI_FUNC(unsigned long long) PyLong_AsUnsignedLongLongMask(PyObject *); +PyAPI_FUNC(long long) PyLong_AsLongLongAndOverflow(PyObject *, int *); + +PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int) Py_DEPRECATED(3.3); +PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base); +PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int); +#endif + +#ifndef Py_LIMITED_API +/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. + v must not be NULL, and must be a normalized long. + There are no error cases. +*/ +PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); + + +/* _PyLong_NumBits. Return the number of bits needed to represent the + absolute value of a long. For example, this returns 1 for 1 and -1, 2 + for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. + v must not be NULL, and must be a normalized long. + (size_t)-1 is returned and OverflowError set if the true result doesn't + fit in a size_t. +*/ +PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); + +/* _PyLong_DivmodNear. Given integers a and b, compute the nearest + integer q to the exact quotient a / b, rounding to the nearest even integer + in the case of a tie. Return (q, r), where r = a - q*b. The remainder r + will satisfy abs(r) <= abs(b)/2, with equality possible only if q is + even. +*/ +PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); + +/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in + base 256, and return a Python int with the same numeric value. + If n is 0, the integer is 0. Else: + If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; + else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the + LSB. + If is_signed is 0/false, view the bytes as a non-negative integer. + If is_signed is 1/true, view the bytes as a 2's-complement integer, + non-negative if bit 0x80 of the MSB is clear, negative if set. + Error returns: + + Return NULL with the appropriate exception set if there's not + enough memory to create the Python int. +*/ +PyAPI_FUNC(PyObject *) _PyLong_FromByteArray( + const unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long + v to a base-256 integer, stored in array bytes. Normally return 0, + return -1 on error. + If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at + bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and + the LSB at bytes[n-1]. + If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes + are filled and there's nothing special about bit 0x80 of the MSB. + If is_signed is 1/true, bytes is filled with the 2's-complement + representation of v's value. Bit 0x80 of the MSB is the sign bit. + Error returns (-1): + + is_signed is 0 and v < 0. TypeError is set in this case, and bytes + isn't altered. + + n isn't big enough to hold the full mathematical value of v. For + example, if is_signed is 0 and there are more digits in the v than + fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of + being large enough to hold a sign bit. OverflowError is set in this + case, but bytes holds the least-significant n bytes of the true value. +*/ +PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_FromNbInt: Convert the given object to a PyLongObject + using the nb_int slot, if available. Raise TypeError if either the + nb_int slot is not available or the result of the call to nb_int + returns something not of type int. +*/ +PyAPI_FUNC(PyLongObject *)_PyLong_FromNbInt(PyObject *); + +/* _PyLong_Format: Convert the long to a string object with given base, + appending a base prefix of 0[box] if base is 2, 8 or 16. */ +PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base); + +PyAPI_FUNC(int) _PyLong_FormatWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + int base, + int alternate); + +PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( + _PyBytesWriter *writer, + char *str, + PyObject *obj, + int base, + int alternate); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif /* Py_LIMITED_API */ + +/* These aren't really part of the int object, but they're handy. The + functions are in Python/mystrtoul.c. + */ +PyAPI_FUNC(unsigned long) PyOS_strtoul(const char *, char **, int); +PyAPI_FUNC(long) PyOS_strtol(const char *, char **, int); + +#ifndef Py_LIMITED_API +/* For use by the gcd function in mathmodule.c */ +PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); +#endif /* !Py_LIMITED_API */ + +#ifndef Py_LIMITED_API +PyAPI_DATA(PyObject *) _PyLong_Zero; +PyAPI_DATA(PyObject *) _PyLong_One; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGOBJECT_H */ diff --git a/Include/marshal.h b/Include/marshal.h new file mode 100644 index 0000000..09d9337 --- /dev/null +++ b/Include/marshal.h @@ -0,0 +1,28 @@ + +/* Interface for marshal.c */ + +#ifndef Py_MARSHAL_H +#define Py_MARSHAL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define Py_MARSHAL_VERSION 4 + +PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int); +PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int); +PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *); +PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *); +#endif +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(const char *, + Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MARSHAL_H */ diff --git a/Include/memoryobject.h b/Include/memoryobject.h new file mode 100644 index 0000000..990a716 --- /dev/null +++ b/Include/memoryobject.h @@ -0,0 +1,72 @@ +/* Memory view object. In Python this is available as "memoryview". */ + +#ifndef Py_MEMORYOBJECT_H +#define Py_MEMORYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; +#endif +PyAPI_DATA(PyTypeObject) PyMemoryView_Type; + +#define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type) + +#ifndef Py_LIMITED_API +/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ +#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view) +/* Get a pointer to the exporting object (this may be NULL!). */ +#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj) +#endif + +PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyMemoryView_FromMemory(char *mem, Py_ssize_t size, + int flags); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info); +#endif +PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, + int buffertype, + char order); + + +/* The structs are declared here so that macros can work, but they shouldn't + be considered public. Don't access their fields directly, use the macros + and functions instead! */ +#ifndef Py_LIMITED_API +#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ +#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ +typedef struct { + PyObject_HEAD + int flags; /* state flags */ + Py_ssize_t exports; /* number of direct memoryview exports */ + Py_buffer master; /* snapshot buffer obtained from the original exporter */ +} _PyManagedBufferObject; + + +/* memoryview state flags */ +#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ +#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ +#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ +#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ +#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ + +typedef struct { + PyObject_VAR_HEAD + _PyManagedBufferObject *mbuf; /* managed buffer */ + Py_hash_t hash; /* hash value for read-only views */ + int flags; /* state flags */ + Py_ssize_t exports; /* number of buffer re-exports */ + Py_buffer view; /* private copy of the exporter's view */ + PyObject *weakreflist; + Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ +} PyMemoryViewObject; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MEMORYOBJECT_H */ diff --git a/Include/metagrammar.h b/Include/metagrammar.h new file mode 100644 index 0000000..15c8ef8 --- /dev/null +++ b/Include/metagrammar.h @@ -0,0 +1,18 @@ +#ifndef Py_METAGRAMMAR_H +#define Py_METAGRAMMAR_H +#ifdef __cplusplus +extern "C" { +#endif + + +#define MSTART 256 +#define RULE 257 +#define RHS 258 +#define ALT 259 +#define ITEM 260 +#define ATOM 261 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METAGRAMMAR_H */ diff --git a/Include/methodobject.h b/Include/methodobject.h new file mode 100644 index 0000000..ea35d86 --- /dev/null +++ b/Include/methodobject.h @@ -0,0 +1,135 @@ + +/* Method object interface */ + +#ifndef Py_METHODOBJECT_H +#define Py_METHODOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* This is about the type 'builtin_function_or_method', + not Python methods in user-defined classes. See classobject.h + for the latter. */ + +PyAPI_DATA(PyTypeObject) PyCFunction_Type; + +#define PyCFunction_Check(op) (Py_TYPE(op) == &PyCFunction_Type) + +typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); +typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); +typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, + PyObject *); +typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *, + PyObject *const *, Py_ssize_t, + PyObject *); +typedef PyObject *(*PyNoArgsFunction)(PyObject *); + +PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *); +PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *); +PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#ifndef Py_LIMITED_API +#define PyCFunction_GET_FUNCTION(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_meth) +#define PyCFunction_GET_SELF(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_STATIC ? \ + NULL : ((PyCFunctionObject *)func) -> m_self) +#define PyCFunction_GET_FLAGS(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_flags) +#endif +PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyCFunction_FastCallDict(PyObject *func, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyCFunction_FastCallKeywords(PyObject *func, + PyObject *const *stack, + Py_ssize_t nargs, + PyObject *kwnames); +#endif + +struct PyMethodDef { + const char *ml_name; /* The name of the built-in function/method */ + PyCFunction ml_meth; /* The C function that implements it */ + int ml_flags; /* Combination of METH_xxx flags, which mostly + describe the args expected by the C func */ + const char *ml_doc; /* The __doc__ attribute, or NULL */ +}; +typedef struct PyMethodDef PyMethodDef; + +#define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) +PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, + PyObject *); + +/* Flag passed to newmethodobject */ +/* #define METH_OLDARGS 0x0000 -- unsupported now */ +#define METH_VARARGS 0x0001 +#define METH_KEYWORDS 0x0002 +/* METH_NOARGS and METH_O must not be combined with the flags above. */ +#define METH_NOARGS 0x0004 +#define METH_O 0x0008 + +/* METH_CLASS and METH_STATIC are a little different; these control + the construction of methods for a class. These cannot be used for + functions in modules. */ +#define METH_CLASS 0x0010 +#define METH_STATIC 0x0020 + +/* METH_COEXIST allows a method to be entered even though a slot has + already filled the entry. When defined, the flag allows a separate + method, "__contains__" for example, to coexist with a defined + slot like sq_contains. */ + +#define METH_COEXIST 0x0040 + +#ifndef Py_LIMITED_API +#define METH_FASTCALL 0x0080 +#endif + +/* This bit is preserved for Stackless Python */ +#ifdef STACKLESS +#define METH_STACKLESS 0x0100 +#else +#define METH_STACKLESS 0x0000 +#endif + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + PyMethodDef *m_ml; /* Description of the C function to call */ + PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ + PyObject *m_module; /* The __module__ attribute, can be anything */ + PyObject *m_weakreflist; /* List of weak references */ +} PyCFunctionObject; + +PyAPI_FUNC(PyObject *) _PyMethodDef_RawFastCallDict( + PyMethodDef *method, + PyObject *self, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyMethodDef_RawFastCallKeywords( + PyMethodDef *method, + PyObject *self, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames); +#endif + +PyAPI_FUNC(int) PyCFunction_ClearFreeList(void); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyCFunction_DebugMallocStats(FILE *out); +PyAPI_FUNC(void) _PyMethod_DebugMallocStats(FILE *out); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METHODOBJECT_H */ diff --git a/Include/modsupport.h b/Include/modsupport.h new file mode 100644 index 0000000..a238bef --- /dev/null +++ b/Include/modsupport.h @@ -0,0 +1,229 @@ + +#ifndef Py_MODSUPPORT_H +#define Py_MODSUPPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Module support interface */ + +#include + +/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier + to mean Py_ssize_t */ +#ifdef PY_SSIZE_T_CLEAN +#define PyArg_Parse _PyArg_Parse_SizeT +#define PyArg_ParseTuple _PyArg_ParseTuple_SizeT +#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT +#define PyArg_VaParse _PyArg_VaParse_SizeT +#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT +#define Py_BuildValue _Py_BuildValue_SizeT +#define Py_VaBuildValue _Py_VaBuildValue_SizeT +#ifndef Py_LIMITED_API +#define _Py_VaBuildStack _Py_VaBuildStack_SizeT +#endif +#else +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); +PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); +#endif /* !Py_LIMITED_API */ +#endif + +/* Due to a glitch in 3.2, the _SizeT versions weren't exported from the DLL. */ +#if !defined(PY_SSIZE_T_CLEAN) || !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); +PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); +PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, ...); +PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); +PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, va_list); +#endif +PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *); +PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); +PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); +PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); + + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyArg_UnpackStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *name, + Py_ssize_t min, + Py_ssize_t max, + ...); + +PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); +PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); +#define _PyArg_NoKeywords(funcname, kwargs) \ + ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) +#define _PyArg_NoPositional(funcname, args) \ + ((args) == NULL || _PyArg_NoPositional((funcname), (args))) + +#endif + +PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject **) _Py_VaBuildStack( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); +#endif + +#ifndef Py_LIMITED_API +typedef struct _PyArg_Parser { + const char *format; + const char * const *keywords; + const char *fname; + const char *custom_msg; + int pos; /* number of positional-only arguments */ + int min; /* minimal number of arguments */ + int max; /* maximal number of positional arguments */ + PyObject *kwtuple; /* tuple of keyword parameter names */ + struct _PyArg_Parser *next; +} _PyArg_Parser; +#ifdef PY_SSIZE_T_CLEAN +#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT +#define _PyArg_ParseStack _PyArg_ParseStack_SizeT +#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT +#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT +#endif +PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, ...); +PyAPI_FUNC(int) _PyArg_ParseStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *format, + ...); +PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames, + struct _PyArg_Parser *, + ...); +PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, va_list); +void _PyArg_Fini(void); +#endif /* Py_LIMITED_API */ + +PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); +PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +PyAPI_FUNC(int) PyModule_SetDocString(PyObject *, const char *); +PyAPI_FUNC(int) PyModule_AddFunctions(PyObject *, PyMethodDef *); +PyAPI_FUNC(int) PyModule_ExecDef(PyObject *module, PyModuleDef *def); +#endif + +#define Py_CLEANUP_SUPPORTED 0x20000 + +#define PYTHON_API_VERSION 1013 +#define PYTHON_API_STRING "1013" +/* The API version is maintained (independently from the Python version) + so we can detect mismatches between the interpreter and dynamically + loaded modules. These are diagnosed by an error message but + the module is still loaded (because the mismatch can only be tested + after loading the module). The error message is intended to + explain the core dump a few seconds later. + + The symbol PYTHON_API_STRING defines the same value as a string + literal. *** PLEASE MAKE SURE THE DEFINITIONS MATCH. *** + + Please add a line or two to the top of this log for each API + version change: + + 22-Feb-2006 MvL 1013 PEP 353 - long indices for sequence lengths + + 19-Aug-2002 GvR 1012 Changes to string object struct for + interning changes, saving 3 bytes. + + 17-Jul-2001 GvR 1011 Descr-branch, just to be on the safe side + + 25-Jan-2001 FLD 1010 Parameters added to PyCode_New() and + PyFrame_New(); Python 2.1a2 + + 14-Mar-2000 GvR 1009 Unicode API added + + 3-Jan-1999 GvR 1007 Decided to change back! (Don't reuse 1008!) + + 3-Dec-1998 GvR 1008 Python 1.5.2b1 + + 18-Jan-1997 GvR 1007 string interning and other speedups + + 11-Oct-1996 GvR renamed Py_Ellipses to Py_Ellipsis :-( + + 30-Jul-1996 GvR Slice and ellipses syntax added + + 23-Jul-1996 GvR For 1.4 -- better safe than sorry this time :-) + + 7-Nov-1995 GvR Keyword arguments (should've been done at 1.3 :-( ) + + 10-Jan-1995 GvR Renamed globals to new naming scheme + + 9-Jan-1995 GvR Initial version (incompatible with older API) +*/ + +/* The PYTHON_ABI_VERSION is introduced in PEP 384. For the lifetime of + Python 3, it will stay at the value of 3; changes to the limited API + must be performed in a strictly backwards-compatible manner. */ +#define PYTHON_ABI_VERSION 3 +#define PYTHON_ABI_STRING "3" + +#ifdef Py_TRACE_REFS + /* When we are tracing reference counts, rename module creation functions so + modules compiled with incompatible settings will generate a + link-time error. */ + #define PyModule_Create2 PyModule_Create2TraceRefs + #define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs +#endif + +PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*, + int apiver); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(struct PyModuleDef*, + int apiver); +#endif + +#ifdef Py_LIMITED_API +#define PyModule_Create(module) \ + PyModule_Create2(module, PYTHON_ABI_VERSION) +#else +#define PyModule_Create(module) \ + PyModule_Create2(module, PYTHON_API_VERSION) +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +PyAPI_FUNC(PyObject *) PyModule_FromDefAndSpec2(PyModuleDef *def, + PyObject *spec, + int module_api_version); + +#ifdef Py_LIMITED_API +#define PyModule_FromDefAndSpec(module, spec) \ + PyModule_FromDefAndSpec2(module, spec, PYTHON_ABI_VERSION) +#else +#define PyModule_FromDefAndSpec(module, spec) \ + PyModule_FromDefAndSpec2(module, spec, PYTHON_API_VERSION) +#endif /* Py_LIMITED_API */ +#endif /* New in 3.5 */ + +#ifndef Py_LIMITED_API +PyAPI_DATA(const char *) _Py_PackageContext; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODSUPPORT_H */ diff --git a/Include/moduleobject.h b/Include/moduleobject.h new file mode 100644 index 0000000..1d8fe46 --- /dev/null +++ b/Include/moduleobject.h @@ -0,0 +1,89 @@ + +/* Module object interface */ + +#ifndef Py_MODULEOBJECT_H +#define Py_MODULEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyModule_Type; + +#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) +#define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type) + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyModule_NewObject( + PyObject *name + ); +#endif +PyAPI_FUNC(PyObject *) PyModule_New( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyModule_GetNameObject(PyObject *); +#endif +PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); +PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *) Py_DEPRECATED(3.2); +PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyModule_Clear(PyObject *); +PyAPI_FUNC(void) _PyModule_ClearDict(PyObject *); +#endif +PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*); +PyAPI_FUNC(void*) PyModule_GetState(PyObject*); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +PyAPI_FUNC(PyObject *) PyModuleDef_Init(struct PyModuleDef*); +PyAPI_DATA(PyTypeObject) PyModuleDef_Type; +#endif + +typedef struct PyModuleDef_Base { + PyObject_HEAD + PyObject* (*m_init)(void); + Py_ssize_t m_index; + PyObject* m_copy; +} PyModuleDef_Base; + +#define PyModuleDef_HEAD_INIT { \ + PyObject_HEAD_INIT(NULL) \ + NULL, /* m_init */ \ + 0, /* m_index */ \ + NULL, /* m_copy */ \ + } + +struct PyModuleDef_Slot; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +typedef struct PyModuleDef_Slot{ + int slot; + void *value; +} PyModuleDef_Slot; + +#define Py_mod_create 1 +#define Py_mod_exec 2 + +#ifndef Py_LIMITED_API +#define _Py_mod_LAST_SLOT 2 +#endif + +#endif /* New in 3.5 */ + +typedef struct PyModuleDef{ + PyModuleDef_Base m_base; + const char* m_name; + const char* m_doc; + Py_ssize_t m_size; + PyMethodDef *m_methods; + struct PyModuleDef_Slot* m_slots; + traverseproc m_traverse; + inquiry m_clear; + freefunc m_free; +} PyModuleDef; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODULEOBJECT_H */ diff --git a/Include/namespaceobject.h b/Include/namespaceobject.h new file mode 100644 index 0000000..0c8d95c --- /dev/null +++ b/Include/namespaceobject.h @@ -0,0 +1,19 @@ + +/* simple namespace object interface */ + +#ifndef NAMESPACEOBJECT_H +#define NAMESPACEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_DATA(PyTypeObject) _PyNamespace_Type; + +PyAPI_FUNC(PyObject *) _PyNamespace_New(PyObject *kwds); +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !NAMESPACEOBJECT_H */ diff --git a/Include/node.h b/Include/node.h new file mode 100644 index 0000000..40596df --- /dev/null +++ b/Include/node.h @@ -0,0 +1,44 @@ + +/* Parse tree node interface */ + +#ifndef Py_NODE_H +#define Py_NODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _node { + short n_type; + char *n_str; + int n_lineno; + int n_col_offset; + int n_nchildren; + struct _node *n_child; +} node; + +PyAPI_FUNC(node *) PyNode_New(int type); +PyAPI_FUNC(int) PyNode_AddChild(node *n, int type, + char *str, int lineno, int col_offset); +PyAPI_FUNC(void) PyNode_Free(node *n); +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyNode_SizeOf(node *n); +#endif + +/* Node access functions */ +#define NCH(n) ((n)->n_nchildren) + +#define CHILD(n, i) (&(n)->n_child[i]) +#define RCHILD(n, i) (CHILD(n, NCH(n) + i)) +#define TYPE(n) ((n)->n_type) +#define STR(n) ((n)->n_str) +#define LINENO(n) ((n)->n_lineno) + +/* Assert that the type of a node is what we expect */ +#define REQ(n, type) assert(TYPE(n) == (type)) + +PyAPI_FUNC(void) PyNode_ListTree(node *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_NODE_H */ diff --git a/Include/object.h b/Include/object.h new file mode 100644 index 0000000..c772dea --- /dev/null +++ b/Include/object.h @@ -0,0 +1,1104 @@ +#ifndef Py_OBJECT_H +#define Py_OBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Object and type object interface */ + +/* +Objects are structures allocated on the heap. Special rules apply to +the use of objects to ensure they are properly garbage-collected. +Objects are never allocated statically or on the stack; they must be +accessed through special macros and functions only. (Type objects are +exceptions to the first rule; the standard types are represented by +statically initialized type objects, although work on type/class unification +for Python 2.2 made it possible to have heap-allocated type objects too). + +An object has a 'reference count' that is increased or decreased when a +pointer to the object is copied or deleted; when the reference count +reaches zero there are no references to the object left and it can be +removed from the heap. + +An object has a 'type' that determines what it represents and what kind +of data it contains. An object's type is fixed when it is created. +Types themselves are represented as objects; an object contains a +pointer to the corresponding type object. The type itself has a type +pointer pointing to the object representing the type 'type', which +contains a pointer to itself!). + +Objects do not float around in memory; once allocated an object keeps +the same size and address. Objects that must hold variable-size data +can contain pointers to variable-size parts of the object. Not all +objects of the same type have the same size; but the size cannot change +after allocation. (These restrictions are made so a reference to an +object can be simply a pointer -- moving an object would require +updating all the pointers, and changing an object's size would require +moving it if there was another object right next to it.) + +Objects are always accessed through pointers of the type 'PyObject *'. +The type 'PyObject' is a structure that only contains the reference count +and the type pointer. The actual memory allocated for an object +contains other data that can only be accessed after casting the pointer +to a pointer to a longer structure type. This longer type must start +with the reference count and type fields; the macro PyObject_HEAD should be +used for this (to accommodate for future changes). The implementation +of a particular object type can cast the object pointer to the proper +type and back. + +A standard interface exists for objects that contain an array of items +whose size is determined when the object is allocated. +*/ + +/* Py_DEBUG implies Py_TRACE_REFS. */ +#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS) +#define Py_TRACE_REFS +#endif + +/* Py_TRACE_REFS implies Py_REF_DEBUG. */ +#if defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) +#define Py_REF_DEBUG +#endif + +#if defined(Py_LIMITED_API) && defined(Py_REF_DEBUG) +#error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG +#endif + + +#ifdef Py_TRACE_REFS +/* Define pointers to support a doubly-linked list of all live heap objects. */ +#define _PyObject_HEAD_EXTRA \ + struct _object *_ob_next; \ + struct _object *_ob_prev; + +#define _PyObject_EXTRA_INIT 0, 0, + +#else +#define _PyObject_HEAD_EXTRA +#define _PyObject_EXTRA_INIT +#endif + +/* PyObject_HEAD defines the initial segment of every PyObject. */ +#define PyObject_HEAD PyObject ob_base; + +#define PyObject_HEAD_INIT(type) \ + { _PyObject_EXTRA_INIT \ + 1, type }, + +#define PyVarObject_HEAD_INIT(type, size) \ + { PyObject_HEAD_INIT(type) size }, + +/* PyObject_VAR_HEAD defines the initial segment of all variable-size + * container objects. These end with a declaration of an array with 1 + * element, but enough space is malloc'ed so that the array actually + * has room for ob_size elements. Note that ob_size is an element count, + * not necessarily a byte count. + */ +#define PyObject_VAR_HEAD PyVarObject ob_base; +#define Py_INVALID_SIZE (Py_ssize_t)-1 + +/* Nothing is actually declared to be a PyObject, but every pointer to + * a Python object can be cast to a PyObject*. This is inheritance built + * by hand. Similarly every pointer to a variable-size Python object can, + * in addition, be cast to PyVarObject*. + */ +typedef struct _object { + _PyObject_HEAD_EXTRA + Py_ssize_t ob_refcnt; + struct _typeobject *ob_type; +} PyObject; + +typedef struct { + PyObject ob_base; + Py_ssize_t ob_size; /* Number of items in variable part */ +} PyVarObject; + +#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) + +#ifndef Py_LIMITED_API +/********************* String Literals ****************************************/ +/* This structure helps managing static strings. The basic usage goes like this: + Instead of doing + + r = PyObject_CallMethod(o, "foo", "args", ...); + + do + + _Py_IDENTIFIER(foo); + ... + r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); + + PyId_foo is a static variable, either on block level or file level. On first + usage, the string "foo" is interned, and the structures are linked. On interpreter + shutdown, all strings are released (through _PyUnicode_ClearStaticStrings). + + Alternatively, _Py_static_string allows choosing the variable name. + _PyUnicode_FromId returns a borrowed reference to the interned string. + _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. +*/ +typedef struct _Py_Identifier { + struct _Py_Identifier *next; + const char* string; + PyObject *object; +} _Py_Identifier; + +#define _Py_static_string_init(value) { .next = NULL, .string = value, .object = NULL } +#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) +#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) + +#endif /* !Py_LIMITED_API */ + +/* +Type objects contain a string containing the type name (to help somewhat +in debugging), the allocation parameters (see PyObject_New() and +PyObject_NewVar()), +and methods for accessing objects of the type. Methods are optional, a +nil pointer meaning that particular kind of access is not available for +this type. The Py_DECREF() macro uses the tp_dealloc method without +checking for a nil pointer; it should always be implemented except if +the implementation can guarantee that the reference count will never +reach zero (e.g., for statically allocated type objects). + +NB: the methods for certain type groups are now contained in separate +method blocks. +*/ + +typedef PyObject * (*unaryfunc)(PyObject *); +typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); +typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); +typedef int (*inquiry)(PyObject *); +typedef Py_ssize_t (*lenfunc)(PyObject *); +typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); +typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); +typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *); +typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *); + +#ifndef Py_LIMITED_API +/* buffer interface */ +typedef struct bufferinfo { + void *buf; + PyObject *obj; /* owned reference */ + Py_ssize_t len; + Py_ssize_t itemsize; /* This is Py_ssize_t so it can be + pointed to by strides in simple case.*/ + int readonly; + int ndim; + char *format; + Py_ssize_t *shape; + Py_ssize_t *strides; + Py_ssize_t *suboffsets; + void *internal; +} Py_buffer; + +typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); +typedef void (*releasebufferproc)(PyObject *, Py_buffer *); + +/* Maximum number of dimensions */ +#define PyBUF_MAX_NDIM 64 + +/* Flags for getting buffers */ +#define PyBUF_SIMPLE 0 +#define PyBUF_WRITABLE 0x0001 +/* we used to include an E, backwards compatible alias */ +#define PyBUF_WRITEABLE PyBUF_WRITABLE +#define PyBUF_FORMAT 0x0004 +#define PyBUF_ND 0x0008 +#define PyBUF_STRIDES (0x0010 | PyBUF_ND) +#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) +#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) +#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) +#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) + +#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) +#define PyBUF_CONTIG_RO (PyBUF_ND) + +#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) +#define PyBUF_STRIDED_RO (PyBUF_STRIDES) + +#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) + +#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) + + +#define PyBUF_READ 0x100 +#define PyBUF_WRITE 0x200 + +/* End buffer interface */ +#endif /* Py_LIMITED_API */ + +typedef int (*objobjproc)(PyObject *, PyObject *); +typedef int (*visitproc)(PyObject *, void *); +typedef int (*traverseproc)(PyObject *, visitproc, void *); + +#ifndef Py_LIMITED_API +typedef struct { + /* Number implementations must check *both* + arguments for proper type and implement the necessary conversions + in the slot functions themselves. */ + + binaryfunc nb_add; + binaryfunc nb_subtract; + binaryfunc nb_multiply; + binaryfunc nb_remainder; + binaryfunc nb_divmod; + ternaryfunc nb_power; + unaryfunc nb_negative; + unaryfunc nb_positive; + unaryfunc nb_absolute; + inquiry nb_bool; + unaryfunc nb_invert; + binaryfunc nb_lshift; + binaryfunc nb_rshift; + binaryfunc nb_and; + binaryfunc nb_xor; + binaryfunc nb_or; + unaryfunc nb_int; + void *nb_reserved; /* the slot formerly known as nb_long */ + unaryfunc nb_float; + + binaryfunc nb_inplace_add; + binaryfunc nb_inplace_subtract; + binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_remainder; + ternaryfunc nb_inplace_power; + binaryfunc nb_inplace_lshift; + binaryfunc nb_inplace_rshift; + binaryfunc nb_inplace_and; + binaryfunc nb_inplace_xor; + binaryfunc nb_inplace_or; + + binaryfunc nb_floor_divide; + binaryfunc nb_true_divide; + binaryfunc nb_inplace_floor_divide; + binaryfunc nb_inplace_true_divide; + + unaryfunc nb_index; + + binaryfunc nb_matrix_multiply; + binaryfunc nb_inplace_matrix_multiply; +} PyNumberMethods; + +typedef struct { + lenfunc sq_length; + binaryfunc sq_concat; + ssizeargfunc sq_repeat; + ssizeargfunc sq_item; + void *was_sq_slice; + ssizeobjargproc sq_ass_item; + void *was_sq_ass_slice; + objobjproc sq_contains; + + binaryfunc sq_inplace_concat; + ssizeargfunc sq_inplace_repeat; +} PySequenceMethods; + +typedef struct { + lenfunc mp_length; + binaryfunc mp_subscript; + objobjargproc mp_ass_subscript; +} PyMappingMethods; + +typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; +} PyAsyncMethods; + +typedef struct { + getbufferproc bf_getbuffer; + releasebufferproc bf_releasebuffer; +} PyBufferProcs; +#endif /* Py_LIMITED_API */ + +typedef void (*freefunc)(void *); +typedef void (*destructor)(PyObject *); +#ifndef Py_LIMITED_API +/* We can't provide a full compile-time check that limited-API + users won't implement tp_print. However, not defining printfunc + and making tp_print of a different function pointer type + should at least cause a warning in most cases. */ +typedef int (*printfunc)(PyObject *, FILE *, int); +#endif +typedef PyObject *(*getattrfunc)(PyObject *, char *); +typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); +typedef int (*setattrfunc)(PyObject *, char *, PyObject *); +typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *); +typedef PyObject *(*reprfunc)(PyObject *); +typedef Py_hash_t (*hashfunc)(PyObject *); +typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); +typedef PyObject *(*getiterfunc) (PyObject *); +typedef PyObject *(*iternextfunc) (PyObject *); +typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*initproc)(PyObject *, PyObject *, PyObject *); +typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); +typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); + +#ifdef Py_LIMITED_API +typedef struct _typeobject PyTypeObject; /* opaque */ +#else +typedef struct _typeobject { + PyObject_VAR_HEAD + const char *tp_name; /* For printing, in format "." */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ + + /* Methods to implement standard operations */ + + destructor tp_dealloc; + printfunc tp_print; + getattrfunc tp_getattr; + setattrfunc tp_setattr; + PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) + or tp_reserved (Python 3) */ + reprfunc tp_repr; + + /* Method suites for standard classes */ + + PyNumberMethods *tp_as_number; + PySequenceMethods *tp_as_sequence; + PyMappingMethods *tp_as_mapping; + + /* More standard operations (here for binary compatibility) */ + + hashfunc tp_hash; + ternaryfunc tp_call; + reprfunc tp_str; + getattrofunc tp_getattro; + setattrofunc tp_setattro; + + /* Functions to access object as input/output buffer */ + PyBufferProcs *tp_as_buffer; + + /* Flags to define presence of optional/expanded features */ + unsigned long tp_flags; + + const char *tp_doc; /* Documentation string */ + + /* Assigned meaning in release 2.0 */ + /* call function for all accessible objects */ + traverseproc tp_traverse; + + /* delete references to contained objects */ + inquiry tp_clear; + + /* Assigned meaning in release 2.1 */ + /* rich comparisons */ + richcmpfunc tp_richcompare; + + /* weak reference enabler */ + Py_ssize_t tp_weaklistoffset; + + /* Iterators */ + getiterfunc tp_iter; + iternextfunc tp_iternext; + + /* Attribute descriptor and subclassing stuff */ + struct PyMethodDef *tp_methods; + struct PyMemberDef *tp_members; + struct PyGetSetDef *tp_getset; + struct _typeobject *tp_base; + PyObject *tp_dict; + descrgetfunc tp_descr_get; + descrsetfunc tp_descr_set; + Py_ssize_t tp_dictoffset; + initproc tp_init; + allocfunc tp_alloc; + newfunc tp_new; + freefunc tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ + PyObject *tp_bases; + PyObject *tp_mro; /* method resolution order */ + PyObject *tp_cache; + PyObject *tp_subclasses; + PyObject *tp_weaklist; + destructor tp_del; + + /* Type attribute cache version tag. Added in version 2.6 */ + unsigned int tp_version_tag; + + destructor tp_finalize; + +#ifdef COUNT_ALLOCS + /* these must be last and never explicitly initialized */ + Py_ssize_t tp_allocs; + Py_ssize_t tp_frees; + Py_ssize_t tp_maxalloc; + struct _typeobject *tp_prev; + struct _typeobject *tp_next; +#endif +} PyTypeObject; +#endif + +typedef struct{ + int slot; /* slot id, see below */ + void *pfunc; /* function pointer */ +} PyType_Slot; + +typedef struct{ + const char* name; + int basicsize; + int itemsize; + unsigned int flags; + PyType_Slot *slots; /* terminated by slot==0. */ +} PyType_Spec; + +PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 +PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); +#endif + +#ifndef Py_LIMITED_API +/* The *real* layout of a type object when allocated on the heap */ +typedef struct _heaptypeobject { + /* Note: there's a dependency on the order of these members + in slotptr() in typeobject.c . */ + PyTypeObject ht_type; + PyAsyncMethods as_async; + PyNumberMethods as_number; + PyMappingMethods as_mapping; + PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, + so that the mapping wins when both + the mapping and the sequence define + a given operator (e.g. __getitem__). + see add_operators() in typeobject.c . */ + PyBufferProcs as_buffer; + PyObject *ht_name, *ht_slots, *ht_qualname; + struct _dictkeysobject *ht_cached_keys; + /* here are optional user slots, followed by the members. */ +} PyHeapTypeObject; + +/* access macro to the members which are floating "behind" the object */ +#define PyHeapType_GET_MEMBERS(etype) \ + ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) +#endif + +/* Generic type check */ +PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); +#define PyObject_TypeCheck(ob, tp) \ + (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) + +PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ +PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ +PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */ + +PyAPI_FUNC(unsigned long) PyType_GetFlags(PyTypeObject*); + +#define PyType_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) +#define PyType_CheckExact(op) (Py_TYPE(op) == &PyType_Type) + +PyAPI_FUNC(int) PyType_Ready(PyTypeObject *); +PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, + PyObject *, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); +PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); +PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *); +PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); +#endif +PyAPI_FUNC(unsigned int) PyType_ClearCache(void); +PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); +PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); +#endif + +/* Generic operations on objects */ +#ifndef Py_LIMITED_API +struct _Py_Identifier; +PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); +PyAPI_FUNC(void) _Py_BreakPoint(void); +PyAPI_FUNC(void) _PyObject_Dump(PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_ASCII(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Bytes(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int); +PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *); +PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); +PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *); +PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *); +/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which + don't raise AttributeError. + + Return 1 and set *result != NULL if an attribute is found. + Return 0 and set *result == NULL if an attribute is not found; + an AttributeError is silenced. + Return -1 and set *result == NULL if an error other than AttributeError + is raised. +*/ +PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **); +PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, struct _Py_Identifier *, PyObject **); +PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, + PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(int) PyObject_GenericSetDict(PyObject *, PyObject *, void *); +#endif +PyAPI_FUNC(Py_hash_t) PyObject_Hash(PyObject *); +PyAPI_FUNC(Py_hash_t) PyObject_HashNotImplemented(PyObject *); +PyAPI_FUNC(int) PyObject_IsTrue(PyObject *); +PyAPI_FUNC(int) PyObject_Not(PyObject *); +PyAPI_FUNC(int) PyCallable_Check(PyObject *); + +PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); +PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); +#endif + +#ifndef Py_LIMITED_API +/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes + dict as the last parameter. */ +PyAPI_FUNC(PyObject *) +_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int); +PyAPI_FUNC(int) +_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, + PyObject *, PyObject *); +#endif /* !Py_LIMITED_API */ + +/* Helper to look up a builtin object */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) +_PyObject_GetBuiltin(const char *name); +#endif + +/* PyObject_Dir(obj) acts like Python builtins.dir(obj), returning a + list of strings. PyObject_Dir(NULL) is like builtins.dir(), + returning the names of the current locals. In this case, if there are + no current locals, NULL is returned, and PyErr_Occurred() is false. +*/ +PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); + + +/* Helpers for printing recursive container types */ +PyAPI_FUNC(int) Py_ReprEnter(PyObject *); +PyAPI_FUNC(void) Py_ReprLeave(PyObject *); + +/* Flag bits for printing: */ +#define Py_PRINT_RAW 1 /* No string quotes etc. */ + +/* +`Type flags (tp_flags) + +These flags are used to extend the type structure in a backwards-compatible +fashion. Extensions can use the flags to indicate (and test) when a given +type structure contains a new feature. The Python core will use these when +introducing new functionality between major revisions (to avoid mid-version +changes in the PYTHON_API_VERSION). + +Arbitration of the flag bit positions will need to be coordinated among +all extension writers who publicly release their extensions (this will +be fewer than you might expect!).. + +Most flags were removed as of Python 3.0 to make room for new flags. (Some +flags are not for backwards compatibility but to indicate the presence of an +optional feature; these flags remain of course.) + +Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value. + +Code can use PyType_HasFeature(type_ob, flag_value) to test whether the +given type object has a specified feature. +*/ + +/* Set if the type object is dynamically allocated */ +#define Py_TPFLAGS_HEAPTYPE (1UL << 9) + +/* Set if the type allows subclassing */ +#define Py_TPFLAGS_BASETYPE (1UL << 10) + +/* Set if the type is 'ready' -- fully initialized */ +#define Py_TPFLAGS_READY (1UL << 12) + +/* Set while the type is being 'readied', to prevent recursive ready calls */ +#define Py_TPFLAGS_READYING (1UL << 13) + +/* Objects support garbage collection (see objimp.h) */ +#define Py_TPFLAGS_HAVE_GC (1UL << 14) + +/* These two bits are preserved for Stackless Python, next after this is 17 */ +#ifdef STACKLESS +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3UL << 15) +#else +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 +#endif + +/* Objects support type attribute cache */ +#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) +#define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19) + +/* Type is abstract and cannot be instantiated */ +#define Py_TPFLAGS_IS_ABSTRACT (1UL << 20) + +/* These flags are used to determine if a type is a subclass. */ +#define Py_TPFLAGS_LONG_SUBCLASS (1UL << 24) +#define Py_TPFLAGS_LIST_SUBCLASS (1UL << 25) +#define Py_TPFLAGS_TUPLE_SUBCLASS (1UL << 26) +#define Py_TPFLAGS_BYTES_SUBCLASS (1UL << 27) +#define Py_TPFLAGS_UNICODE_SUBCLASS (1UL << 28) +#define Py_TPFLAGS_DICT_SUBCLASS (1UL << 29) +#define Py_TPFLAGS_BASE_EXC_SUBCLASS (1UL << 30) +#define Py_TPFLAGS_TYPE_SUBCLASS (1UL << 31) + +#define Py_TPFLAGS_DEFAULT ( \ + Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ + Py_TPFLAGS_HAVE_VERSION_TAG | \ + 0) + +/* NOTE: The following flags reuse lower bits (removed as part of the + * Python 3.0 transition). */ + +/* Type structure has tp_finalize member (3.4) */ +#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) + +#ifdef Py_LIMITED_API +#define PyType_HasFeature(t,f) ((PyType_GetFlags(t) & (f)) != 0) +#else +#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) +#endif +#define PyType_FastSubclass(t,f) PyType_HasFeature(t,f) + + +/* +The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement +reference counts. Py_DECREF calls the object's deallocator function when +the refcount falls to 0; for +objects that don't contain references to other objects or heap memory +this can be the standard function free(). Both macros can be used +wherever a void expression is allowed. The argument must not be a +NULL pointer. If it may be NULL, use Py_XINCREF/Py_XDECREF instead. +The macro _Py_NewReference(op) initialize reference counts to 1, and +in special builds (Py_REF_DEBUG, Py_TRACE_REFS) performs additional +bookkeeping appropriate to the special build. + +We assume that the reference count field can never overflow; this can +be proven when the size of the field is the same as the pointer size, so +we ignore the possibility. Provided a C int is at least 32 bits (which +is implicitly assumed in many parts of this code), that's enough for +about 2**31 references to an object. + +XXX The following became out of date in Python 2.2, but I'm not sure +XXX what the full truth is now. Certainly, heap-allocated type objects +XXX can and should be deallocated. +Type objects should never be deallocated; the type pointer in an object +is not considered to be a reference to the type object, to save +complications in the deallocation function. (This is actually a +decision that's up to the implementer of each new type so if you want, +you can count such references to the type object.) +*/ + +/* First define a pile of simple helper macros, one set per special + * build symbol. These either expand to the obvious things, or to + * nothing at all when the special mode isn't in effect. The main + * macros can later be defined just once then, yet expand to different + * things depending on which special build options are and aren't in effect. + * Trust me : while painful, this is 20x easier to understand than, + * e.g, defining _Py_NewReference five different times in a maze of nested + * #ifdefs (we used to do that -- it was impenetrable). + */ +#ifdef Py_REF_DEBUG +PyAPI_DATA(Py_ssize_t) _Py_RefTotal; +PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname, + int lineno, PyObject *op); +PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); +#define _Py_INC_REFTOTAL _Py_RefTotal++ +#define _Py_DEC_REFTOTAL _Py_RefTotal-- +#define _Py_REF_DEBUG_COMMA , +#define _Py_CHECK_REFCNT(OP) \ +{ if (((PyObject*)OP)->ob_refcnt < 0) \ + _Py_NegativeRefcount(__FILE__, __LINE__, \ + (PyObject *)(OP)); \ +} +/* Py_REF_DEBUG also controls the display of refcounts and memory block + * allocations at the interactive prompt and at interpreter shutdown + */ +PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void); +#else +#define _Py_INC_REFTOTAL +#define _Py_DEC_REFTOTAL +#define _Py_REF_DEBUG_COMMA +#define _Py_CHECK_REFCNT(OP) /* a semicolon */; +#endif /* Py_REF_DEBUG */ + +#ifdef COUNT_ALLOCS +PyAPI_FUNC(void) inc_count(PyTypeObject *); +PyAPI_FUNC(void) dec_count(PyTypeObject *); +#define _Py_INC_TPALLOCS(OP) inc_count(Py_TYPE(OP)) +#define _Py_INC_TPFREES(OP) dec_count(Py_TYPE(OP)) +#define _Py_DEC_TPFREES(OP) Py_TYPE(OP)->tp_frees-- +#define _Py_COUNT_ALLOCS_COMMA , +#else +#define _Py_INC_TPALLOCS(OP) +#define _Py_INC_TPFREES(OP) +#define _Py_DEC_TPFREES(OP) +#define _Py_COUNT_ALLOCS_COMMA +#endif /* COUNT_ALLOCS */ + +#ifdef Py_TRACE_REFS +/* Py_TRACE_REFS is such major surgery that we call external routines. */ +PyAPI_FUNC(void) _Py_NewReference(PyObject *); +PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +PyAPI_FUNC(void) _Py_PrintReferences(FILE *); +PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *); +PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); + +#else +/* Without Py_TRACE_REFS, there's little enough to do that we expand code + * inline. + */ +#define _Py_NewReference(op) ( \ + _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA \ + _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ + Py_REFCNT(op) = 1) + +#define _Py_ForgetReference(op) _Py_INC_TPFREES(op) + +#ifdef Py_LIMITED_API +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +#else +#define _Py_Dealloc(op) ( \ + _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \ + (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op))) +#endif +#endif /* !Py_TRACE_REFS */ + +#define Py_INCREF(op) ( \ + _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ + ((PyObject *)(op))->ob_refcnt++) + +#define Py_DECREF(op) \ + do { \ + PyObject *_py_decref_tmp = (PyObject *)(op); \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --(_py_decref_tmp)->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(_py_decref_tmp) \ + else \ + _Py_Dealloc(_py_decref_tmp); \ + } while (0) + +/* Safely decref `op` and set `op` to NULL, especially useful in tp_clear + * and tp_dealloc implementations. + * + * Note that "the obvious" code can be deadly: + * + * Py_XDECREF(op); + * op = NULL; + * + * Typically, `op` is something like self->containee, and `self` is done + * using its `containee` member. In the code sequence above, suppose + * `containee` is non-NULL with a refcount of 1. Its refcount falls to + * 0 on the first line, which can trigger an arbitrary amount of code, + * possibly including finalizers (like __del__ methods or weakref callbacks) + * coded in Python, which in turn can release the GIL and allow other threads + * to run, etc. Such code may even invoke methods of `self` again, or cause + * cyclic gc to trigger, but-- oops! --self->containee still points to the + * object being torn down, and it may be in an insane state while being torn + * down. This has in fact been a rich historic source of miserable (rare & + * hard-to-diagnose) segfaulting (and other) bugs. + * + * The safe way is: + * + * Py_CLEAR(op); + * + * That arranges to set `op` to NULL _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * There are cases where it's safe to use the naive code, but they're brittle. + * For example, if `op` points to a Python integer, you know that destroying + * one of those can't cause problems -- but in part that relies on that + * Python integers aren't currently weakly referencable. Best practice is + * to use Py_CLEAR() even if you can't think of a reason for why you need to. + */ +#define Py_CLEAR(op) \ + do { \ + PyObject *_py_tmp = (PyObject *)(op); \ + if (_py_tmp != NULL) { \ + (op) = NULL; \ + Py_DECREF(_py_tmp); \ + } \ + } while (0) + +/* Macros to use in case the object pointer may be NULL: */ +#define Py_XINCREF(op) \ + do { \ + PyObject *_py_xincref_tmp = (PyObject *)(op); \ + if (_py_xincref_tmp != NULL) \ + Py_INCREF(_py_xincref_tmp); \ + } while (0) + +#define Py_XDECREF(op) \ + do { \ + PyObject *_py_xdecref_tmp = (PyObject *)(op); \ + if (_py_xdecref_tmp != NULL) \ + Py_DECREF(_py_xdecref_tmp); \ + } while (0) + +#ifndef Py_LIMITED_API +/* Safely decref `op` and set `op` to `op2`. + * + * As in case of Py_CLEAR "the obvious" code can be deadly: + * + * Py_DECREF(op); + * op = op2; + * + * The safe way is: + * + * Py_SETREF(op, op2); + * + * That arranges to set `op` to `op2` _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of + * Py_DECREF. + */ + +#define Py_SETREF(op, op2) \ + do { \ + PyObject *_py_tmp = (PyObject *)(op); \ + (op) = (op2); \ + Py_DECREF(_py_tmp); \ + } while (0) + +#define Py_XSETREF(op, op2) \ + do { \ + PyObject *_py_tmp = (PyObject *)(op); \ + (op) = (op2); \ + Py_XDECREF(_py_tmp); \ + } while (0) + +#endif /* ifndef Py_LIMITED_API */ + +/* +These are provided as conveniences to Python runtime embedders, so that +they can have object code that is not dependent on Python compilation flags. +*/ +PyAPI_FUNC(void) Py_IncRef(PyObject *); +PyAPI_FUNC(void) Py_DecRef(PyObject *); + +#ifndef Py_LIMITED_API +PyAPI_DATA(PyTypeObject) _PyNone_Type; +PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type; +#endif /* !Py_LIMITED_API */ + +/* +_Py_NoneStruct is an object of undefined type which can be used in contexts +where NULL (nil) is not suitable (since NULL often means 'error'). + +Don't forget to apply Py_INCREF() when returning this value!!! +*/ +PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ +#define Py_None (&_Py_NoneStruct) + +/* Macro for returning Py_None from a function */ +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None + +/* +Py_NotImplemented is a singleton used to signal that an operation is +not implemented for a given type combination. +*/ +PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ +#define Py_NotImplemented (&_Py_NotImplementedStruct) + +/* Macro for returning Py_NotImplemented from a function */ +#define Py_RETURN_NOTIMPLEMENTED \ + return Py_INCREF(Py_NotImplemented), Py_NotImplemented + +/* Rich comparison opcodes */ +#define Py_LT 0 +#define Py_LE 1 +#define Py_EQ 2 +#define Py_NE 3 +#define Py_GT 4 +#define Py_GE 5 + +/* + * Macro for implementing rich comparisons + * + * Needs to be a macro because any C-comparable type can be used. + */ +#define Py_RETURN_RICHCOMPARE(val1, val2, op) \ + do { \ + switch (op) { \ + case Py_EQ: if ((val1) == (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_NE: if ((val1) != (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_LT: if ((val1) < (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_GT: if ((val1) > (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_LE: if ((val1) <= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_GE: if ((val1) >= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + default: \ + Py_UNREACHABLE(); \ + } \ + } while (0) + +#ifndef Py_LIMITED_API +/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. + * Defined in object.c. + */ +PyAPI_DATA(int) _Py_SwappedOp[]; +#endif /* !Py_LIMITED_API */ + + +/* +More conventions +================ + +Argument Checking +----------------- + +Functions that take objects as arguments normally don't check for nil +arguments, but they do check the type of the argument, and return an +error if the function doesn't apply to the type. + +Failure Modes +------------- + +Functions may fail for a variety of reasons, including running out of +memory. This is communicated to the caller in two ways: an error string +is set (see errors.h), and the function result differs: functions that +normally return a pointer return NULL for failure, functions returning +an integer return -1 (which could be a legal return value too!), and +other functions return 0 for success and -1 for failure. +Callers should always check for errors before using the result. If +an error was set, the caller must either explicitly clear it, or pass +the error on to its caller. + +Reference Counts +---------------- + +It takes a while to get used to the proper usage of reference counts. + +Functions that create an object set the reference count to 1; such new +objects must be stored somewhere or destroyed again with Py_DECREF(). +Some functions that 'store' objects, such as PyTuple_SetItem() and +PyList_SetItem(), +don't increment the reference count of the object, since the most +frequent use is to store a fresh object. Functions that 'retrieve' +objects, such as PyTuple_GetItem() and PyDict_GetItemString(), also +don't increment +the reference count, since most frequently the object is only looked at +quickly. Thus, to retrieve an object and store it again, the caller +must call Py_INCREF() explicitly. + +NOTE: functions that 'consume' a reference count, like +PyList_SetItem(), consume the reference even if the object wasn't +successfully stored, to simplify error handling. + +It seems attractive to make other functions that take an object as +argument consume a reference count; however, this may quickly get +confusing (even the current practice is already confusing). Consider +it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at +times. +*/ + + +/* Trashcan mechanism, thanks to Christian Tismer. + +When deallocating a container object, it's possible to trigger an unbounded +chain of deallocations, as each Py_DECREF in turn drops the refcount on "the +next" object in the chain to 0. This can easily lead to stack faults, and +especially in threads (which typically have less stack space to work with). + +A container object that participates in cyclic gc can avoid this by +bracketing the body of its tp_dealloc function with a pair of macros: + +static void +mytype_dealloc(mytype *p) +{ + ... declarations go here ... + + PyObject_GC_UnTrack(p); // must untrack first + Py_TRASHCAN_SAFE_BEGIN(p) + ... The body of the deallocator goes here, including all calls ... + ... to Py_DECREF on contained objects. ... + Py_TRASHCAN_SAFE_END(p) +} + +CAUTION: Never return from the middle of the body! If the body needs to +"get out early", put a label immediately before the Py_TRASHCAN_SAFE_END +call, and goto it. Else the call-depth counter (see below) will stay +above 0 forever, and the trashcan will never get emptied. + +How it works: The BEGIN macro increments a call-depth counter. So long +as this counter is small, the body of the deallocator is run directly without +further ado. But if the counter gets large, it instead adds p to a list of +objects to be deallocated later, skips the body of the deallocator, and +resumes execution after the END macro. The tp_dealloc routine then returns +without deallocating anything (and so unbounded call-stack depth is avoided). + +When the call stack finishes unwinding again, code generated by the END macro +notices this, and calls another routine to deallocate all the objects that +may have been added to the list of deferred deallocations. In effect, a +chain of N deallocations is broken into (N-1)/(PyTrash_UNWIND_LEVEL-1) pieces, +with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL. +*/ + +#ifndef Py_LIMITED_API +/* This is the old private API, invoked by the macros before 3.2.4. + Kept for binary compatibility of extensions using the stable ABI. */ +PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*); +PyAPI_FUNC(void) _PyTrash_destroy_chain(void); +#endif /* !Py_LIMITED_API */ + +/* The new thread-safe private API, invoked by the macros below. */ +PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyObject*); +PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void); + +#define PyTrash_UNWIND_LEVEL 50 + +#define Py_TRASHCAN_SAFE_BEGIN(op) \ + do { \ + PyThreadState *_tstate = PyThreadState_GET(); \ + if (_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL) { \ + ++_tstate->trash_delete_nesting; + /* The body of the deallocator is here. */ +#define Py_TRASHCAN_SAFE_END(op) \ + --_tstate->trash_delete_nesting; \ + if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \ + _PyTrash_thread_destroy_chain(); \ + } \ + else \ + _PyTrash_thread_deposit_object((PyObject*)op); \ + } while (0); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) +_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, + size_t sizeof_block); +PyAPI_FUNC(void) +_PyObject_DebugTypeStats(FILE *out); +#endif /* ifndef Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJECT_H */ diff --git a/Include/objimpl.h b/Include/objimpl.h new file mode 100644 index 0000000..057bb50 --- /dev/null +++ b/Include/objimpl.h @@ -0,0 +1,370 @@ +/* The PyObject_ memory family: high-level object memory interfaces. + See pymem.h for the low-level PyMem_ family. +*/ + +#ifndef Py_OBJIMPL_H +#define Py_OBJIMPL_H + +#include "pymem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyObject_ memory functions with calls to the platform + malloc/realloc/ calloc/free, or with calls to PyMem_. +*/ + +/* +Functions and macros for modules that implement new object types. + + - PyObject_New(type, typeobj) allocates memory for a new object of the given + type, and initializes part of it. 'type' must be the C structure type used + to represent the object, and 'typeobj' the address of the corresponding + type object. Reference count and type pointer are filled in; the rest of + the bytes of the object are *undefined*! The resulting expression type is + 'type *'. The size of the object is determined by the tp_basicsize field + of the type object. + + - PyObject_NewVar(type, typeobj, n) is similar but allocates a variable-size + object with room for n items. In addition to the refcount and type pointer + fields, this also fills in the ob_size field. + + - PyObject_Del(op) releases the memory allocated for an object. It does not + run a destructor -- it only frees the memory. PyObject_Free is identical. + + - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't + allocate memory. Instead of a 'type' parameter, they take a pointer to a + new object (allocated by an arbitrary allocator), and initialize its object + header fields. + +Note that objects created with PyObject_{New, NewVar} are allocated using the +specialized Python allocator (implemented in obmalloc.c), if WITH_PYMALLOC is +enabled. In addition, a special debugging allocator is used if PYMALLOC_DEBUG +is also #defined. + +In case a specific form of memory management is needed (for example, if you +must use the platform malloc heap(s), or shared memory, or C++ local storage or +operator new), you must first allocate the object with your custom allocator, +then pass its pointer to PyObject_{Init, InitVar} for filling in its Python- +specific fields: reference count, type pointer, possibly others. You should +be aware that Python has no control over these objects because they don't +cooperate with the Python memory manager. Such objects may not be eligible +for automatic garbage collection and you have to make sure that they are +released accordingly whenever their destructor gets called (cf. the specific +form of memory management you're using). + +Unless you have specific memory management requirements, use +PyObject_{New, NewVar, Del}. +*/ + +/* + * Raw object memory interface + * =========================== + */ + +/* Functions to call the same malloc/realloc/free as used by Python's + object allocator. If WITH_PYMALLOC is enabled, these may differ from + the platform malloc/realloc/free. The Python object allocator is + designed for fast, cache-conscious allocation of many "small" objects, + and with low hidden memory overhead. + + PyObject_Malloc(0) returns a unique non-NULL pointer if possible. + + PyObject_Realloc(NULL, n) acts like PyObject_Malloc(n). + PyObject_Realloc(p != NULL, 0) does not return NULL, or free the memory + at p. + + Returned pointers must be checked for NULL explicitly; no action is + performed on failure other than to return NULL (no warning it printed, no + exception is set, etc). + + For allocating objects, use PyObject_{New, NewVar} instead whenever + possible. The PyObject_{Malloc, Realloc, Free} family is exposed + so that you can exploit Python's small-block allocator for non-object + uses. If you must use these routines to allocate object memory, make sure + the object gets initialized via PyObject_{Init, InitVar} after obtaining + the raw memory. +*/ +PyAPI_FUNC(void *) PyObject_Malloc(size_t size); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(void *) PyObject_Calloc(size_t nelem, size_t elsize); +#endif +PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyObject_Free(void *ptr); + +#ifndef Py_LIMITED_API +/* This function returns the number of allocated memory blocks, regardless of size */ +PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); +#endif /* !Py_LIMITED_API */ + +/* Macros */ +#ifdef WITH_PYMALLOC +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); +#endif /* #ifndef Py_LIMITED_API */ +#endif + +/* Macros */ +#define PyObject_MALLOC PyObject_Malloc +#define PyObject_REALLOC PyObject_Realloc +#define PyObject_FREE PyObject_Free +#define PyObject_Del PyObject_Free +#define PyObject_DEL PyObject_Free + + +/* + * Generic object allocator interface + * ================================== + */ + +/* Functions */ +PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *); +PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *, + PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); + +#define PyObject_New(type, typeobj) \ + ( (type *) _PyObject_New(typeobj) ) +#define PyObject_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_NewVar((typeobj), (n)) ) + +/* Macros trading binary compatibility for speed. See also pymem.h. + Note that these macros expect non-NULL object pointers.*/ +#define PyObject_INIT(op, typeobj) \ + ( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) +#define PyObject_INIT_VAR(op, typeobj, size) \ + ( Py_SIZE(op) = (size), PyObject_INIT((op), (typeobj)) ) + +#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) + +/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a + vrbl-size object with nitems items, exclusive of gc overhead (if any). The + value is rounded up to the closest multiple of sizeof(void *), in order to + ensure that pointer fields at the end of the object are correctly aligned + for the platform (this is of special importance for subclasses of, e.g., + str or int, so that pointers can be stored after the embedded data). + + Note that there's no memory wastage in doing this, as malloc has to + return (at worst) pointer-aligned memory anyway. +*/ +#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 +# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" +#endif + +#define _PyObject_VAR_SIZE(typeobj, nitems) \ + _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \ + (nitems)*(typeobj)->tp_itemsize, \ + SIZEOF_VOID_P) + +#define PyObject_NEW(type, typeobj) \ +( (type *) PyObject_Init( \ + (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) + +#define PyObject_NEW_VAR(type, typeobj, n) \ +( (type *) PyObject_InitVar( \ + (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\ + (typeobj), (n)) ) + +/* This example code implements an object constructor with a custom + allocator, where PyObject_New is inlined, and shows the important + distinction between two steps (at least): + 1) the actual allocation of the object storage; + 2) the initialization of the Python specific fields + in this storage with PyObject_{Init, InitVar}. + + PyObject * + YourObject_New(...) + { + PyObject *op; + + op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); + if (op == NULL) + return PyErr_NoMemory(); + + PyObject_Init(op, &YourTypeStruct); + + op->ob_field = value; + ... + return op; + } + + Note that in C++, the use of the new operator usually implies that + the 1st step is performed automatically for you, so in a C++ class + constructor you would start directly with PyObject_Init/InitVar +*/ + +#ifndef Py_LIMITED_API +typedef struct { + /* user context passed as the first argument to the 2 functions */ + void *ctx; + + /* allocate an arena of size bytes */ + void* (*alloc) (void *ctx, size_t size); + + /* free an arena */ + void (*free) (void *ctx, void *ptr, size_t size); +} PyObjectArenaAllocator; + +/* Get the arena allocator. */ +PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator); + +/* Set the arena allocator. */ +PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator); +#endif + + +/* + * Garbage Collection Support + * ========================== + */ + +/* C equivalent of gc.collect() which ignores the state of gc.enabled. */ +PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(void); +PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void); +#endif + +/* Test if a type has a GC head */ +#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) + +/* Test if an object has a GC head */ +#define PyObject_IS_GC(o) (PyType_IS_GC(Py_TYPE(o)) && \ + (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o))) + +PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); +#define PyObject_GC_Resize(type, op, n) \ + ( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) ) + +/* GC information is stored BEFORE the object structure. */ +#ifndef Py_LIMITED_API +typedef union _gc_head { + struct { + union _gc_head *gc_next; + union _gc_head *gc_prev; + Py_ssize_t gc_refs; + } gc; + double dummy; /* force worst-case alignment */ +} PyGC_Head; + +extern PyGC_Head *_PyGC_generation0; + +#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1) + +/* Bit 0 is set when tp_finalize is called */ +#define _PyGC_REFS_MASK_FINALIZED (1 << 0) +/* The (N-1) most significant bits contain the gc state / refcount */ +#define _PyGC_REFS_SHIFT (1) +#define _PyGC_REFS_MASK (((size_t) -1) << _PyGC_REFS_SHIFT) + +#define _PyGCHead_REFS(g) ((g)->gc.gc_refs >> _PyGC_REFS_SHIFT) +#define _PyGCHead_SET_REFS(g, v) do { \ + (g)->gc.gc_refs = ((g)->gc.gc_refs & ~_PyGC_REFS_MASK) \ + | (((size_t)(v)) << _PyGC_REFS_SHIFT); \ + } while (0) +#define _PyGCHead_DECREF(g) ((g)->gc.gc_refs -= 1 << _PyGC_REFS_SHIFT) + +#define _PyGCHead_FINALIZED(g) (((g)->gc.gc_refs & _PyGC_REFS_MASK_FINALIZED) != 0) +#define _PyGCHead_SET_FINALIZED(g, v) do { \ + (g)->gc.gc_refs = ((g)->gc.gc_refs & ~_PyGC_REFS_MASK_FINALIZED) \ + | (v != 0); \ + } while (0) + +#define _PyGC_FINALIZED(o) _PyGCHead_FINALIZED(_Py_AS_GC(o)) +#define _PyGC_SET_FINALIZED(o, v) _PyGCHead_SET_FINALIZED(_Py_AS_GC(o), v) + +#define _PyGC_REFS(o) _PyGCHead_REFS(_Py_AS_GC(o)) + +#define _PyGC_REFS_UNTRACKED (-2) +#define _PyGC_REFS_REACHABLE (-3) +#define _PyGC_REFS_TENTATIVELY_UNREACHABLE (-4) + +/* Tell the GC to track this object. NB: While the object is tracked the + * collector it must be safe to call the ob_traverse method. */ +#define _PyObject_GC_TRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + if (_PyGCHead_REFS(g) != _PyGC_REFS_UNTRACKED) \ + Py_FatalError("GC object already tracked"); \ + _PyGCHead_SET_REFS(g, _PyGC_REFS_REACHABLE); \ + g->gc.gc_next = _PyGC_generation0; \ + g->gc.gc_prev = _PyGC_generation0->gc.gc_prev; \ + g->gc.gc_prev->gc.gc_next = g; \ + _PyGC_generation0->gc.gc_prev = g; \ + } while (0); + +/* Tell the GC to stop tracking this object. + * gc_next doesn't need to be set to NULL, but doing so is a good + * way to provoke memory errors if calling code is confused. + */ +#define _PyObject_GC_UNTRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + assert(_PyGCHead_REFS(g) != _PyGC_REFS_UNTRACKED); \ + _PyGCHead_SET_REFS(g, _PyGC_REFS_UNTRACKED); \ + g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \ + g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \ + g->gc.gc_next = NULL; \ + } while (0); + +/* True if the object is currently tracked by the GC. */ +#define _PyObject_GC_IS_TRACKED(o) \ + (_PyGC_REFS(o) != _PyGC_REFS_UNTRACKED) + +/* True if the object may be tracked by the GC in the future, or already is. + This can be useful to implement some optimizations. */ +#define _PyObject_GC_MAY_BE_TRACKED(obj) \ + (PyObject_IS_GC(obj) && \ + (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) +#endif /* Py_LIMITED_API */ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size); +PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(void) PyObject_GC_Track(void *); +PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); +PyAPI_FUNC(void) PyObject_GC_Del(void *); + +#define PyObject_GC_New(type, typeobj) \ + ( (type *) _PyObject_GC_New(typeobj) ) +#define PyObject_GC_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_GC_NewVar((typeobj), (n)) ) + + +/* Utility macro to help write tp_traverse functions. + * To use this macro, the tp_traverse function must name its arguments + * "visit" and "arg". This is intended to keep tp_traverse functions + * looking as much alike as possible. + */ +#define Py_VISIT(op) \ + do { \ + if (op) { \ + int vret = visit((PyObject *)(op), arg); \ + if (vret) \ + return vret; \ + } \ + } while (0) + + +/* Test if a type supports weak references */ +#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) + +#define PyObject_GET_WEAKREFS_LISTPTR(o) \ + ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJIMPL_H */ diff --git a/Include/odictobject.h b/Include/odictobject.h new file mode 100644 index 0000000..8378dc4 --- /dev/null +++ b/Include/odictobject.h @@ -0,0 +1,43 @@ +#ifndef Py_ODICTOBJECT_H +#define Py_ODICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* OrderedDict */ +/* This API is optional and mostly redundant. */ + +#ifndef Py_LIMITED_API + +typedef struct _odictobject PyODictObject; + +PyAPI_DATA(PyTypeObject) PyODict_Type; +PyAPI_DATA(PyTypeObject) PyODictIter_Type; +PyAPI_DATA(PyTypeObject) PyODictKeys_Type; +PyAPI_DATA(PyTypeObject) PyODictItems_Type; +PyAPI_DATA(PyTypeObject) PyODictValues_Type; + +#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) +#define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type) +#define PyODict_SIZE(op) PyDict_GET_SIZE((op)) + +PyAPI_FUNC(PyObject *) PyODict_New(void); +PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); +PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); + +/* wrappers around PyDict* functions */ +#define PyODict_GetItem(od, key) PyDict_GetItem((PyObject *)od, key) +#define PyODict_GetItemWithError(od, key) \ + PyDict_GetItemWithError((PyObject *)od, key) +#define PyODict_Contains(od, key) PyDict_Contains((PyObject *)od, key) +#define PyODict_Size(od) PyDict_Size((PyObject *)od) +#define PyODict_GetItemString(od, key) \ + PyDict_GetItemString((PyObject *)od, key) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ODICTOBJECT_H */ diff --git a/Include/opcode.h b/Include/opcode.h new file mode 100644 index 0000000..fc6cbf3 --- /dev/null +++ b/Include/opcode.h @@ -0,0 +1,147 @@ +/* Auto-generated by Tools/scripts/generate_opcode_h.py */ +#ifndef Py_OPCODE_H +#define Py_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + + /* Instruction opcodes for compiled code */ +#define POP_TOP 1 +#define ROT_TWO 2 +#define ROT_THREE 3 +#define DUP_TOP 4 +#define DUP_TOP_TWO 5 +#define NOP 9 +#define UNARY_POSITIVE 10 +#define UNARY_NEGATIVE 11 +#define UNARY_NOT 12 +#define UNARY_INVERT 15 +#define BINARY_MATRIX_MULTIPLY 16 +#define INPLACE_MATRIX_MULTIPLY 17 +#define BINARY_POWER 19 +#define BINARY_MULTIPLY 20 +#define BINARY_MODULO 22 +#define BINARY_ADD 23 +#define BINARY_SUBTRACT 24 +#define BINARY_SUBSCR 25 +#define BINARY_FLOOR_DIVIDE 26 +#define BINARY_TRUE_DIVIDE 27 +#define INPLACE_FLOOR_DIVIDE 28 +#define INPLACE_TRUE_DIVIDE 29 +#define GET_AITER 50 +#define GET_ANEXT 51 +#define BEFORE_ASYNC_WITH 52 +#define INPLACE_ADD 55 +#define INPLACE_SUBTRACT 56 +#define INPLACE_MULTIPLY 57 +#define INPLACE_MODULO 59 +#define STORE_SUBSCR 60 +#define DELETE_SUBSCR 61 +#define BINARY_LSHIFT 62 +#define BINARY_RSHIFT 63 +#define BINARY_AND 64 +#define BINARY_XOR 65 +#define BINARY_OR 66 +#define INPLACE_POWER 67 +#define GET_ITER 68 +#define GET_YIELD_FROM_ITER 69 +#define PRINT_EXPR 70 +#define LOAD_BUILD_CLASS 71 +#define YIELD_FROM 72 +#define GET_AWAITABLE 73 +#define INPLACE_LSHIFT 75 +#define INPLACE_RSHIFT 76 +#define INPLACE_AND 77 +#define INPLACE_XOR 78 +#define INPLACE_OR 79 +#define BREAK_LOOP 80 +#define WITH_CLEANUP_START 81 +#define WITH_CLEANUP_FINISH 82 +#define RETURN_VALUE 83 +#define IMPORT_STAR 84 +#define SETUP_ANNOTATIONS 85 +#define YIELD_VALUE 86 +#define POP_BLOCK 87 +#define END_FINALLY 88 +#define POP_EXCEPT 89 +#define HAVE_ARGUMENT 90 +#define STORE_NAME 90 +#define DELETE_NAME 91 +#define UNPACK_SEQUENCE 92 +#define FOR_ITER 93 +#define UNPACK_EX 94 +#define STORE_ATTR 95 +#define DELETE_ATTR 96 +#define STORE_GLOBAL 97 +#define DELETE_GLOBAL 98 +#define LOAD_CONST 100 +#define LOAD_NAME 101 +#define BUILD_TUPLE 102 +#define BUILD_LIST 103 +#define BUILD_SET 104 +#define BUILD_MAP 105 +#define LOAD_ATTR 106 +#define COMPARE_OP 107 +#define IMPORT_NAME 108 +#define IMPORT_FROM 109 +#define JUMP_FORWARD 110 +#define JUMP_IF_FALSE_OR_POP 111 +#define JUMP_IF_TRUE_OR_POP 112 +#define JUMP_ABSOLUTE 113 +#define POP_JUMP_IF_FALSE 114 +#define POP_JUMP_IF_TRUE 115 +#define LOAD_GLOBAL 116 +#define CONTINUE_LOOP 119 +#define SETUP_LOOP 120 +#define SETUP_EXCEPT 121 +#define SETUP_FINALLY 122 +#define LOAD_FAST 124 +#define STORE_FAST 125 +#define DELETE_FAST 126 +#define RAISE_VARARGS 130 +#define CALL_FUNCTION 131 +#define MAKE_FUNCTION 132 +#define BUILD_SLICE 133 +#define LOAD_CLOSURE 135 +#define LOAD_DEREF 136 +#define STORE_DEREF 137 +#define DELETE_DEREF 138 +#define CALL_FUNCTION_KW 141 +#define CALL_FUNCTION_EX 142 +#define SETUP_WITH 143 +#define EXTENDED_ARG 144 +#define LIST_APPEND 145 +#define SET_ADD 146 +#define MAP_ADD 147 +#define LOAD_CLASSDEREF 148 +#define BUILD_LIST_UNPACK 149 +#define BUILD_MAP_UNPACK 150 +#define BUILD_MAP_UNPACK_WITH_CALL 151 +#define BUILD_TUPLE_UNPACK 152 +#define BUILD_SET_UNPACK 153 +#define SETUP_ASYNC_WITH 154 +#define FORMAT_VALUE 155 +#define BUILD_CONST_KEY_MAP 156 +#define BUILD_STRING 157 +#define BUILD_TUPLE_UNPACK_WITH_CALL 158 +#define LOAD_METHOD 160 +#define CALL_METHOD 161 + +/* EXCEPT_HANDLER is a special, implicit block type which is created when + entering an except handler. It is not an opcode but we define it here + as we want it to be available to both frameobject.c and ceval.c, while + remaining private.*/ +#define EXCEPT_HANDLER 257 + + +enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, + PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, PyCmp_IN, PyCmp_NOT_IN, + PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; + +#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_H */ diff --git a/Include/osdefs.h b/Include/osdefs.h new file mode 100644 index 0000000..bd84c1c --- /dev/null +++ b/Include/osdefs.h @@ -0,0 +1,47 @@ +#ifndef Py_OSDEFS_H +#define Py_OSDEFS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Operating system dependencies */ + +#ifdef MS_WINDOWS +#define SEP L'\\' +#define ALTSEP L'/' +#define MAXPATHLEN 256 +#define DELIM L';' +#endif + +/* Filename separator */ +#ifndef SEP +#define SEP L'/' +#endif + +/* Max pathname length */ +#ifdef __hpux +#include +#include +#ifndef PATH_MAX +#define PATH_MAX MAXPATHLEN +#endif +#endif + +#ifndef MAXPATHLEN +#if defined(PATH_MAX) && PATH_MAX > 1024 +#define MAXPATHLEN PATH_MAX +#else +#define MAXPATHLEN 1024 +#endif +#endif + +/* Search path entry delimiter */ +#ifndef DELIM +#define DELIM L':' +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OSDEFS_H */ diff --git a/Include/osmodule.h b/Include/osmodule.h new file mode 100644 index 0000000..9095c2f --- /dev/null +++ b/Include/osmodule.h @@ -0,0 +1,17 @@ + +/* os module interface */ + +#ifndef Py_OSMODULE_H +#define Py_OSMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_FUNC(PyObject *) PyOS_FSPath(PyObject *path); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OSMODULE_H */ diff --git a/Include/parsetok.h b/Include/parsetok.h new file mode 100644 index 0000000..c9407a3 --- /dev/null +++ b/Include/parsetok.h @@ -0,0 +1,108 @@ + +/* Parser-tokenizer link interface */ +#ifndef Py_LIMITED_API +#ifndef Py_PARSETOK_H +#define Py_PARSETOK_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int error; +#ifndef PGEN + /* The filename is useless for pgen, see comment in tok_state structure */ + PyObject *filename; +#endif + int lineno; + int offset; + char *text; /* UTF-8-encoded string */ + int token; + int expected; +} perrdetail; + +#if 0 +#define PyPARSE_YIELD_IS_KEYWORD 0x0001 +#endif + +#define PyPARSE_DONT_IMPLY_DEDENT 0x0002 + +#if 0 +#define PyPARSE_WITH_IS_KEYWORD 0x0003 +#define PyPARSE_PRINT_IS_FUNCTION 0x0004 +#define PyPARSE_UNICODE_LITERALS 0x0008 +#endif + +#define PyPARSE_IGNORE_COOKIE 0x0010 +#define PyPARSE_BARRY_AS_BDFL 0x0020 + +PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, + perrdetail *); +PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int, + const char *, const char *, + perrdetail *); + +PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int, + perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseFileFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + const char *enc, + grammar *g, + int start, + const char *ps1, + const char *ps2, + perrdetail *err_ret, + int flags); +PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + const char *enc, + grammar *g, + int start, + const char *ps1, + const char *ps2, + perrdetail *err_ret, + int *flags); +PyAPI_FUNC(node *) PyParser_ParseFileObject( + FILE *fp, + PyObject *filename, + const char *enc, + grammar *g, + int start, + const char *ps1, + const char *ps2, + perrdetail *err_ret, + int *flags); + +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename( + const char *s, + const char *filename, /* decoded from the filesystem encoding */ + grammar *g, + int start, + perrdetail *err_ret, + int flags); +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx( + const char *s, + const char *filename, /* decoded from the filesystem encoding */ + grammar *g, + int start, + perrdetail *err_ret, + int *flags); +PyAPI_FUNC(node *) PyParser_ParseStringObject( + const char *s, + PyObject *filename, + grammar *g, + int start, + perrdetail *err_ret, + int *flags); + +/* Note that the following functions are defined in pythonrun.c, + not in parsetok.c */ +PyAPI_FUNC(void) PyParser_SetError(perrdetail *); +PyAPI_FUNC(void) PyParser_ClearError(perrdetail *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PARSETOK_H */ +#endif /* !Py_LIMITED_API */ diff --git a/Include/patchlevel.h b/Include/patchlevel.h new file mode 100644 index 0000000..13876bd --- /dev/null +++ b/Include/patchlevel.h @@ -0,0 +1,35 @@ + +/* Python version identification scheme. + + When the major or minor version changes, the VERSION variable in + configure.ac must also be changed. + + There is also (independent) API version information in modsupport.h. +*/ + +/* Values for PY_RELEASE_LEVEL */ +#define PY_RELEASE_LEVEL_ALPHA 0xA +#define PY_RELEASE_LEVEL_BETA 0xB +#define PY_RELEASE_LEVEL_GAMMA 0xC /* For release candidates */ +#define PY_RELEASE_LEVEL_FINAL 0xF /* Serial should be 0 here */ + /* Higher for patch releases */ + +/* Version parsed out into numeric values */ +/*--start constants--*/ +#define PY_MAJOR_VERSION 3 +#define PY_MINOR_VERSION 7 +#define PY_MICRO_VERSION 0 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 + +/* Version as a string */ +#define PY_VERSION "3.7.0" +/*--end constants--*/ + +/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. + Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */ +#define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \ + (PY_MINOR_VERSION << 16) | \ + (PY_MICRO_VERSION << 8) | \ + (PY_RELEASE_LEVEL << 4) | \ + (PY_RELEASE_SERIAL << 0)) diff --git a/Include/pgen.h b/Include/pgen.h new file mode 100644 index 0000000..8a325ed --- /dev/null +++ b/Include/pgen.h @@ -0,0 +1,18 @@ +#ifndef Py_PGEN_H +#define Py_PGEN_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Parser generator interface */ + +extern grammar *meta_grammar(void); + +struct _node; +extern grammar *pgen(struct _node *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PGEN_H */ diff --git a/Include/pgenheaders.h b/Include/pgenheaders.h new file mode 100644 index 0000000..dbc5e0a --- /dev/null +++ b/Include/pgenheaders.h @@ -0,0 +1,43 @@ +#ifndef Py_PGENHEADERS_H +#define Py_PGENHEADERS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Include files and extern declarations used by most of the parser. */ + +#include "Python.h" + +PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); + +#define addarc _Py_addarc +#define addbit _Py_addbit +#define adddfa _Py_adddfa +#define addfirstsets _Py_addfirstsets +#define addlabel _Py_addlabel +#define addstate _Py_addstate +#define delbitset _Py_delbitset +#define dumptree _Py_dumptree +#define findlabel _Py_findlabel +#define freegrammar _Py_freegrammar +#define mergebitset _Py_mergebitset +#define meta_grammar _Py_meta_grammar +#define newbitset _Py_newbitset +#define newgrammar _Py_newgrammar +#define pgen _Py_pgen +#define printgrammar _Py_printgrammar +#define printnonterminals _Py_printnonterminals +#define printtree _Py_printtree +#define samebitset _Py_samebitset +#define showtree _Py_showtree +#define tok_dump _Py_tok_dump +#define translatelabels _Py_translatelabels + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PGENHEADERS_H */ diff --git a/Include/py_curses.h b/Include/py_curses.h new file mode 100644 index 0000000..0eebc36 --- /dev/null +++ b/Include/py_curses.h @@ -0,0 +1,159 @@ + +#ifndef Py_CURSES_H +#define Py_CURSES_H + +#ifdef __APPLE__ +/* +** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards +** against multiple definition of wchar_t. +*/ +#ifdef _BSD_WCHAR_T_DEFINED_ +#define _WCHAR_T +#endif +#endif /* __APPLE__ */ + +/* On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards + against multiple definition of wchar_t and wint_t. */ +#if defined(__FreeBSD__) && defined(_XOPEN_SOURCE_EXTENDED) +# ifndef __wchar_t +# define __wchar_t +# endif +# ifndef __wint_t +# define __wint_t +# endif +#endif + +#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS) +/* The following definition is necessary for ncurses 5.7; without it, + some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python + can't get at the WINDOW flags field. */ +#define NCURSES_OPAQUE 0 +#endif + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif + +#ifdef HAVE_NCURSES_H +/* configure was checking , but we will + use , which has some or all these features. */ +#if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0) +#define WINDOW_HAS_FLAGS 1 +#endif +#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906 +#define HAVE_CURSES_IS_PAD 1 +#endif +#ifndef MVWDELCH_IS_EXPRESSION +#define MVWDELCH_IS_EXPRESSION 1 +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define PyCurses_API_pointers 4 + +/* Type declarations */ + +typedef struct { + PyObject_HEAD + WINDOW *win; + char *encoding; +} PyCursesWindowObject; + +#define PyCursesWindow_Check(v) (Py_TYPE(v) == &PyCursesWindow_Type) + +#define PyCurses_CAPSULE_NAME "_curses._C_API" + + +#ifdef CURSES_MODULE +/* This section is used when compiling _cursesmodule.c */ + +#else +/* This section is used in modules that use the _cursesmodule API */ + +static void **PyCurses_API; + +#define PyCursesWindow_Type (*(PyTypeObject *) PyCurses_API[0]) +#define PyCursesSetupTermCalled {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;} +#define PyCursesInitialised {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;} +#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;} + +#define import_curses() \ + PyCurses_API = (void **)PyCapsule_Import(PyCurses_CAPSULE_NAME, 1); + +#endif + +/* general error messages */ +static const char catchall_ERR[] = "curses function returned ERR"; +static const char catchall_NULL[] = "curses function returned NULL"; + +/* Function Prototype Macros - They are ugly but very, very useful. ;-) + + X - function name + TYPE - parameter Type + ERGSTR - format string for construction of the return value + PARSESTR - format string for argument parsing + */ + +#define NoArgNoReturnFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyCursesCheckERR(X(), # X); } + +#define NoArgOrFlagNoReturnFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self, PyObject *args) \ +{ \ + int flag = 0; \ + PyCursesInitialised \ + switch(PyTuple_Size(args)) { \ + case 0: \ + return PyCursesCheckERR(X(), # X); \ + case 1: \ + if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; \ + if (flag) return PyCursesCheckERR(X(), # X); \ + else return PyCursesCheckERR(no ## X (), # X); \ + default: \ + PyErr_SetString(PyExc_TypeError, # X " requires 0 or 1 arguments"); \ + return NULL; } } + +#define NoArgReturnIntFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyLong_FromLong((long) X()); } + + +#define NoArgReturnStringFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyBytes_FromString(X()); } + +#define NoArgTrueFalseFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + if (X () == FALSE) { \ + Py_RETURN_FALSE; \ + } \ + Py_RETURN_TRUE; } + +#define NoArgNoReturnVoidFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + X(); \ + Py_RETURN_NONE; } + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(Py_CURSES_H) */ + + diff --git a/Include/pyarena.h b/Include/pyarena.h new file mode 100644 index 0000000..db3ad01 --- /dev/null +++ b/Include/pyarena.h @@ -0,0 +1,64 @@ +/* An arena-like memory interface for the compiler. + */ + +#ifndef Py_LIMITED_API +#ifndef Py_PYARENA_H +#define Py_PYARENA_H + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _arena PyArena; + + /* PyArena_New() and PyArena_Free() create a new arena and free it, + respectively. Once an arena has been created, it can be used + to allocate memory via PyArena_Malloc(). Pointers to PyObject can + also be registered with the arena via PyArena_AddPyObject(), and the + arena will ensure that the PyObjects stay alive at least until + PyArena_Free() is called. When an arena is freed, all the memory it + allocated is freed, the arena releases internal references to registered + PyObject*, and none of its pointers are valid. + XXX (tim) What does "none of its pointers are valid" mean? Does it + XXX mean that pointers previously obtained via PyArena_Malloc() are + XXX no longer valid? (That's clearly true, but not sure that's what + XXX the text is trying to say.) + + PyArena_New() returns an arena pointer. On error, it + returns a negative number and sets an exception. + XXX (tim): Not true. On error, PyArena_New() actually returns NULL, + XXX and looks like it may or may not set an exception (e.g., if the + XXX internal PyList_New(0) returns NULL, PyArena_New() passes that on + XXX and an exception is set; OTOH, if the internal + XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but + XXX an exception is not set in that case). + */ + PyAPI_FUNC(PyArena *) PyArena_New(void); + PyAPI_FUNC(void) PyArena_Free(PyArena *); + + /* Mostly like malloc(), return the address of a block of memory spanning + * `size` bytes, or return NULL (without setting an exception) if enough + * new memory can't be obtained. Unlike malloc(0), PyArena_Malloc() with + * size=0 does not guarantee to return a unique pointer (the pointer + * returned may equal one or more other pointers obtained from + * PyArena_Malloc()). + * Note that pointers obtained via PyArena_Malloc() must never be passed to + * the system free() or realloc(), or to any of Python's similar memory- + * management functions. PyArena_Malloc()-obtained pointers remain valid + * until PyArena_Free(ar) is called, at which point all pointers obtained + * from the arena `ar` become invalid simultaneously. + */ + PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t size); + + /* This routine isn't a proper arena allocation routine. It takes + * a PyObject* and records it so that it can be DECREFed when the + * arena is freed. + */ + PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYARENA_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/pyatomic.h b/Include/pyatomic.h new file mode 100644 index 0000000..9a497a6 --- /dev/null +++ b/Include/pyatomic.h @@ -0,0 +1,535 @@ +#ifndef Py_ATOMIC_H +#define Py_ATOMIC_H +#ifdef Py_BUILD_CORE + +#include "dynamic_annotations.h" + +#include "pyconfig.h" + +#if defined(HAVE_STD_ATOMIC) +#include +#endif + + +#if defined(_MSC_VER) +#include +#include +#endif + +/* This is modeled after the atomics interface from C1x, according to + * the draft at + * http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf. + * Operations and types are named the same except with a _Py_ prefix + * and have the same semantics. + * + * Beware, the implementations here are deep magic. + */ + +#if defined(HAVE_STD_ATOMIC) + +typedef enum _Py_memory_order { + _Py_memory_order_relaxed = memory_order_relaxed, + _Py_memory_order_acquire = memory_order_acquire, + _Py_memory_order_release = memory_order_release, + _Py_memory_order_acq_rel = memory_order_acq_rel, + _Py_memory_order_seq_cst = memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + atomic_uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + atomic_int _value; +} _Py_atomic_int; + +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ + atomic_signal_fence(ORDER) + +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ + atomic_thread_fence(ORDER) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + atomic_store_explicit(&(ATOMIC_VAL)->_value, NEW_VAL, ORDER) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + atomic_load_explicit(&(ATOMIC_VAL)->_value, ORDER) + +/* Use builtin atomic operations in GCC >= 4.7 */ +#elif defined(HAVE_BUILTIN_ATOMIC) + +typedef enum _Py_memory_order { + _Py_memory_order_relaxed = __ATOMIC_RELAXED, + _Py_memory_order_acquire = __ATOMIC_ACQUIRE, + _Py_memory_order_release = __ATOMIC_RELEASE, + _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL, + _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST +} _Py_memory_order; + +typedef struct _Py_atomic_address { + uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + int _value; +} _Py_atomic_int; + +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ + __atomic_signal_fence(ORDER) + +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ + __atomic_thread_fence(ORDER) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + (assert((ORDER) == __ATOMIC_RELAXED \ + || (ORDER) == __ATOMIC_SEQ_CST \ + || (ORDER) == __ATOMIC_RELEASE), \ + __atomic_store_n(&(ATOMIC_VAL)->_value, NEW_VAL, ORDER)) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + (assert((ORDER) == __ATOMIC_RELAXED \ + || (ORDER) == __ATOMIC_SEQ_CST \ + || (ORDER) == __ATOMIC_ACQUIRE \ + || (ORDER) == __ATOMIC_CONSUME), \ + __atomic_load_n(&(ATOMIC_VAL)->_value, ORDER)) + +/* Only support GCC (for expression statements) and x86 (for simple + * atomic semantics) and MSVC x86/x64/ARM */ +#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64)) +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + int _value; +} _Py_atomic_int; + + +static __inline__ void +_Py_atomic_signal_fence(_Py_memory_order order) +{ + if (order != _Py_memory_order_relaxed) + __asm__ volatile("":::"memory"); +} + +static __inline__ void +_Py_atomic_thread_fence(_Py_memory_order order) +{ + if (order != _Py_memory_order_relaxed) + __asm__ volatile("mfence":::"memory"); +} + +/* Tell the race checker about this operation's effects. */ +static __inline__ void +_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) +{ + (void)address; /* shut up -Wunused-parameter */ + switch(order) { + case _Py_memory_order_release: + case _Py_memory_order_acq_rel: + case _Py_memory_order_seq_cst: + _Py_ANNOTATE_HAPPENS_BEFORE(address); + break; + case _Py_memory_order_relaxed: + case _Py_memory_order_acquire: + break; + } + switch(order) { + case _Py_memory_order_acquire: + case _Py_memory_order_acq_rel: + case _Py_memory_order_seq_cst: + _Py_ANNOTATE_HAPPENS_AFTER(address); + break; + case _Py_memory_order_relaxed: + case _Py_memory_order_release: + break; + } +} + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + __extension__ ({ \ + __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ + __typeof__(atomic_val->_value) new_val = NEW_VAL;\ + volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \ + _Py_memory_order order = ORDER; \ + _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ + \ + /* Perform the operation. */ \ + _Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \ + switch(order) { \ + case _Py_memory_order_release: \ + _Py_atomic_signal_fence(_Py_memory_order_release); \ + /* fallthrough */ \ + case _Py_memory_order_relaxed: \ + *volatile_data = new_val; \ + break; \ + \ + case _Py_memory_order_acquire: \ + case _Py_memory_order_acq_rel: \ + case _Py_memory_order_seq_cst: \ + __asm__ volatile("xchg %0, %1" \ + : "+r"(new_val) \ + : "m"(atomic_val->_value) \ + : "memory"); \ + break; \ + } \ + _Py_ANNOTATE_IGNORE_WRITES_END(); \ + }) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + __extension__ ({ \ + __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ + __typeof__(atomic_val->_value) result; \ + volatile __typeof__(result) *volatile_data = &atomic_val->_value; \ + _Py_memory_order order = ORDER; \ + _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ + \ + /* Perform the operation. */ \ + _Py_ANNOTATE_IGNORE_READS_BEGIN(); \ + switch(order) { \ + case _Py_memory_order_release: \ + case _Py_memory_order_acq_rel: \ + case _Py_memory_order_seq_cst: \ + /* Loads on x86 are not releases by default, so need a */ \ + /* thread fence. */ \ + _Py_atomic_thread_fence(_Py_memory_order_release); \ + break; \ + default: \ + /* No fence */ \ + break; \ + } \ + result = *volatile_data; \ + switch(order) { \ + case _Py_memory_order_acquire: \ + case _Py_memory_order_acq_rel: \ + case _Py_memory_order_seq_cst: \ + /* Loads on x86 are automatically acquire operations so */ \ + /* can get by with just a compiler fence. */ \ + _Py_atomic_signal_fence(_Py_memory_order_acquire); \ + break; \ + default: \ + /* No fence */ \ + break; \ + } \ + _Py_ANNOTATE_IGNORE_READS_END(); \ + result; \ + }) + +#elif defined(_MSC_VER) +/* _Interlocked* functions provide a full memory barrier and are therefore + enough for acq_rel and seq_cst. If the HLE variants aren't available + in hardware they will fall back to a full memory barrier as well. + + This might affect performance but likely only in some very specific and + hard to meassure scenario. +*/ +#if defined(_M_IX86) || defined(_M_X64) +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + volatile uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + volatile int _value; +} _Py_atomic_int; + + +#if defined(_M_X64) +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange64_HLEAcquire((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange64_HLERelease((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + break; \ + default: \ + _InterlockedExchange64((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + break; \ + } +#else +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); +#endif + +#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange_HLEAcquire((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange_HLERelease((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + break; \ + default: \ + _InterlockedExchange((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + break; \ + } + +#if defined(_M_X64) +/* This has to be an intptr_t for now. + gil_created() uses -1 as a sentinel value, if this returns + a uintptr_t it will do an unsigned compare and crash +*/ +inline intptr_t _Py_atomic_load_64bit(volatile uintptr_t* value, int order) { + __int64 old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old); + break; + } + } + return old; +} + +#else +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) *ATOMIC_VAL +#endif + +inline int _Py_atomic_load_32bit(volatile int* value, int order) { + long old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange((volatile long*)value, old, old) != old); + break; + } + } + return old; +} + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + if (sizeof(*ATOMIC_VAL._value) == 8) { \ + _Py_atomic_store_64bit((volatile long long*)ATOMIC_VAL._value, NEW_VAL, ORDER) } else { \ + _Py_atomic_store_32bit((volatile long*)ATOMIC_VAL._value, NEW_VAL, ORDER) } + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + ( \ + sizeof(*(ATOMIC_VAL._value)) == 8 ? \ + _Py_atomic_load_64bit((volatile long long*)ATOMIC_VAL._value, ORDER) : \ + _Py_atomic_load_32bit((volatile long*)ATOMIC_VAL._value, ORDER) \ + ) +#elif defined(_M_ARM) || defined(_M_ARM64) +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + volatile uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + volatile int _value; +} _Py_atomic_int; + + +#if defined(_M_ARM64) +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange64_acq((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange64_rel((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + break; \ + default: \ + _InterlockedExchange64((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + break; \ + } +#else +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); +#endif + +#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange_acq((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange_rel((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + break; \ + default: \ + _InterlockedExchange((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + break; \ + } + +#if defined(_M_ARM64) +/* This has to be an intptr_t for now. + gil_created() uses -1 as a sentinel value, if this returns + a uintptr_t it will do an unsigned compare and crash +*/ +inline intptr_t _Py_atomic_load_64bit(volatile uintptr_t* value, int order) { + uintptr_t old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_acq(value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_rel(value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange64(value, old, old) != old); + break; + } + } + return old; +} + +#else +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) *ATOMIC_VAL +#endif + +inline int _Py_atomic_load_32bit(volatile int* value, int order) { + int old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange_acq(value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange_rel(value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange(value, old, old) != old); + break; + } + } + return old; +} + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + if (sizeof(*ATOMIC_VAL._value) == 8) { \ + _Py_atomic_store_64bit(ATOMIC_VAL._value, NEW_VAL, ORDER) } else { \ + _Py_atomic_store_32bit(ATOMIC_VAL._value, NEW_VAL, ORDER) } + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + ( \ + sizeof(*(ATOMIC_VAL._value)) == 8 ? \ + _Py_atomic_load_64bit(ATOMIC_VAL._value, ORDER) : \ + _Py_atomic_load_32bit(ATOMIC_VAL._value, ORDER) \ + ) +#endif +#else /* !gcc x86 !_msc_ver */ +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + int _value; +} _Py_atomic_int; +/* Fall back to other compilers and processors by assuming that simple + volatile accesses are atomic. This is false, so people should port + this. */ +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0) +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0) +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + ((ATOMIC_VAL)->_value = NEW_VAL) +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + ((ATOMIC_VAL)->_value) +#endif + +/* Standardized shortcuts. */ +#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ + _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, _Py_memory_order_seq_cst) +#define _Py_atomic_load(ATOMIC_VAL) \ + _Py_atomic_load_explicit(ATOMIC_VAL, _Py_memory_order_seq_cst) + +/* Python-local extensions */ + +#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \ + _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, _Py_memory_order_relaxed) +#define _Py_atomic_load_relaxed(ATOMIC_VAL) \ + _Py_atomic_load_explicit(ATOMIC_VAL, _Py_memory_order_relaxed) +#endif /* Py_BUILD_CORE */ +#endif /* Py_ATOMIC_H */ diff --git a/Include/pycapsule.h b/Include/pycapsule.h new file mode 100644 index 0000000..d9ecda7 --- /dev/null +++ b/Include/pycapsule.h @@ -0,0 +1,59 @@ + +/* Capsule objects let you wrap a C "void *" pointer in a Python + object. They're a way of passing data through the Python interpreter + without creating your own custom type. + + Capsules are used for communication between extension modules. + They provide a way for an extension module to export a C interface + to other extension modules, so that extension modules can use the + Python import mechanism to link to one another. + + For more information, please see "c-api/capsule.html" in the + documentation. +*/ + +#ifndef Py_CAPSULE_H +#define Py_CAPSULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyCapsule_Type; + +typedef void (*PyCapsule_Destructor)(PyObject *); + +#define PyCapsule_CheckExact(op) (Py_TYPE(op) == &PyCapsule_Type) + + +PyAPI_FUNC(PyObject *) PyCapsule_New( + void *pointer, + const char *name, + PyCapsule_Destructor destructor); + +PyAPI_FUNC(void *) PyCapsule_GetPointer(PyObject *capsule, const char *name); + +PyAPI_FUNC(PyCapsule_Destructor) PyCapsule_GetDestructor(PyObject *capsule); + +PyAPI_FUNC(const char *) PyCapsule_GetName(PyObject *capsule); + +PyAPI_FUNC(void *) PyCapsule_GetContext(PyObject *capsule); + +PyAPI_FUNC(int) PyCapsule_IsValid(PyObject *capsule, const char *name); + +PyAPI_FUNC(int) PyCapsule_SetPointer(PyObject *capsule, void *pointer); + +PyAPI_FUNC(int) PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor); + +PyAPI_FUNC(int) PyCapsule_SetName(PyObject *capsule, const char *name); + +PyAPI_FUNC(int) PyCapsule_SetContext(PyObject *capsule, void *context); + +PyAPI_FUNC(void *) PyCapsule_Import( + const char *name, /* UTF-8 encoded string */ + int no_block); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CAPSULE_H */ diff --git a/Include/pyconfig.h b/Include/pyconfig.h new file mode 100644 index 0000000..d2a3f5d --- /dev/null +++ b/Include/pyconfig.h @@ -0,0 +1,693 @@ +#ifndef Py_CONFIG_H +#define Py_CONFIG_H + +/* pyconfig.h. NOT Generated automatically by configure. + +This is a manually maintained version used for the Watcom, +Borland and Microsoft Visual C++ compilers. It is a +standard part of the Python distribution. + +WINDOWS DEFINES: +The code specific to Windows should be wrapped around one of +the following #defines + +MS_WIN64 - Code specific to the MS Win64 API +MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs) +MS_WINDOWS - Code specific to Windows, but all versions. +Py_ENABLE_SHARED - Code if the Python core is built as a DLL. + +Also note that neither "_M_IX86" or "_MSC_VER" should be used for +any purpose other than "Windows Intel x86 specific" and "Microsoft +compiler specific". Therefore, these should be very rare. + + +NOTE: The following symbols are deprecated: +NT, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT +MS_CORE_DLL. + +WIN32 is still required for the locale module. + +*/ + +/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */ +#ifdef USE_DL_EXPORT +# define Py_BUILD_CORE +#endif /* USE_DL_EXPORT */ + +/* Visual Studio 2005 introduces deprecation warnings for + "insecure" and POSIX functions. The insecure functions should + be replaced by *_s versions (according to Microsoft); the + POSIX functions by _* versions (which, according to Microsoft, + would be ISO C conforming). Neither renaming is feasible, so + we just silence the warnings. */ + +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +#define HAVE_IO_H +#define HAVE_SYS_UTIME_H +#define HAVE_TEMPNAM +#define HAVE_TMPFILE +#define HAVE_TMPNAM +#define HAVE_CLOCK +#define HAVE_STRERROR + +#include + +#define HAVE_HYPOT +#define HAVE_STRFTIME +#define DONT_HAVE_SIG_ALARM +#define DONT_HAVE_SIG_PAUSE +#define LONG_BIT 32 +#define WORD_BIT 32 + +#define MS_WIN32 /* only support win32 and greater. */ +#define MS_WINDOWS +#ifndef PYTHONPATH +# define PYTHONPATH L".\\DLLs;.\\lib" +#endif +#define NT_THREADS +#define WITH_THREAD +#ifndef NETSCAPE_PI +#define USE_SOCKET +#endif + + +/* Compiler specific defines */ + +/* ------------------------------------------------------------------------*/ +/* Microsoft C defines _MSC_VER */ +#ifdef _MSC_VER + +/* We want COMPILER to expand to a string containing _MSC_VER's *value*. + * This is horridly tricky, because the stringization operator only works + * on macro arguments, and doesn't evaluate macros passed *as* arguments. + * Attempts simpler than the following appear doomed to produce "_MSC_VER" + * literally in the string. + */ +#define _Py_PASTE_VERSION(SUFFIX) \ + ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") +/* e.g., this produces, after compile-time string catenation, + * ("[MSC v.1200 32 bit (Intel)]") + * + * _Py_STRINGIZE(_MSC_VER) expands to + * _Py_STRINGIZE1((_MSC_VER)) expands to + * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting + * it's scanned again for macros and so further expands to (under MSVC 6) + * _Py_STRINGIZE2(1200) which then expands to + * "1200" + */ +#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X)) +#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X +#define _Py_STRINGIZE2(X) #X + +/* MSVC defines _WINxx to differentiate the windows platform types + + Note that for compatibility reasons _WIN32 is defined on Win32 + *and* on Win64. For the same reasons, in Python, MS_WIN32 is + defined on Win32 *and* Win64. Win32 only code must therefore be + guarded as follows: + #if defined(MS_WIN32) && !defined(MS_WIN64) +*/ +#ifdef _WIN64 +#define MS_WIN64 +#endif + +/* set the COMPILER */ +#ifdef MS_WIN64 +#if defined(_M_X64) || defined(_M_AMD64) +#if defined(__INTEL_COMPILER) +#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#else +#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") +#endif /* __INTEL_COMPILER */ +#define PYD_PLATFORM_TAG "win_amd64" +#else +#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") +#endif +#endif /* MS_WIN64 */ + +/* set the version macros for the windows headers */ +/* Python 3.5+ requires Windows Vista or greater */ +#define Py_WINVER 0x0600 /* _WIN32_WINNT_VISTA */ +#define Py_NTDDI NTDDI_VISTA + +/* We only set these values when building Python - we don't want to force + these values on extensions, as that will affect the prototypes and + structures exposed in the Windows headers. Even when building Python, we + allow a single source file to override this - they may need access to + structures etc so it can optionally use new Windows features if it + determines at runtime they are available. +*/ +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE) +#ifndef NTDDI_VERSION +#define NTDDI_VERSION Py_NTDDI +#endif +#ifndef WINVER +#define WINVER Py_WINVER +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT Py_WINVER +#endif +#endif + +/* _W64 is not defined for VC6 or eVC4 */ +#ifndef _W64 +#define _W64 +#endif + +/* Define like size_t, omitting the "unsigned" */ +#ifdef MS_WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif +#define HAVE_SSIZE_T 1 + +#if defined(MS_WIN32) && !defined(MS_WIN64) +#if defined(_M_IX86) +#if defined(__INTEL_COMPILER) +#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#else +#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") +#endif /* __INTEL_COMPILER */ +#define PYD_PLATFORM_TAG "win32" +#elif defined(_M_ARM) +#define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") +#define PYD_PLATFORM_TAG "win_arm" +#else +#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") +#endif +#endif /* MS_WIN32 && !MS_WIN64 */ + +typedef int pid_t; + +#include +#define Py_IS_NAN _isnan +#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X)) +#define Py_IS_FINITE(X) _finite(X) +#define copysign _copysign + +/* VS 2010 and above already defines hypot as _hypot */ +#if _MSC_VER < 1600 +#define hypot _hypot +#endif + +/* VS 2015 defines these names with a leading underscore */ +#if _MSC_VER >= 1900 +#define timezone _timezone +#define daylight _daylight +#define tzname _tzname +#endif + +/* Side by Side assemblies supported in VS 2005 and VS 2008 but not 2010*/ +#if _MSC_VER >= 1400 && _MSC_VER < 1600 +#define HAVE_SXS 1 +#endif + +/* define some ANSI types that are not defined in earlier Win headers */ +#if _MSC_VER >= 1200 +/* This file only exists in VC 6.0 or higher */ +#include +#endif + +#endif /* _MSC_VER */ + +/* ------------------------------------------------------------------------*/ +/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ +#if defined(__GNUC__) && defined(_WIN32) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ +/* Suggested by Rene Liebscher to avoid a GCC 2.91.* + bug that requires structure imports. More recent versions of the + compiler don't exhibit this bug. +*/ +#if (__GNUC__==2) && (__GNUC_MINOR__<=91) +#warning "Please use an up-to-date version of gcc! (>2.91 recommended)" +#endif + +#define COMPILER "[gcc]" +#define hypot _hypot +#define PY_LONG_LONG long long +#define PY_LLONG_MIN LLONG_MIN +#define PY_LLONG_MAX LLONG_MAX +#define PY_ULLONG_MAX ULLONG_MAX +#endif /* GNUC */ + +/* ------------------------------------------------------------------------*/ +/* lcc-win32 defines __LCC__ */ +#if defined(__LCC__) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ + +#define COMPILER "[lcc-win32]" +typedef int pid_t; +/* __declspec() is supported here too - do nothing to get the defaults */ + +#endif /* LCC */ + +/* ------------------------------------------------------------------------*/ +/* End of compilers - finish up */ + +#ifndef NO_STDIO_H +# include +#endif + +/* 64 bit ints are usually spelt __int64 unless compiler has overridden */ +#ifndef PY_LONG_LONG +# define PY_LONG_LONG __int64 +# define PY_LLONG_MAX _I64_MAX +# define PY_LLONG_MIN _I64_MIN +# define PY_ULLONG_MAX _UI64_MAX +#endif + +/* For Windows the Python core is in a DLL by default. Test +Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ +#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED) +# define Py_ENABLE_SHARED 1 /* standard symbol for shared library */ +# define MS_COREDLL /* deprecated old symbol */ +#endif /* !MS_NO_COREDLL && ... */ + +/* All windows compilers that use this header support __declspec */ +#define HAVE_DECLSPEC_DLL + +/* For an MSVC DLL, we can nominate the .lib files used by extensions */ +#ifdef MS_COREDLL +# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) + /* not building the core - must be an ext */ +# if defined(_MSC_VER) + /* So MSVC users need not specify the .lib + file in their Makefile (other compilers are + generally taken care of by distutils.) */ +# if defined(_DEBUG) +# pragma comment(lib,"python37_d.lib") +# elif defined(Py_LIMITED_API) +# pragma comment(lib,"python3.lib") +# else +# pragma comment(lib,"python37.lib") +# endif /* _DEBUG */ +# endif /* _MSC_VER */ +# endif /* Py_BUILD_CORE */ +#endif /* MS_COREDLL */ + +#if defined(MS_WIN64) +/* maintain "win32" sys.platform for backward compatibility of Python code, + the Win64 API should be close enough to the Win32 API to make this + preferable */ +# define PLATFORM "win32" +# define SIZEOF_VOID_P 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 8 +# define SIZEOF_SIZE_T 8 +/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff HAVE_LONG_LONG, + sizeof(off_t) > sizeof(long), and sizeof(PY_LONG_LONG) >= sizeof(off_t). + On Win64 the second condition is not true, but if fpos_t replaces off_t + then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64 + should define this. */ +# define HAVE_LARGEFILE_SUPPORT +#elif defined(MS_WIN32) +# define PLATFORM "win32" +# define HAVE_LARGEFILE_SUPPORT +# define SIZEOF_VOID_P 4 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 4 +# define SIZEOF_SIZE_T 4 + /* MS VS2005 changes time_t to a 64-bit type on all platforms */ +# if defined(_MSC_VER) && _MSC_VER >= 1400 +# define SIZEOF_TIME_T 8 +# else +# define SIZEOF_TIME_T 4 +# endif +#endif + +#ifdef _DEBUG +# define Py_DEBUG +#endif + + +#ifdef MS_WIN32 + +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_LONG 8 +#define SIZEOF_DOUBLE 8 +#define SIZEOF_FLOAT 4 + +/* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200. + Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't + define these. + If some compiler does not provide them, modify the #if appropriately. */ +#if defined(_MSC_VER) +#if _MSC_VER > 1300 +#define HAVE_UINTPTR_T 1 +#define HAVE_INTPTR_T 1 +#else +/* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */ +#define Py_LL(x) x##I64 +#endif /* _MSC_VER > 1300 */ +#endif /* _MSC_VER */ + +#endif + +/* define signed and unsigned exact-width 32-bit and 64-bit types, used in the + implementation of Python integers. */ +#define PY_UINT32_T uint32_t +#define PY_UINT64_T uint64_t +#define PY_INT32_T int32_t +#define PY_INT64_T int64_t + +/* Fairly standard from here! */ + +/* Define to 1 if you have the `copysign' function. */ +#define HAVE_COPYSIGN 1 + +/* Define to 1 if you have the `round' function. */ +#if _MSC_VER >= 1800 +#define HAVE_ROUND 1 +#endif + +/* Define to 1 if you have the `isinf' macro. */ +#define HAVE_DECL_ISINF 1 + +/* Define to 1 if you have the `isnan' function. */ +#define HAVE_DECL_ISNAN 1 + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define to empty if the keyword does not work. */ +/* #define const */ + +/* Define to 1 if you have the header file. */ +#define HAVE_CONIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DIRECT_H 1 + +/* Define if you have dirent.h. */ +/* #define DIRENT 1 */ + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +/* #undef GETGROUPS_T */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#define HAVE_TZNAME + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define if you don't have dirent.h, but have ndir.h. */ +/* #undef NDIR */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you don't have dirent.h, but have sys/dir.h. */ +/* #undef SYSDIR */ + +/* Define if you don't have dirent.h, but have sys/ndir.h. */ +/* #undef SYSNDIR */ + +/* Define if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* Define if your declares struct tm. */ +/* #define TM_IN_SYS_TIME 1 */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef VOID_CLOSEDIR */ + +/* Define if getpgrp() must be called as getpgrp(0) + and (consequently) setpgrp() as setpgrp(0, 0). */ +/* #undef GETPGRP_HAVE_ARGS */ + +/* Define this if your time.h defines altzone */ +/* #define HAVE_ALTZONE */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV + +/* Define if your compiler supports function prototypes */ +#define HAVE_PROTOTYPES + +/* Define if you can safely include both and + (which you can't on SCO ODT 3.0). */ +/* #undef SYS_SELECT_WITH_SYS_TIME */ + +/* Define if you want documentation strings in extension modules */ +#define WITH_DOC_STRINGS 1 + +/* Define if you want to compile in rudimentary thread support */ +/* #undef WITH_THREAD */ + +/* Define if you want to use the GNU readline library */ +/* #define WITH_READLINE 1 */ + +/* Use Python's own small-block memory-allocator. */ +#define WITH_PYMALLOC 1 + +/* Define if you have clock. */ +/* #define HAVE_CLOCK */ + +/* Define when any dynamic module loading is enabled */ +#define HAVE_DYNAMIC_LOADING + +/* Define if you have ftime. */ +#define HAVE_FTIME + +/* Define if you have getpeername. */ +#define HAVE_GETPEERNAME + +/* Define if you have getpgrp. */ +/* #undef HAVE_GETPGRP */ + +/* Define if you have getpid. */ +#define HAVE_GETPID + +/* Define if you have gettimeofday. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define if you have getwd. */ +/* #undef HAVE_GETWD */ + +/* Define if you have lstat. */ +/* #undef HAVE_LSTAT */ + +/* Define if you have the mktime function. */ +#define HAVE_MKTIME + +/* Define if you have nice. */ +/* #undef HAVE_NICE */ + +/* Define if you have readlink. */ +/* #undef HAVE_READLINK */ + +/* Define if you have setpgid. */ +/* #undef HAVE_SETPGID */ + +/* Define if you have setpgrp. */ +/* #undef HAVE_SETPGRP */ + +/* Define if you have setsid. */ +/* #undef HAVE_SETSID */ + +/* Define if you have setvbuf. */ +#define HAVE_SETVBUF + +/* Define if you have siginterrupt. */ +/* #undef HAVE_SIGINTERRUPT */ + +/* Define if you have symlink. */ +/* #undef HAVE_SYMLINK */ + +/* Define if you have tcgetpgrp. */ +/* #undef HAVE_TCGETPGRP */ + +/* Define if you have tcsetpgrp. */ +/* #undef HAVE_TCSETPGRP */ + +/* Define if you have times. */ +/* #undef HAVE_TIMES */ + +/* Define if you have uname. */ +/* #undef HAVE_UNAME */ + +/* Define if you have waitpid. */ +/* #undef HAVE_WAITPID */ + +/* Define to 1 if you have the `wcsftime' function. */ +#if defined(_MSC_VER) && _MSC_VER >= 1310 +#define HAVE_WCSFTIME 1 +#endif + +/* Define to 1 if you have the `wcscoll' function. */ +#define HAVE_WCSCOLL 1 + +/* Define to 1 if you have the `wcsxfrm' function. */ +#define HAVE_WCSXFRM 1 + +/* Define if the zlib library has inflateCopy */ +#define HAVE_ZLIB_COPY 1 + +/* Define if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PROCESS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define if you have the prototypes. */ +#define HAVE_STDARG_PROTOTYPES + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_AUDIOIO_H */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_PARAM_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SELECT_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIMES_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UN_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTSNAME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_UNISTD_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_UTIME_H 1 */ + +/* Define if the compiler provides a wchar.h header file. */ +#define HAVE_WCHAR_H 1 + +/* The size of `wchar_t', as computed by sizeof. */ +#define SIZEOF_WCHAR_T 2 + +/* The size of `_Bool', as computed by sizeof. */ +#define SIZEOF__BOOL 1 + +/* The size of `pid_t', as computed by sizeof. */ +#define SIZEOF_PID_T SIZEOF_INT + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define if you have the mpc library (-lmpc). */ +/* #undef HAVE_LIBMPC */ + +/* Define if you have the nsl library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define if you have the seq library (-lseq). */ +/* #undef HAVE_LIBSEQ */ + +/* Define if you have the socket library (-lsocket). */ +#define HAVE_LIBSOCKET 1 + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Define if you have the termcap library (-ltermcap). */ +/* #undef HAVE_LIBTERMCAP */ + +/* Define if you have the termlib library (-ltermlib). */ +/* #undef HAVE_LIBTERMLIB */ + +/* Define if you have the thread library (-lthread). */ +/* #undef HAVE_LIBTHREAD */ + +/* WinSock does not use a bitmask in select, and uses + socket handles greater than FD_SETSIZE */ +#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 + +/* Define to 1 if you have the `erf' function. */ +#define HAVE_ERF 1 + +/* Define to 1 if you have the `erfc' function. */ +#define HAVE_ERFC 1 + +/* Define if you have the 'inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* framework name */ +#define _PYTHONFRAMEWORK "" + +/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ +#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 + +#endif /* !Py_CONFIG_H */ diff --git a/Include/pyctype.h b/Include/pyctype.h new file mode 100644 index 0000000..6bce63e --- /dev/null +++ b/Include/pyctype.h @@ -0,0 +1,33 @@ +#ifndef Py_LIMITED_API +#ifndef PYCTYPE_H +#define PYCTYPE_H + +#define PY_CTF_LOWER 0x01 +#define PY_CTF_UPPER 0x02 +#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) +#define PY_CTF_DIGIT 0x04 +#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) +#define PY_CTF_SPACE 0x08 +#define PY_CTF_XDIGIT 0x10 + +PyAPI_DATA(const unsigned int) _Py_ctype_table[256]; + +/* Unlike their C counterparts, the following macros are not meant to + * handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument + * must be a signed/unsigned char. */ +#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) +#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) +#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) +#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) +#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) +#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) +#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) + +PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256]; +PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256]; + +#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) +#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) + +#endif /* !PYCTYPE_H */ +#endif /* !Py_LIMITED_API */ diff --git a/Include/pydebug.h b/Include/pydebug.h new file mode 100644 index 0000000..bd4aafe --- /dev/null +++ b/Include/pydebug.h @@ -0,0 +1,40 @@ +#ifndef Py_LIMITED_API +#ifndef Py_PYDEBUG_H +#define Py_PYDEBUG_H +#ifdef __cplusplus +extern "C" { +#endif + +/* These global variable are defined in pylifecycle.c */ +/* XXX (ncoghlan): move these declarations to pylifecycle.h? */ +PyAPI_DATA(int) Py_DebugFlag; +PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_QuietFlag; +PyAPI_DATA(int) Py_InteractiveFlag; +PyAPI_DATA(int) Py_InspectFlag; +PyAPI_DATA(int) Py_OptimizeFlag; +PyAPI_DATA(int) Py_NoSiteFlag; +PyAPI_DATA(int) Py_BytesWarningFlag; +PyAPI_DATA(int) Py_FrozenFlag; +PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +PyAPI_DATA(int) Py_NoUserSiteDirectory; +PyAPI_DATA(int) Py_UnbufferedStdioFlag; +PyAPI_DATA(int) Py_HashRandomizationFlag; +PyAPI_DATA(int) Py_IsolatedFlag; + +#ifdef MS_WINDOWS +PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; +PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; +#endif + +/* this is a wrapper around getenv() that pays attention to + Py_IgnoreEnvironmentFlag. It should be used for getting variables like + PYTHONPATH and PYTHONHOME from the environment */ +#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYDEBUG_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/pydtrace.h b/Include/pydtrace.h new file mode 100644 index 0000000..037961d --- /dev/null +++ b/Include/pydtrace.h @@ -0,0 +1,57 @@ +/* Static DTrace probes interface */ + +#ifndef Py_DTRACE_H +#define Py_DTRACE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WITH_DTRACE + +#include "pydtrace_probes.h" + +/* pydtrace_probes.h, on systems with DTrace, is auto-generated to include + `PyDTrace_{PROBE}` and `PyDTrace_{PROBE}_ENABLED()` macros for every probe + defined in pydtrace_provider.d. + + Calling these functions must be guarded by a `PyDTrace_{PROBE}_ENABLED()` + check to minimize performance impact when probing is off. For example: + + if (PyDTrace_FUNCTION_ENTRY_ENABLED()) + PyDTrace_FUNCTION_ENTRY(f); +*/ + +#else + +/* Without DTrace, compile to nothing. */ + +static inline void PyDTrace_LINE(const char *arg0, const char *arg1, int arg2) {} +static inline void PyDTrace_FUNCTION_ENTRY(const char *arg0, const char *arg1, int arg2) {} +static inline void PyDTrace_FUNCTION_RETURN(const char *arg0, const char *arg1, int arg2) {} +static inline void PyDTrace_GC_START(int arg0) {} +static inline void PyDTrace_GC_DONE(int arg0) {} +static inline void PyDTrace_INSTANCE_NEW_START(int arg0) {} +static inline void PyDTrace_INSTANCE_NEW_DONE(int arg0) {} +static inline void PyDTrace_INSTANCE_DELETE_START(int arg0) {} +static inline void PyDTrace_INSTANCE_DELETE_DONE(int arg0) {} +static inline void PyDTrace_IMPORT_FIND_LOAD_START(const char *arg0) {} +static inline void PyDTrace_IMPORT_FIND_LOAD_DONE(const char *arg0, int arg1) {} + +static inline int PyDTrace_LINE_ENABLED(void) { return 0; } +static inline int PyDTrace_FUNCTION_ENTRY_ENABLED(void) { return 0; } +static inline int PyDTrace_FUNCTION_RETURN_ENABLED(void) { return 0; } +static inline int PyDTrace_GC_START_ENABLED(void) { return 0; } +static inline int PyDTrace_GC_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_NEW_START_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_NEW_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_IMPORT_FIND_LOAD_START_ENABLED(void) { return 0; } +static inline int PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED(void) { return 0; } + +#endif /* !WITH_DTRACE */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_DTRACE_H */ diff --git a/Include/pyerrors.h b/Include/pyerrors.h new file mode 100644 index 0000000..f289471 --- /dev/null +++ b/Include/pyerrors.h @@ -0,0 +1,504 @@ +#ifndef Py_ERRORS_H +#define Py_ERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Error objects */ + +#ifndef Py_LIMITED_API +/* PyException_HEAD defines the initial segment of every exception class. */ +#define PyException_HEAD PyObject_HEAD PyObject *dict;\ + PyObject *args; PyObject *traceback;\ + PyObject *context; PyObject *cause;\ + char suppress_context; + +typedef struct { + PyException_HEAD +} PyBaseExceptionObject; + +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *filename; + PyObject *lineno; + PyObject *offset; + PyObject *text; + PyObject *print_file_and_line; +} PySyntaxErrorObject; + +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *name; + PyObject *path; +} PyImportErrorObject; + +typedef struct { + PyException_HEAD + PyObject *encoding; + PyObject *object; + Py_ssize_t start; + Py_ssize_t end; + PyObject *reason; +} PyUnicodeErrorObject; + +typedef struct { + PyException_HEAD + PyObject *code; +} PySystemExitObject; + +typedef struct { + PyException_HEAD + PyObject *myerrno; + PyObject *strerror; + PyObject *filename; + PyObject *filename2; +#ifdef MS_WINDOWS + PyObject *winerror; +#endif + Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */ +} PyOSErrorObject; + +typedef struct { + PyException_HEAD + PyObject *value; +} PyStopIterationObject; + +/* Compatibility typedefs */ +typedef PyOSErrorObject PyEnvironmentErrorObject; +#ifdef MS_WINDOWS +typedef PyOSErrorObject PyWindowsErrorObject; +#endif +#endif /* !Py_LIMITED_API */ + +/* Error handling definitions */ + +PyAPI_FUNC(void) PyErr_SetNone(PyObject *); +PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); +_PyErr_StackItem *_PyErr_GetTopmostException(PyThreadState *tstate); +#endif +PyAPI_FUNC(void) PyErr_SetString( + PyObject *exception, + const char *string /* decoded from utf-8 */ + ); +PyAPI_FUNC(PyObject *) PyErr_Occurred(void); +PyAPI_FUNC(void) PyErr_Clear(void); +PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); +PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(void) PyErr_GetExcInfo(PyObject **, PyObject **, PyObject **); +PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); +#endif + +#if defined(__clang__) || \ + (defined(__GNUC_MAJOR__) && \ + ((__GNUC_MAJOR__ >= 3) || \ + (__GNUC_MAJOR__ == 2) && (__GNUC_MINOR__ >= 5))) +#define _Py_NO_RETURN __attribute__((__noreturn__)) +#else +#define _Py_NO_RETURN +#endif + +/* Defined in Python/pylifecycle.c */ +PyAPI_FUNC(void) Py_FatalError(const char *message) _Py_NO_RETURN; + +#if defined(Py_DEBUG) || defined(Py_LIMITED_API) +#define _PyErr_OCCURRED() PyErr_Occurred() +#else +#define _PyErr_OCCURRED() (PyThreadState_GET()->curexc_type) +#endif + +/* Error testing and normalization */ +PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *); +PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); +PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**); + +/* Traceback manipulation (PEP 3134) */ +PyAPI_FUNC(int) PyException_SetTraceback(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyException_GetTraceback(PyObject *); + +/* Cause manipulation (PEP 3134) */ +PyAPI_FUNC(PyObject *) PyException_GetCause(PyObject *); +PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *); + +/* Context manipulation (PEP 3134) */ +PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *); +PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); +#endif + +/* */ + +#define PyExceptionClass_Check(x) \ + (PyType_Check((x)) && \ + PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS)) + +#define PyExceptionInstance_Check(x) \ + PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS) + +#define PyExceptionClass_Name(x) \ + ((char *)(((PyTypeObject*)(x))->tp_name)) + +#define PyExceptionInstance_Class(x) ((PyObject*)((x)->ob_type)) + + +/* Predefined exceptions */ + +PyAPI_DATA(PyObject *) PyExc_BaseException; +PyAPI_DATA(PyObject *) PyExc_Exception; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_DATA(PyObject *) PyExc_StopAsyncIteration; +#endif +PyAPI_DATA(PyObject *) PyExc_StopIteration; +PyAPI_DATA(PyObject *) PyExc_GeneratorExit; +PyAPI_DATA(PyObject *) PyExc_ArithmeticError; +PyAPI_DATA(PyObject *) PyExc_LookupError; + +PyAPI_DATA(PyObject *) PyExc_AssertionError; +PyAPI_DATA(PyObject *) PyExc_AttributeError; +PyAPI_DATA(PyObject *) PyExc_BufferError; +PyAPI_DATA(PyObject *) PyExc_EOFError; +PyAPI_DATA(PyObject *) PyExc_FloatingPointError; +PyAPI_DATA(PyObject *) PyExc_OSError; +PyAPI_DATA(PyObject *) PyExc_ImportError; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_DATA(PyObject *) PyExc_ModuleNotFoundError; +#endif +PyAPI_DATA(PyObject *) PyExc_IndexError; +PyAPI_DATA(PyObject *) PyExc_KeyError; +PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt; +PyAPI_DATA(PyObject *) PyExc_MemoryError; +PyAPI_DATA(PyObject *) PyExc_NameError; +PyAPI_DATA(PyObject *) PyExc_OverflowError; +PyAPI_DATA(PyObject *) PyExc_RuntimeError; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_DATA(PyObject *) PyExc_RecursionError; +#endif +PyAPI_DATA(PyObject *) PyExc_NotImplementedError; +PyAPI_DATA(PyObject *) PyExc_SyntaxError; +PyAPI_DATA(PyObject *) PyExc_IndentationError; +PyAPI_DATA(PyObject *) PyExc_TabError; +PyAPI_DATA(PyObject *) PyExc_ReferenceError; +PyAPI_DATA(PyObject *) PyExc_SystemError; +PyAPI_DATA(PyObject *) PyExc_SystemExit; +PyAPI_DATA(PyObject *) PyExc_TypeError; +PyAPI_DATA(PyObject *) PyExc_UnboundLocalError; +PyAPI_DATA(PyObject *) PyExc_UnicodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeEncodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError; +PyAPI_DATA(PyObject *) PyExc_ValueError; +PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError; + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_DATA(PyObject *) PyExc_BlockingIOError; +PyAPI_DATA(PyObject *) PyExc_BrokenPipeError; +PyAPI_DATA(PyObject *) PyExc_ChildProcessError; +PyAPI_DATA(PyObject *) PyExc_ConnectionError; +PyAPI_DATA(PyObject *) PyExc_ConnectionAbortedError; +PyAPI_DATA(PyObject *) PyExc_ConnectionRefusedError; +PyAPI_DATA(PyObject *) PyExc_ConnectionResetError; +PyAPI_DATA(PyObject *) PyExc_FileExistsError; +PyAPI_DATA(PyObject *) PyExc_FileNotFoundError; +PyAPI_DATA(PyObject *) PyExc_InterruptedError; +PyAPI_DATA(PyObject *) PyExc_IsADirectoryError; +PyAPI_DATA(PyObject *) PyExc_NotADirectoryError; +PyAPI_DATA(PyObject *) PyExc_PermissionError; +PyAPI_DATA(PyObject *) PyExc_ProcessLookupError; +PyAPI_DATA(PyObject *) PyExc_TimeoutError; +#endif + + +/* Compatibility aliases */ +PyAPI_DATA(PyObject *) PyExc_EnvironmentError; +PyAPI_DATA(PyObject *) PyExc_IOError; +#ifdef MS_WINDOWS +PyAPI_DATA(PyObject *) PyExc_WindowsError; +#endif + +/* Predefined warning categories */ +PyAPI_DATA(PyObject *) PyExc_Warning; +PyAPI_DATA(PyObject *) PyExc_UserWarning; +PyAPI_DATA(PyObject *) PyExc_DeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_SyntaxWarning; +PyAPI_DATA(PyObject *) PyExc_RuntimeWarning; +PyAPI_DATA(PyObject *) PyExc_FutureWarning; +PyAPI_DATA(PyObject *) PyExc_ImportWarning; +PyAPI_DATA(PyObject *) PyExc_UnicodeWarning; +PyAPI_DATA(PyObject *) PyExc_BytesWarning; +PyAPI_DATA(PyObject *) PyExc_ResourceWarning; + + +/* Convenience functions */ + +PyAPI_FUNC(int) PyErr_BadArgument(void); +PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( + PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObjects( + PyObject *, PyObject *, PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( + PyObject *exc, + const char *filename /* decoded from the filesystem encoding */ + ); +#if defined(MS_WINDOWS) && !defined(Py_LIMITED_API) +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename( + PyObject *, const Py_UNICODE *) Py_DEPRECATED(3.3); +#endif /* MS_WINDOWS */ + +PyAPI_FUNC(PyObject *) PyErr_Format( + PyObject *exception, + const char *format, /* ASCII-encoded string */ + ... + ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(PyObject *) PyErr_FormatV( + PyObject *exception, + const char *format, + va_list vargs); +#endif + +#ifndef Py_LIMITED_API +/* Like PyErr_Format(), but saves current exception as __context__ and + __cause__. + */ +PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause( + PyObject *exception, + const char *format, /* ASCII-encoded string */ + ... + ); +#endif + +#ifdef MS_WINDOWS +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename( + int ierr, + const char *filename /* decoded from the filesystem encoding */ + ); +#ifndef Py_LIMITED_API +/* XXX redeclare to use WSTRING */ +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( + int, const Py_UNICODE *) Py_DEPRECATED(3.3); +#endif +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *,int, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyObject *,int, PyObject *, PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( + PyObject *exc, + int ierr, + const char *filename /* decoded from the filesystem encoding */ + ); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename( + PyObject *,int, const Py_UNICODE *) Py_DEPRECATED(3.3); +#endif +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); +#endif /* MS_WINDOWS */ + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_FUNC(PyObject *) PyErr_SetImportErrorSubclass(PyObject *, PyObject *, + PyObject *, PyObject *); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyErr_SetImportError(PyObject *, PyObject *, + PyObject *); +#endif + +/* Export the old function so that the existing API remains available: */ +PyAPI_FUNC(void) PyErr_BadInternalCall(void); +PyAPI_FUNC(void) _PyErr_BadInternalCall(const char *filename, int lineno); +/* Mask the old API with a call to the new API for code compiled under + Python 2.0: */ +#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) + +/* Function to create a new exception */ +PyAPI_FUNC(PyObject *) PyErr_NewException( + const char *name, PyObject *base, PyObject *dict); +PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc( + const char *name, const char *doc, PyObject *base, PyObject *dict); +PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); + +/* In exceptions.c */ +#ifndef Py_LIMITED_API +/* Helper that attempts to replace the current exception with one of the + * same type but with a prefix added to the exception text. The resulting + * exception description looks like: + * + * prefix (exc_type: original_exc_str) + * + * Only some exceptions can be safely replaced. If the function determines + * it isn't safe to perform the replacement, it will leave the original + * unmodified exception in place. + * + * Returns a borrowed reference to the new exception (if any), NULL if the + * existing exception was left in place. + */ +PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause( + const char *prefix_format, /* ASCII-encoded string */ + ... + ); +#endif + + +/* In signalmodule.c */ +PyAPI_FUNC(int) PyErr_CheckSignals(void); +PyAPI_FUNC(void) PyErr_SetInterrupt(void); + +/* In signalmodule.c */ +#ifndef Py_LIMITED_API +int PySignal_SetWakeupFd(int fd); +#endif + +/* Support for adding program text to SyntaxErrors */ +PyAPI_FUNC(void) PyErr_SyntaxLocation( + const char *filename, /* decoded from the filesystem encoding */ + int lineno); +PyAPI_FUNC(void) PyErr_SyntaxLocationEx( + const char *filename, /* decoded from the filesystem encoding */ + int lineno, + int col_offset); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) PyErr_SyntaxLocationObject( + PyObject *filename, + int lineno, + int col_offset); +#endif +PyAPI_FUNC(PyObject *) PyErr_ProgramText( + const char *filename, /* decoded from the filesystem encoding */ + int lineno); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( + PyObject *filename, + int lineno); +#endif + +/* The following functions are used to create and modify unicode + exceptions from C */ + +/* create a UnicodeDecodeError object */ +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_Create( + const char *encoding, /* UTF-8 encoded string */ + const char *object, + Py_ssize_t length, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ); + +/* create a UnicodeEncodeError object */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( + const char *encoding, /* UTF-8 encoded string */ + const Py_UNICODE *object, + Py_ssize_t length, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ) Py_DEPRECATED(3.3); +#endif + +/* create a UnicodeTranslateError object */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( + const Py_UNICODE *object, + Py_ssize_t length, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ) Py_DEPRECATED(3.3); +PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( + PyObject *object, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ); +#endif + +/* get the encoding attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetEncoding(PyObject *); + +/* get the object attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetObject(PyObject *); + +/* get the value of the start attribute (the int * may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetStart(PyObject *, Py_ssize_t *); + +/* assign a new value to the start attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetStart(PyObject *, Py_ssize_t); + +/* get the value of the end attribute (the int *may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetEnd(PyObject *, Py_ssize_t *); + +/* assign a new value to the end attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetEnd(PyObject *, Py_ssize_t); + +/* get the value of the reason attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetReason(PyObject *); + +/* assign a new value to the reason attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetReason( + PyObject *exc, + const char *reason /* UTF-8 encoded string */ + ); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetReason( + PyObject *exc, + const char *reason /* UTF-8 encoded string */ + ); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason( + PyObject *exc, + const char *reason /* UTF-8 encoded string */ + ); + +/* These APIs aren't really part of the error implementation, but + often needed to format error messages; the native C lib APIs are + not available on all platforms, which is why we provide emulations + for those platforms in Python/mysnprintf.c, + WARNING: The return value of snprintf varies across platforms; do + not rely on any particular behavior; eventually the C99 defn may + be reliable. +*/ +#if defined(MS_WIN32) && !defined(HAVE_SNPRINTF) +# define HAVE_SNPRINTF +# define snprintf _snprintf +# define vsnprintf _vsnprintf +#endif + +#include +PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 3, 4))); +PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) + Py_GCC_ATTRIBUTE((format(printf, 3, 0))); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRORS_H */ diff --git a/Include/pyexpat.h b/Include/pyexpat.h new file mode 100644 index 0000000..44259bf --- /dev/null +++ b/Include/pyexpat.h @@ -0,0 +1,53 @@ +/* Stuff to export relevant 'expat' entry points from pyexpat to other + * parser modules, such as cElementTree. */ + +/* note: you must import expat.h before importing this module! */ + +#define PyExpat_CAPI_MAGIC "pyexpat.expat_CAPI 1.0" +#define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI" + +struct PyExpat_CAPI +{ + char* magic; /* set to PyExpat_CAPI_MAGIC */ + int size; /* set to sizeof(struct PyExpat_CAPI) */ + int MAJOR_VERSION; + int MINOR_VERSION; + int MICRO_VERSION; + /* pointers to selected expat functions. add new functions at + the end, if needed */ + const XML_LChar * (*ErrorString)(enum XML_Error code); + enum XML_Error (*GetErrorCode)(XML_Parser parser); + XML_Size (*GetErrorColumnNumber)(XML_Parser parser); + XML_Size (*GetErrorLineNumber)(XML_Parser parser); + enum XML_Status (*Parse)( + XML_Parser parser, const char *s, int len, int isFinal); + XML_Parser (*ParserCreate_MM)( + const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + void (*ParserFree)(XML_Parser parser); + void (*SetCharacterDataHandler)( + XML_Parser parser, XML_CharacterDataHandler handler); + void (*SetCommentHandler)( + XML_Parser parser, XML_CommentHandler handler); + void (*SetDefaultHandlerExpand)( + XML_Parser parser, XML_DefaultHandler handler); + void (*SetElementHandler)( + XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end); + void (*SetNamespaceDeclHandler)( + XML_Parser parser, XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + void (*SetProcessingInstructionHandler)( + XML_Parser parser, XML_ProcessingInstructionHandler handler); + void (*SetUnknownEncodingHandler)( + XML_Parser parser, XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + void (*SetUserData)(XML_Parser parser, void *userData); + void (*SetStartDoctypeDeclHandler)(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding); + int (*DefaultUnknownEncodingHandler)( + void *encodingHandlerData, const XML_Char *name, XML_Encoding *info); + /* always add new stuff to the end! */ +}; + diff --git a/Include/pyfpe.h b/Include/pyfpe.h new file mode 100644 index 0000000..5a99e39 --- /dev/null +++ b/Include/pyfpe.h @@ -0,0 +1,12 @@ +#ifndef Py_PYFPE_H +#define Py_PYFPE_H + +/* These macros used to do something when Python was built with --with-fpectl, + * but support for that was dropped in 3.7. We continue to define them though, + * to avoid breaking API users. + */ + +#define PyFPE_START_PROTECT(err_string, leave_stmt) +#define PyFPE_END_PROTECT(v) + +#endif /* !Py_PYFPE_H */ diff --git a/Include/pyhash.h b/Include/pyhash.h new file mode 100644 index 0000000..9cfd071 --- /dev/null +++ b/Include/pyhash.h @@ -0,0 +1,145 @@ +#ifndef Py_HASH_H + +#define Py_HASH_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Helpers for hash functions */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double); +PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*); +PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); +#endif + +/* Prime multiplier used in string and various other hashes. */ +#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */ + +/* Parameters used for the numeric hash implementation. See notes for + _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on + reduction modulo the prime 2**_PyHASH_BITS - 1. */ + +#if SIZEOF_VOID_P >= 8 +# define _PyHASH_BITS 61 +#else +# define _PyHASH_BITS 31 +#endif + +#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1) +#define _PyHASH_INF 314159 +#define _PyHASH_NAN 0 +#define _PyHASH_IMAG _PyHASH_MULTIPLIER + + +/* hash secret + * + * memory layout on 64 bit systems + * cccccccc cccccccc cccccccc uc -- unsigned char[24] + * pppppppp ssssssss ........ fnv -- two Py_hash_t + * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t + * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t + * ........ ........ eeeeeeee pyexpat XML hash salt + * + * memory layout on 32 bit systems + * cccccccc cccccccc cccccccc uc + * ppppssss ........ ........ fnv -- two Py_hash_t + * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*) + * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t + * ........ ........ eeee.... pyexpat XML hash salt + * + * (*) The siphash member may not be available on 32 bit platforms without + * an unsigned int64 data type. + */ +#ifndef Py_LIMITED_API +typedef union { + /* ensure 24 bytes */ + unsigned char uc[24]; + /* two Py_hash_t for FNV */ + struct { + Py_hash_t prefix; + Py_hash_t suffix; + } fnv; + /* two uint64 for SipHash24 */ + struct { + uint64_t k0; + uint64_t k1; + } siphash; + /* a different (!) Py_hash_t for small string optimization */ + struct { + unsigned char padding[16]; + Py_hash_t suffix; + } djbx33a; + struct { + unsigned char padding[16]; + Py_hash_t hashsalt; + } expat; +} _Py_HashSecret_t; +PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; +#endif + +#ifdef Py_DEBUG +PyAPI_DATA(int) _Py_HashSecret_Initialized; +#endif + + +/* hash function definition */ +#ifndef Py_LIMITED_API +typedef struct { + Py_hash_t (*const hash)(const void *, Py_ssize_t); + const char *name; + const int hash_bits; + const int seed_bits; +} PyHash_FuncDef; + +PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); +#endif + + +/* cutoff for small string DJBX33A optimization in range [1, cutoff). + * + * About 50% of the strings in a typical Python application are smaller than + * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks. + * NEVER use DJBX33A for long strings! + * + * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms + * should use a smaller cutoff because it is easier to create colliding + * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should + * provide a decent safety margin. + */ +#ifndef Py_HASH_CUTOFF +# define Py_HASH_CUTOFF 0 +#elif (Py_HASH_CUTOFF > 7 || Py_HASH_CUTOFF < 0) +# error Py_HASH_CUTOFF must in range 0...7. +#endif /* Py_HASH_CUTOFF */ + + +/* hash algorithm selection + * + * The values for Py_HASH_SIPHASH24 and Py_HASH_FNV are hard-coded in the + * configure script. + * + * - FNV is available on all platforms and architectures. + * - SIPHASH24 only works on plaforms that don't require aligned memory for integers. + * - With EXTERNAL embedders can provide an alternative implementation with:: + * + * PyHash_FuncDef PyHash_Func = {...}; + * + * XXX: Figure out __declspec() for extern PyHash_FuncDef. + */ +#define Py_HASH_EXTERNAL 0 +#define Py_HASH_SIPHASH24 1 +#define Py_HASH_FNV 2 + +#ifndef Py_HASH_ALGORITHM +# ifndef HAVE_ALIGNED_REQUIRED +# define Py_HASH_ALGORITHM Py_HASH_SIPHASH24 +# else +# define Py_HASH_ALGORITHM Py_HASH_FNV +# endif /* uint64_t && uint32_t && aligned */ +#endif /* Py_HASH_ALGORITHM */ + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_HASH_H */ diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h new file mode 100644 index 0000000..659c6df --- /dev/null +++ b/Include/pylifecycle.h @@ -0,0 +1,214 @@ + +/* Interfaces to configure, query, create & destroy the Python runtime */ + +#ifndef Py_PYLIFECYCLE_H +#define Py_PYLIFECYCLE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +typedef struct { + const char *prefix; + const char *msg; + int user_err; +} _PyInitError; + +/* Almost all errors causing Python initialization to fail */ +#ifdef _MSC_VER + /* Visual Studio 2015 doesn't implement C99 __func__ in C */ +# define _Py_INIT_GET_FUNC() __FUNCTION__ +#else +# define _Py_INIT_GET_FUNC() __func__ +#endif + +#define _Py_INIT_OK() \ + (_PyInitError){.prefix = NULL, .msg = NULL, .user_err = 0} +#define _Py_INIT_ERR(MSG) \ + (_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 0} +/* Error that can be fixed by the user like invalid input parameter. + Don't abort() the process on such error. */ +#define _Py_INIT_USER_ERR(MSG) \ + (_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 1} +#define _Py_INIT_NO_MEMORY() _Py_INIT_USER_ERR("memory allocation failed") +#define _Py_INIT_FAILED(err) \ + (err.msg != NULL) + +#endif + + +PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); + +PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); + +#ifndef Py_LIMITED_API +/* Only used by applications that embed the interpreter and need to + * override the standard encoding determination mechanism + */ +PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, + const char *errors); + +/* PEP 432 Multi-phase initialization API (Private while provisional!) */ +PyAPI_FUNC(_PyInitError) _Py_InitializeCore(const _PyCoreConfig *); +PyAPI_FUNC(int) _Py_IsCoreInitialized(void); + +PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *); +PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); +PyAPI_FUNC(int) _PyCoreConfig_Copy( + _PyCoreConfig *config, + const _PyCoreConfig *config2); + +PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read( + _PyMainInterpreterConfig *config, + const _PyCoreConfig *core_config); +PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *); +PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy( + _PyMainInterpreterConfig *config, + const _PyMainInterpreterConfig *config2); + +PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *); +#endif + +/* Initialization and finalization */ +PyAPI_FUNC(void) Py_Initialize(void); +PyAPI_FUNC(void) Py_InitializeEx(int); +#ifndef Py_LIMITED_API +PyAPI_FUNC(_PyInitError) _Py_InitializeEx_Private(int, int); +PyAPI_FUNC(void) _Py_FatalInitError(_PyInitError err) _Py_NO_RETURN; +#endif +PyAPI_FUNC(void) Py_Finalize(void); +PyAPI_FUNC(int) Py_FinalizeEx(void); +PyAPI_FUNC(int) Py_IsInitialized(void); + +/* Subinterpreter support */ +PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); +PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); + + +/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level + * exit functions. + */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(PyObject *), PyObject *); +#endif +PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); + +PyAPI_FUNC(void) Py_Exit(int) _Py_NO_RETURN; + +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_RestoreSignals(void); + +PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); +#endif + +/* Bootstrap __main__ (defined in Modules/main.c) */ +PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); +#ifdef Py_BUILD_CORE +PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv); +#endif + +/* In getpath.c */ +PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); +PyAPI_FUNC(wchar_t *) Py_GetPrefix(void); +PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); +PyAPI_FUNC(wchar_t *) Py_GetPath(void); +#ifdef Py_BUILD_CORE +PyAPI_FUNC(_PyInitError) _PyPathConfig_Init(const _PyCoreConfig *core_config); +PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv); +PyAPI_FUNC(int) _Py_FindEnvConfigValue( + FILE *env_file, + const wchar_t *key, + wchar_t *value, + size_t value_size); +#endif +PyAPI_FUNC(void) Py_SetPath(const wchar_t *); +#ifdef MS_WINDOWS +int _Py_CheckPython3(void); +#endif + +/* In their own files */ +PyAPI_FUNC(const char *) Py_GetVersion(void); +PyAPI_FUNC(const char *) Py_GetPlatform(void); +PyAPI_FUNC(const char *) Py_GetCopyright(void); +PyAPI_FUNC(const char *) Py_GetCompiler(void); +PyAPI_FUNC(const char *) Py_GetBuildInfo(void); +#ifndef Py_LIMITED_API +PyAPI_FUNC(const char *) _Py_gitidentifier(void); +PyAPI_FUNC(const char *) _Py_gitversion(void); +#endif + +/* Internal -- various one-time initializations */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); +PyAPI_FUNC(_PyInitError) _PySys_BeginInit(PyObject **sysmod); +PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict, _PyMainInterpreterConfig *config); +PyAPI_FUNC(_PyInitError) _PyImport_Init(PyInterpreterState *interp); +PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); +PyAPI_FUNC(_PyInitError) _PyImportHooks_Init(void); +PyAPI_FUNC(int) _PyFrame_Init(void); +PyAPI_FUNC(int) _PyFloat_Init(void); +PyAPI_FUNC(int) PyByteArray_Init(void); +PyAPI_FUNC(_PyInitError) _Py_HashRandomization_Init(const _PyCoreConfig *); +#endif +#ifdef Py_BUILD_CORE +PyAPI_FUNC(int) _Py_ReadHashSeed( + const char *seed_text, + int *use_hash_seed, + unsigned long *hash_seed); +#endif + +/* Various internal finalizers */ + +#ifdef Py_BUILD_CORE +PyAPI_FUNC(void) _PyExc_Fini(void); +PyAPI_FUNC(void) _PyImport_Fini(void); +PyAPI_FUNC(void) _PyImport_Fini2(void); +PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void); +PyAPI_FUNC(void) _PyGC_Fini(void); +PyAPI_FUNC(void) _PyType_Fini(void); +PyAPI_FUNC(void) _Py_HashRandomization_Fini(void); +#endif /* Py_BUILD_CORE */ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) PyMethod_Fini(void); +PyAPI_FUNC(void) PyFrame_Fini(void); +PyAPI_FUNC(void) PyCFunction_Fini(void); +PyAPI_FUNC(void) PyDict_Fini(void); +PyAPI_FUNC(void) PyTuple_Fini(void); +PyAPI_FUNC(void) PyList_Fini(void); +PyAPI_FUNC(void) PySet_Fini(void); +PyAPI_FUNC(void) PyBytes_Fini(void); +PyAPI_FUNC(void) PyByteArray_Fini(void); +PyAPI_FUNC(void) PyFloat_Fini(void); +PyAPI_FUNC(void) PyOS_FiniInterrupts(void); +PyAPI_FUNC(void) PySlice_Fini(void); +PyAPI_FUNC(void) PyAsyncGen_Fini(void); + +PyAPI_FUNC(int) _Py_IsFinalizing(void); +#endif /* !Py_LIMITED_API */ + +/* Signals */ +typedef void (*PyOS_sighandler_t)(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); + +#ifndef Py_LIMITED_API +/* Random */ +PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size); +PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size); +#endif /* !Py_LIMITED_API */ + +/* Legacy locale support */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_CoerceLegacyLocale(const _PyCoreConfig *config); +PyAPI_FUNC(int) _Py_LegacyLocaleDetected(void); +PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYLIFECYCLE_H */ diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h new file mode 100644 index 0000000..9dde11b --- /dev/null +++ b/Include/pymacconfig.h @@ -0,0 +1,102 @@ +#ifndef PYMACCONFIG_H +#define PYMACCONFIG_H + /* + * This file moves some of the autoconf magic to compile-time + * when building on MacOSX. This is needed for building 4-way + * universal binaries and for 64-bit universal binaries because + * the values redefined below aren't configure-time constant but + * only compile-time constant in these scenarios. + */ + +#if defined(__APPLE__) + +# undef SIZEOF_LONG +# undef SIZEOF_PTHREAD_T +# undef SIZEOF_SIZE_T +# undef SIZEOF_TIME_T +# undef SIZEOF_VOID_P +# undef SIZEOF__BOOL +# undef SIZEOF_UINTPTR_T +# undef SIZEOF_PTHREAD_T +# undef WORDS_BIGENDIAN +# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 +# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 +# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# undef HAVE_GCC_ASM_FOR_X87 + +# undef VA_LIST_IS_ARRAY +# if defined(__LP64__) && defined(__x86_64__) +# define VA_LIST_IS_ARRAY 1 +# endif + +# undef HAVE_LARGEFILE_SUPPORT +# ifndef __LP64__ +# define HAVE_LARGEFILE_SUPPORT 1 +# endif + +# undef SIZEOF_LONG +# ifdef __LP64__ +# define SIZEOF__BOOL 1 +# define SIZEOF__BOOL 1 +# define SIZEOF_LONG 8 +# define SIZEOF_PTHREAD_T 8 +# define SIZEOF_SIZE_T 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_VOID_P 8 +# define SIZEOF_UINTPTR_T 8 +# define SIZEOF_PTHREAD_T 8 +# else +# ifdef __ppc__ +# define SIZEOF__BOOL 4 +# else +# define SIZEOF__BOOL 1 +# endif +# define SIZEOF_LONG 4 +# define SIZEOF_PTHREAD_T 4 +# define SIZEOF_SIZE_T 4 +# define SIZEOF_TIME_T 4 +# define SIZEOF_VOID_P 4 +# define SIZEOF_UINTPTR_T 4 +# define SIZEOF_PTHREAD_T 4 +# endif + +# if defined(__LP64__) + /* MacOSX 10.4 (the first release to support 64-bit code + * at all) only supports 64-bit in the UNIX layer. + * Therefore suppress the toolbox-glue in 64-bit mode. + */ + + /* In 64-bit mode setpgrp always has no arguments, in 32-bit + * mode that depends on the compilation environment + */ +# undef SETPGRP_HAVE_ARG + +# endif + +#ifdef __BIG_ENDIAN__ +#define WORDS_BIGENDIAN 1 +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 +#else +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +#endif /* __BIG_ENDIAN */ + +#ifdef __i386__ +# define HAVE_GCC_ASM_FOR_X87 +#endif + + /* + * The definition in pyconfig.h is only valid on the OS release + * where configure ran on and not necessarily for all systems where + * the executable can be used on. + * + * Specifically: OSX 10.4 has limited supported for '%zd', while + * 10.5 has full support for '%zd'. A binary built on 10.5 won't + * work properly on 10.4 unless we suppress the definition + * of PY_FORMAT_SIZE_T + */ +#undef PY_FORMAT_SIZE_T + + +#endif /* defined(_APPLE__) */ + +#endif /* PYMACCONFIG_H */ diff --git a/Include/pymacro.h b/Include/pymacro.h new file mode 100644 index 0000000..3f6ddbe --- /dev/null +++ b/Include/pymacro.h @@ -0,0 +1,100 @@ +#ifndef Py_PYMACRO_H +#define Py_PYMACRO_H + +/* Minimum value between x and y */ +#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x)) + +/* Maximum value between x and y */ +#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y)) + +/* Absolute value of the number x */ +#define Py_ABS(x) ((x) < 0 ? -(x) : (x)) + +#define _Py_XSTRINGIFY(x) #x + +/* Convert the argument to a string. For example, Py_STRINGIFY(123) is replaced + with "123" by the preprocessor. Defines are also replaced by their value. + For example Py_STRINGIFY(__LINE__) is replaced by the line number, not + by "__LINE__". */ +#define Py_STRINGIFY(x) _Py_XSTRINGIFY(x) + +/* Get the size of a structure member in bytes */ +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) + +/* Argument must be a char or an int in [-128, 127] or [0, 255]. */ +#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff)) + +/* Assert a build-time dependency, as an expression. + + Your compile will fail if the condition isn't true, or can't be evaluated + by the compiler. This can be used in an expression: its value is 0. + + Example: + + #define foo_to_char(foo) \ + ((char *)(foo) \ + + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0)) + + Written by Rusty Russell, public domain, http://ccodearchive.net/ */ +#define Py_BUILD_ASSERT_EXPR(cond) \ + (sizeof(char [1 - 2*!(cond)]) - 1) + +#define Py_BUILD_ASSERT(cond) do { \ + (void)Py_BUILD_ASSERT_EXPR(cond); \ + } while(0) + +/* Get the number of elements in a visible array + + This does not work on pointers, or arrays declared as [], or function + parameters. With correct compiler support, such usage will cause a build + error (see Py_BUILD_ASSERT_EXPR). + + Written by Rusty Russell, public domain, http://ccodearchive.net/ + + Requires at GCC 3.1+ */ +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__) && \ + (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ >= 4))) +/* Two gcc extensions. + &a[0] degrades to a pointer: a different type from an array */ +#define Py_ARRAY_LENGTH(array) \ + (sizeof(array) / sizeof((array)[0]) \ + + Py_BUILD_ASSERT_EXPR(!__builtin_types_compatible_p(typeof(array), \ + typeof(&(array)[0])))) +#else +#define Py_ARRAY_LENGTH(array) \ + (sizeof(array) / sizeof((array)[0])) +#endif + + +/* Define macros for inline documentation. */ +#define PyDoc_VAR(name) static char name[] +#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) +#ifdef WITH_DOC_STRINGS +#define PyDoc_STR(str) str +#else +#define PyDoc_STR(str) "" +#endif + +/* Below "a" is a power of 2. */ +/* Round down size "n" to be a multiple of "a". */ +#define _Py_SIZE_ROUND_DOWN(n, a) ((size_t)(n) & ~(size_t)((a) - 1)) +/* Round up size "n" to be a multiple of "a". */ +#define _Py_SIZE_ROUND_UP(n, a) (((size_t)(n) + \ + (size_t)((a) - 1)) & ~(size_t)((a) - 1)) +/* Round pointer "p" down to the closest "a"-aligned address <= "p". */ +#define _Py_ALIGN_DOWN(p, a) ((void *)((uintptr_t)(p) & ~(uintptr_t)((a) - 1))) +/* Round pointer "p" up to the closest "a"-aligned address >= "p". */ +#define _Py_ALIGN_UP(p, a) ((void *)(((uintptr_t)(p) + \ + (uintptr_t)((a) - 1)) & ~(uintptr_t)((a) - 1))) +/* Check if pointer "p" is aligned to "a"-bytes boundary. */ +#define _Py_IS_ALIGNED(p, a) (!((uintptr_t)(p) & (uintptr_t)((a) - 1))) + +#ifdef __GNUC__ +#define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) +#else +#define Py_UNUSED(name) _unused_ ## name +#endif + +#define Py_UNREACHABLE() abort() + +#endif /* Py_PYMACRO_H */ diff --git a/Include/pymath.h b/Include/pymath.h new file mode 100644 index 0000000..6cf69f9 --- /dev/null +++ b/Include/pymath.h @@ -0,0 +1,230 @@ +#ifndef Py_PYMATH_H +#define Py_PYMATH_H + +#include "pyconfig.h" /* include for defines */ + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to mathematical +functions and constants +**************************************************************************/ + +/* Python provides implementations for copysign, round and hypot in + * Python/pymath.c just in case your math library doesn't provide the + * functions. + * + *Note: PC/pyconfig.h defines copysign as _copysign + */ +#ifndef HAVE_COPYSIGN +extern double copysign(double, double); +#endif + +#ifndef HAVE_ROUND +extern double round(double); +#endif + +#ifndef HAVE_HYPOT +extern double hypot(double, double); +#endif + +/* extra declarations */ +#ifndef _MSC_VER +#ifndef __STDC__ +extern double fmod (double, double); +extern double frexp (double, int *); +extern double ldexp (double, int); +extern double modf (double, double *); +extern double pow(double, double); +#endif /* __STDC__ */ +#endif /* _MSC_VER */ + +/* High precision definition of pi and e (Euler) + * The values are taken from libc6's math.h. + */ +#ifndef Py_MATH_PIl +#define Py_MATH_PIl 3.1415926535897932384626433832795029L +#endif +#ifndef Py_MATH_PI +#define Py_MATH_PI 3.14159265358979323846 +#endif + +#ifndef Py_MATH_El +#define Py_MATH_El 2.7182818284590452353602874713526625L +#endif + +#ifndef Py_MATH_E +#define Py_MATH_E 2.7182818284590452354 +#endif + +/* Tau (2pi) to 40 digits, taken from tauday.com/tau-digits. */ +#ifndef Py_MATH_TAU +#define Py_MATH_TAU 6.2831853071795864769252867665590057683943L +#endif + + +/* On x86, Py_FORCE_DOUBLE forces a floating-point number out of an x87 FPU + register and into a 64-bit memory location, rounding from extended + precision to double precision in the process. On other platforms it does + nothing. */ + +/* we take double rounding as evidence of x87 usage */ +#ifndef Py_LIMITED_API +#ifndef Py_FORCE_DOUBLE +# ifdef X87_DOUBLE_ROUNDING +PyAPI_FUNC(double) _Py_force_double(double); +# define Py_FORCE_DOUBLE(X) (_Py_force_double(X)) +# else +# define Py_FORCE_DOUBLE(X) (X) +# endif +#endif +#endif + +#ifndef Py_LIMITED_API +#ifdef HAVE_GCC_ASM_FOR_X87 +PyAPI_FUNC(unsigned short) _Py_get_387controlword(void); +PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); +#endif +#endif + +/* Py_IS_NAN(X) + * Return 1 if float or double arg is a NaN, else 0. + * Caution: + * X is evaluated more than once. + * This may not work on all platforms. Each platform has *some* + * way to spell this, though -- override in pyconfig.h if you have + * a platform where it doesn't work. + * Note: PC/pyconfig.h defines Py_IS_NAN as _isnan + */ +#ifndef Py_IS_NAN +#if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1 +#define Py_IS_NAN(X) isnan(X) +#else +#define Py_IS_NAN(X) ((X) != (X)) +#endif +#endif + +/* Py_IS_INFINITY(X) + * Return 1 if float or double arg is an infinity, else 0. + * Caution: + * X is evaluated more than once. + * This implementation may set the underflow flag if |X| is very small; + * it really can't be implemented correctly (& easily) before C99. + * Override in pyconfig.h if you have a better spelling on your platform. + * Py_FORCE_DOUBLE is used to avoid getting false negatives from a + * non-infinite value v sitting in an 80-bit x87 register such that + * v becomes infinite when spilled from the register to 64-bit memory. + * Note: PC/pyconfig.h defines Py_IS_INFINITY as _isinf + */ +#ifndef Py_IS_INFINITY +# if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1 +# define Py_IS_INFINITY(X) isinf(X) +# else +# define Py_IS_INFINITY(X) ((X) && \ + (Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X))) +# endif +#endif + +/* Py_IS_FINITE(X) + * Return 1 if float or double arg is neither infinite nor NAN, else 0. + * Some compilers (e.g. VisualStudio) have intrisics for this, so a special + * macro for this particular test is useful + * Note: PC/pyconfig.h defines Py_IS_FINITE as _finite + */ +#ifndef Py_IS_FINITE +#if defined HAVE_DECL_ISFINITE && HAVE_DECL_ISFINITE == 1 +#define Py_IS_FINITE(X) isfinite(X) +#elif defined HAVE_FINITE +#define Py_IS_FINITE(X) finite(X) +#else +#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) +#endif +#endif + +/* HUGE_VAL is supposed to expand to a positive double infinity. Python + * uses Py_HUGE_VAL instead because some platforms are broken in this + * respect. We used to embed code in pyport.h to try to worm around that, + * but different platforms are broken in conflicting ways. If you're on + * a platform where HUGE_VAL is defined incorrectly, fiddle your Python + * config to #define Py_HUGE_VAL to something that works on your platform. + */ +#ifndef Py_HUGE_VAL +#define Py_HUGE_VAL HUGE_VAL +#endif + +/* Py_NAN + * A value that evaluates to a NaN. On IEEE 754 platforms INF*0 or + * INF/INF works. Define Py_NO_NAN in pyconfig.h if your platform + * doesn't support NaNs. + */ +#if !defined(Py_NAN) && !defined(Py_NO_NAN) +#if !defined(__INTEL_COMPILER) + #define Py_NAN (Py_HUGE_VAL * 0.) +#else /* __INTEL_COMPILER */ + #if defined(ICC_NAN_STRICT) + #pragma float_control(push) + #pragma float_control(precise, on) + #pragma float_control(except, on) + #if defined(_MSC_VER) + __declspec(noinline) + #else /* Linux */ + __attribute__((noinline)) + #endif /* _MSC_VER */ + static double __icc_nan() + { + return sqrt(-1.0); + } + #pragma float_control (pop) + #define Py_NAN __icc_nan() + #else /* ICC_NAN_RELAXED as default for Intel Compiler */ + static const union { unsigned char buf[8]; double __icc_nan; } __nan_store = {0,0,0,0,0,0,0xf8,0x7f}; + #define Py_NAN (__nan_store.__icc_nan) + #endif /* ICC_NAN_STRICT */ +#endif /* __INTEL_COMPILER */ +#endif + +/* Py_OVERFLOWED(X) + * Return 1 iff a libm function overflowed. Set errno to 0 before calling + * a libm function, and invoke this macro after, passing the function + * result. + * Caution: + * This isn't reliable. C99 no longer requires libm to set errno under + * any exceptional condition, but does require +- HUGE_VAL return + * values on overflow. A 754 box *probably* maps HUGE_VAL to a + * double infinity, and we're cool if that's so, unless the input + * was an infinity and an infinity is the expected result. A C89 + * system sets errno to ERANGE, so we check for that too. We're + * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or + * if the returned result is a NaN, or if a C89 box returns HUGE_VAL + * in non-overflow cases. + * X is evaluated more than once. + * Some platforms have better way to spell this, so expect some #ifdef'ery. + * + * OpenBSD uses 'isinf()' because a compiler bug on that platform causes + * the longer macro version to be mis-compiled. This isn't optimal, and + * should be removed once a newer compiler is available on that platform. + * The system that had the failure was running OpenBSD 3.2 on Intel, with + * gcc 2.95.3. + * + * According to Tim's checkin, the FreeBSD systems use isinf() to work + * around a FPE bug on that platform. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#define Py_OVERFLOWED(X) isinf(X) +#else +#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \ + (X) == Py_HUGE_VAL || \ + (X) == -Py_HUGE_VAL)) +#endif + +/* Return whether integral type *type* is signed or not. */ +#define _Py_IntegralTypeSigned(type) ((type)(-1) < 0) +/* Return the maximum value of integral type *type*. */ +#define _Py_IntegralTypeMax(type) ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) +/* Return the minimum value of integral type *type*. */ +#define _Py_IntegralTypeMin(type) ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0) +/* Check whether *v* is in the range of integral type *type*. This is most + * useful if *v* is floating-point, since demoting a floating-point *v* to an + * integral type that cannot represent *v*'s integral part is undefined + * behavior. */ +#define _Py_InIntegralTypeRange(type, v) (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) + +#endif /* Py_PYMATH_H */ diff --git a/Include/pymem.h b/Include/pymem.h new file mode 100644 index 0000000..8ee0efd --- /dev/null +++ b/Include/pymem.h @@ -0,0 +1,244 @@ +/* The PyMem_ family: low-level memory allocation interfaces. + See objimpl.h for the PyObject_ memory family. +*/ + +#ifndef Py_PYMEM_H +#define Py_PYMEM_H + +#include "pyport.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); +PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyMem_RawFree(void *ptr); + +/* Configure the Python memory allocators. Pass NULL to use default + allocators. */ +PyAPI_FUNC(int) _PyMem_SetupAllocators(const char *opt); + +/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ +PyAPI_FUNC(const char*) _PyMem_GetAllocatorsName(void); + +/* Track an allocated memory block in the tracemalloc module. + Return 0 on success, return -1 on error (failed to allocate memory to store + the trace). + + Return -2 if tracemalloc is disabled. + + If memory block is already tracked, update the existing trace. */ +PyAPI_FUNC(int) PyTraceMalloc_Track( + unsigned int domain, + uintptr_t ptr, + size_t size); + +/* Untrack an allocated memory block in the tracemalloc module. + Do nothing if the block was not tracked. + + Return -2 if tracemalloc is disabled, otherwise return 0. */ +PyAPI_FUNC(int) PyTraceMalloc_Untrack( + unsigned int domain, + uintptr_t ptr); + +/* Get the traceback where a memory block was allocated. + + Return a tuple of (filename: str, lineno: int) tuples. + + Return None if the tracemalloc module is disabled or if the memory block + is not tracked by tracemalloc. + + Raise an exception and return NULL on error. */ +PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback( + unsigned int domain, + uintptr_t ptr); +#endif /* !Py_LIMITED_API */ + + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyMem_ with calls to the platform malloc/realloc/ + calloc/free. For example, on Windows different DLLs may end up using + different heaps, and if you use PyMem_Malloc you'll get the memory from the + heap used by the Python DLL; it could be a disaster if you free()'ed that + directly in your own extension. Using PyMem_Free instead ensures Python + can return the memory to the proper heap. As another example, in + PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_ + memory functions in special debugging wrappers that add additional + debugging info to dynamic memory blocks. The system routines have no idea + what to do with that stuff, and the Python wrappers have no idea what to do + with raw blocks obtained directly by the system routines then. + + The GIL must be held when using these APIs. +*/ + +/* + * Raw memory interface + * ==================== + */ + +/* Functions + + Functions supplying platform-independent semantics for malloc/realloc/ + free. These functions make sure that allocating 0 bytes returns a distinct + non-NULL pointer (whenever possible -- if we're flat out of memory, NULL + may be returned), even if the platform malloc and realloc don't. + Returned pointers must be checked for NULL explicitly. No action is + performed on failure (no exception is set, no warning is printed, etc). +*/ + +PyAPI_FUNC(void *) PyMem_Malloc(size_t size); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); +#endif +PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyMem_Free(void *ptr); + +#ifndef Py_LIMITED_API +/* strdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); + +/* strdup() using PyMem_Malloc() */ +PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); + +/* wcsdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); +#endif + +/* Macros. */ + +/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL + for malloc(0), which would be treated as an error. Some platforms + would return a pointer with no memory behind it, which would break + pymalloc. To solve these problems, allocate an extra byte. */ +/* Returns NULL to indicate error if a negative size or size larger than + Py_ssize_t can represent is supplied. Helps prevents security holes. */ +#define PyMem_MALLOC(n) PyMem_Malloc(n) +#define PyMem_REALLOC(p, n) PyMem_Realloc(p, n) +#define PyMem_FREE(p) PyMem_Free(p) + +/* + * Type-oriented memory interface + * ============================== + * + * Allocate memory for n objects of the given type. Returns a new pointer + * or NULL if the request was too large or memory allocation failed. Use + * these macros rather than doing the multiplication yourself so that proper + * overflow checking is always done. + */ + +#define PyMem_New(type, n) \ + ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + ( (type *) PyMem_Malloc((n) * sizeof(type)) ) ) +#define PyMem_NEW(type, n) \ + ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) ) + +/* + * The value of (p) is always clobbered by this macro regardless of success. + * The caller MUST check if (p) is NULL afterwards and deal with the memory + * error if so. This means the original value of (p) MUST be saved for the + * caller's memory error handler to not lose track of it. + */ +#define PyMem_Resize(p, type, n) \ + ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) +#define PyMem_RESIZE(p, type, n) \ + ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) + +/* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used + * anymore. They're just confusing aliases for PyMem_{Free,FREE} now. + */ +#define PyMem_Del PyMem_Free +#define PyMem_DEL PyMem_FREE + +#ifndef Py_LIMITED_API +typedef enum { + /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ + PYMEM_DOMAIN_RAW, + + /* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */ + PYMEM_DOMAIN_MEM, + + /* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */ + PYMEM_DOMAIN_OBJ +} PyMemAllocatorDomain; + +typedef struct { + /* user context passed as the first argument to the 4 functions */ + void *ctx; + + /* allocate a memory block */ + void* (*malloc) (void *ctx, size_t size); + + /* allocate a memory block initialized by zeros */ + void* (*calloc) (void *ctx, size_t nelem, size_t elsize); + + /* allocate or resize a memory block */ + void* (*realloc) (void *ctx, void *ptr, size_t new_size); + + /* release a memory block */ + void (*free) (void *ctx, void *ptr); +} PyMemAllocatorEx; + +/* Get the memory block allocator of the specified domain. */ +PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Set the memory block allocator of the specified domain. + + The new allocator must return a distinct non-NULL pointer when requesting + zero bytes. + + For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL + is not held when the allocator is called. + + If the new allocator is not a hook (don't call the previous allocator), the + PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks + on top on the new allocator. */ +PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Setup hooks to detect bugs in the following Python memory allocator + functions: + + - PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree() + - PyMem_Malloc(), PyMem_Realloc(), PyMem_Free() + - PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() + + Newly allocated memory is filled with the byte 0xCB, freed memory is filled + with the byte 0xDB. Additional checks: + + - detect API violations, ex: PyObject_Free() called on a buffer allocated + by PyMem_Malloc() + - detect write before the start of the buffer (buffer underflow) + - detect write after the end of the buffer (buffer overflow) + + The function does nothing if Python is not compiled is debug mode. */ +PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); +#endif + +#ifdef Py_BUILD_CORE +/* Set the memory allocator of the specified domain to the default. + Save the old allocator into *old_alloc if it's non-NULL. + Return on success, or return -1 if the domain is unknown. */ +PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( + PyMemAllocatorDomain domain, + PyMemAllocatorEx *old_alloc); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYMEM_H */ diff --git a/Include/pyport.h b/Include/pyport.h new file mode 100644 index 0000000..c1f4c7f --- /dev/null +++ b/Include/pyport.h @@ -0,0 +1,793 @@ +#ifndef Py_PYPORT_H +#define Py_PYPORT_H + +#include "pyconfig.h" /* include for defines */ + +#include + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to basic +C language & library operations whose spellings vary across platforms. + +Please try to make documentation here as clear as possible: by definition, +the stuff here is trying to illuminate C's darkest corners. + +Config #defines referenced here: + +SIGNED_RIGHT_SHIFT_ZERO_FILLS +Meaning: To be defined iff i>>j does not extend the sign bit when i is a + signed integral type and i < 0. +Used in: Py_ARITHMETIC_RIGHT_SHIFT + +Py_DEBUG +Meaning: Extra checks compiled in for debug mode. +Used in: Py_SAFE_DOWNCAST + +**************************************************************************/ + +/* typedefs for some C9X-defined synonyms for integral types. + * + * The names in Python are exactly the same as the C9X names, except with a + * Py_ prefix. Until C9X is universally implemented, this is the only way + * to ensure that Python gets reliable names that don't conflict with names + * in non-Python code that are playing their own tricks to define the C9X + * names. + * + * NOTE: don't go nuts here! Python has no use for *most* of the C9X + * integral synonyms. Only define the ones we actually need. + */ + +/* long long is required. Ensure HAVE_LONG_LONG is defined for compatibility. */ +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 +#endif +#ifndef PY_LONG_LONG +#define PY_LONG_LONG long long +/* If LLONG_MAX is defined in limits.h, use that. */ +#define PY_LLONG_MIN LLONG_MIN +#define PY_LLONG_MAX LLONG_MAX +#define PY_ULLONG_MAX ULLONG_MAX +#endif + +#define PY_UINT32_T uint32_t +#define PY_UINT64_T uint64_t + +/* Signed variants of the above */ +#define PY_INT32_T int32_t +#define PY_INT64_T int64_t + +/* If PYLONG_BITS_IN_DIGIT is not defined then we'll use 30-bit digits if all + the necessary integer types are available, and we're on a 64-bit platform + (as determined by SIZEOF_VOID_P); otherwise we use 15-bit digits. */ + +#ifndef PYLONG_BITS_IN_DIGIT +#if SIZEOF_VOID_P >= 8 +#define PYLONG_BITS_IN_DIGIT 30 +#else +#define PYLONG_BITS_IN_DIGIT 15 +#endif +#endif + +/* uintptr_t is the C9X name for an unsigned integral type such that a + * legitimate void* can be cast to uintptr_t and then back to void* again + * without loss of information. Similarly for intptr_t, wrt a signed + * integral type. + */ +typedef uintptr_t Py_uintptr_t; +typedef intptr_t Py_intptr_t; + +/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) == + * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an + * unsigned integral type). See PEP 353 for details. + */ +#ifdef HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef Py_intptr_t Py_ssize_t; +#else +# error "Python needs a typedef for Py_ssize_t in pyport.h." +#endif + +/* Py_hash_t is the same size as a pointer. */ +#define SIZEOF_PY_HASH_T SIZEOF_SIZE_T +typedef Py_ssize_t Py_hash_t; +/* Py_uhash_t is the unsigned equivalent needed to calculate numeric hash. */ +#define SIZEOF_PY_UHASH_T SIZEOF_SIZE_T +typedef size_t Py_uhash_t; + +/* Only used for compatibility with code that may not be PY_SSIZE_T_CLEAN. */ +#ifdef PY_SSIZE_T_CLEAN +typedef Py_ssize_t Py_ssize_clean_t; +#else +typedef int Py_ssize_clean_t; +#endif + +/* Largest possible value of size_t. */ +#define PY_SIZE_MAX SIZE_MAX + +/* Largest positive value of type Py_ssize_t. */ +#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1)) +/* Smallest negative value of type Py_ssize_t. */ +#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) + +/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf + * format to convert an argument with the width of a size_t or Py_ssize_t. + * C99 introduced "z" for this purpose, but not all platforms support that; + * e.g., MS compilers use "I" instead. + * + * These "high level" Python format functions interpret "z" correctly on + * all platforms (Python interprets the format string itself, and does whatever + * the platform C requires to convert a size_t/Py_ssize_t argument): + * + * PyBytes_FromFormat + * PyErr_Format + * PyBytes_FromFormatV + * PyUnicode_FromFormatV + * + * Lower-level uses require that you interpolate the correct format modifier + * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for + * example, + * + * Py_ssize_t index; + * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index); + * + * That will expand to %ld, or %Id, or to something else correct for a + * Py_ssize_t on the platform. + */ +#ifndef PY_FORMAT_SIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__) +# define PY_FORMAT_SIZE_T "" +# elif SIZEOF_SIZE_T == SIZEOF_LONG +# define PY_FORMAT_SIZE_T "l" +# elif defined(MS_WINDOWS) +# define PY_FORMAT_SIZE_T "I" +# else +# error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T" +# endif +#endif + +/* Py_LOCAL can be used instead of static to get the fastest possible calling + * convention for functions that are local to a given module. + * + * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining, + * for platforms that support that. + * + * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more + * "aggressive" inlining/optimization is enabled for the entire module. This + * may lead to code bloat, and may slow things down for those reasons. It may + * also lead to errors, if the code relies on pointer aliasing. Use with + * care. + * + * NOTE: You can only use this for functions that are entirely local to a + * module; functions that are exported via method tables, callbacks, etc, + * should keep using static. + */ + +#if defined(_MSC_VER) +#if defined(PY_LOCAL_AGGRESSIVE) +/* enable more aggressive optimization for visual studio */ +#pragma optimize("agtw", on) +#endif +/* ignore warnings if the compiler decides not to inline a function */ +#pragma warning(disable: 4710) +/* fastest possible local call under MSVC */ +#define Py_LOCAL(type) static type __fastcall +#define Py_LOCAL_INLINE(type) static __inline type __fastcall +#else +#define Py_LOCAL(type) static type +#define Py_LOCAL_INLINE(type) static inline type +#endif + +/* Py_MEMCPY is kept for backwards compatibility, + * see https://bugs.python.org/issue28126 */ +#define Py_MEMCPY memcpy + +#include + +#ifdef HAVE_IEEEFP_H +#include /* needed for 'finite' declaration on some platforms */ +#endif + +#include /* Moved here from the math section, before extern "C" */ + +/******************************************** + * WRAPPER FOR and/or * + ********************************************/ + +#ifdef TIME_WITH_SYS_TIME +#include +#include +#else /* !TIME_WITH_SYS_TIME */ +#ifdef HAVE_SYS_TIME_H +#include +#else /* !HAVE_SYS_TIME_H */ +#include +#endif /* !HAVE_SYS_TIME_H */ +#endif /* !TIME_WITH_SYS_TIME */ + + +/****************************** + * WRAPPER FOR * + ******************************/ + +/* NB caller must include */ + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* !HAVE_SYS_SELECT_H */ + +/******************************* + * stat() and fstat() fiddling * + *******************************/ + +#ifdef HAVE_SYS_STAT_H +#include +#elif defined(HAVE_STAT_H) +#include +#endif + +#ifndef S_IFMT +/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */ +#define S_IFMT 0170000 +#endif + +#ifndef S_IFLNK +/* Windows doesn't define S_IFLNK but posixmodule.c maps + * IO_REPARSE_TAG_SYMLINK to S_IFLNK */ +# define S_IFLNK 0120000 +#endif + +#ifndef S_ISREG +#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISDIR +#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif + +#ifndef S_ISCHR +#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) +#endif + +#ifdef __cplusplus +/* Move this down here since some C++ #include's don't like to be included + inside an extern "C" */ +extern "C" { +#endif + + +/* Py_ARITHMETIC_RIGHT_SHIFT + * C doesn't define whether a right-shift of a signed integer sign-extends + * or zero-fills. Here a macro to force sign extension: + * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) + * Return I >> J, forcing sign extension. Arithmetically, return the + * floor of I/2**J. + * Requirements: + * I should have signed integer type. In the terminology of C99, this can + * be either one of the five standard signed integer types (signed char, + * short, int, long, long long) or an extended signed integer type. + * J is an integer >= 0 and strictly less than the number of bits in the + * type of I (because C doesn't define what happens for J outside that + * range either). + * TYPE used to specify the type of I, but is now ignored. It's been left + * in for backwards compatibility with versions <= 2.6 or 3.0. + * Caution: + * I may be evaluated more than once. + */ +#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \ + ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J)) +#else +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J)) +#endif + +/* Py_FORCE_EXPANSION(X) + * "Simply" returns its argument. However, macro expansions within the + * argument are evaluated. This unfortunate trickery is needed to get + * token-pasting to work as desired in some cases. + */ +#define Py_FORCE_EXPANSION(X) X + +/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) + * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this + * assert-fails if any information is lost. + * Caution: + * VALUE may be evaluated more than once. + */ +#ifdef Py_DEBUG +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \ + (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE)) +#else +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE) +#endif + +/* Py_SET_ERRNO_ON_MATH_ERROR(x) + * If a libm function did not set errno, but it looks like the result + * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno + * to 0 before calling a libm function, and invoke this macro after, + * passing the function result. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X is evaluated more than once. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64)) +#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM; +#else +#define _Py_SET_EDOM_FOR_NAN(X) ; +#endif +#define Py_SET_ERRNO_ON_MATH_ERROR(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + else _Py_SET_EDOM_FOR_NAN(X) \ + } \ + } while(0) + +/* Py_SET_ERANGE_ON_OVERFLOW(x) + * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility. + */ +#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X) + +/* Py_ADJUST_ERANGE1(x) + * Py_ADJUST_ERANGE2(x, y) + * Set errno to 0 before calling a libm function, and invoke one of these + * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful + * for functions returning complex results). This makes two kinds of + * adjustments to errno: (A) If it looks like the platform libm set + * errno=ERANGE due to underflow, clear errno. (B) If it looks like the + * platform libm overflowed but didn't set errno, force errno to ERANGE. In + * effect, we're trying to force a useful implementation of C89 errno + * behavior. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X and Y may be evaluated more than once. + */ +#define Py_ADJUST_ERANGE1(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE && (X) == 0.0) \ + errno = 0; \ + } while(0) + +#define Py_ADJUST_ERANGE2(X, Y) \ + do { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \ + (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \ + if (errno == 0) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE) \ + errno = 0; \ + } while(0) + +/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are + * required to support the short float repr introduced in Python 3.1) require + * that the floating-point unit that's being used for arithmetic operations + * on C doubles is set to use 53-bit precision. It also requires that the + * FPU rounding mode is round-half-to-even, but that's less often an issue. + * + * If your FPU isn't already set to 53-bit precision/round-half-to-even, and + * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should + * + * #define HAVE_PY_SET_53BIT_PRECISION 1 + * + * and also give appropriate definitions for the following three macros: + * + * _PY_SET_53BIT_PRECISION_START : store original FPU settings, and + * set FPU to 53-bit precision/round-half-to-even + * _PY_SET_53BIT_PRECISION_END : restore original FPU settings + * _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to + * use the two macros above. + * + * The macros are designed to be used within a single C function: see + * Python/pystrtod.c for an example of their use. + */ + +/* get and set x87 control word for gcc/x86 */ +#ifdef HAVE_GCC_ASM_FOR_X87 +#define HAVE_PY_SET_53BIT_PRECISION 1 +/* _Py_get/set_387controlword functions are defined in Python/pymath.c */ +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned short old_387controlword, new_387controlword +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + old_387controlword = _Py_get_387controlword(); \ + new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(new_387controlword); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(old_387controlword) +#endif + +/* get and set x87 control word for VisualStudio/x86 */ +#if defined(_MSC_VER) && !defined(_WIN64) /* x87 not supported in 64-bit */ +#define HAVE_PY_SET_53BIT_PRECISION 1 +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned int old_387controlword, new_387controlword, out_387controlword +/* We use the __control87_2 function to set only the x87 control word. + The SSE control word is unaffected. */ +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + __control87_2(0, 0, &old_387controlword, NULL); \ + new_387controlword = \ + (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \ + if (new_387controlword != old_387controlword) \ + __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \ + &out_387controlword, NULL); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + do { \ + if (new_387controlword != old_387controlword) \ + __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \ + &out_387controlword, NULL); \ + } while (0) +#endif + +#ifdef HAVE_GCC_ASM_FOR_MC68881 +#define HAVE_PY_SET_53BIT_PRECISION 1 +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned int old_fpcr, new_fpcr +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \ + /* Set double precision / round to nearest. */ \ + new_fpcr = (old_fpcr & ~0xf0) | 0x80; \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + do { \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \ + } while (0) +#endif + +/* default definitions are empty */ +#ifndef HAVE_PY_SET_53BIT_PRECISION +#define _Py_SET_53BIT_PRECISION_HEADER +#define _Py_SET_53BIT_PRECISION_START +#define _Py_SET_53BIT_PRECISION_END +#endif + +/* If we can't guarantee 53-bit precision, don't use the code + in Python/dtoa.c, but fall back to standard code. This + means that repr of a float will be long (17 sig digits). + + Realistically, there are two things that could go wrong: + + (1) doubles aren't IEEE 754 doubles, or + (2) we're on x86 with the rounding precision set to 64-bits + (extended precision), and we don't know how to change + the rounding precision. + */ + +#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +#define PY_NO_SHORT_FLOAT_REPR +#endif + +/* double rounding is symptomatic of use of extended precision on x86. If + we're seeing double rounding, and we don't have any mechanism available for + changing the FPU rounding precision, then don't use Python/dtoa.c. */ +#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) +#define PY_NO_SHORT_FLOAT_REPR +#endif + + +/* Py_DEPRECATED(version) + * Declare a variable, type, or function deprecated. + * Usage: + * extern int old_var Py_DEPRECATED(2.3); + * typedef int T1 Py_DEPRECATED(2.4); + * extern int x() Py_DEPRECATED(2.5); + */ +#if defined(__GNUC__) \ + && ((__GNUC__ >= 4) || (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) +#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +#else +#define Py_DEPRECATED(VERSION_UNUSED) +#endif + + +/* _Py_HOT_FUNCTION + * The hot attribute on a function is used to inform the compiler that the + * function is a hot spot of the compiled program. The function is optimized + * more aggressively and on many target it is placed into special subsection of + * the text section so all hot functions appears close together improving + * locality. + * + * Usage: + * int _Py_HOT_FUNCTION x(void) { return 3; } + * + * Issue #28618: This attribute must not be abused, otherwise it can have a + * negative effect on performance. Only the functions were Python spend most of + * its time must use it. Use a profiler when running performance benchmark + * suite to find these functions. + */ +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) +#define _Py_HOT_FUNCTION __attribute__((hot)) +#else +#define _Py_HOT_FUNCTION +#endif + +/* _Py_NO_INLINE + * Disable inlining on a function. For example, it helps to reduce the C stack + * consumption. + * + * Usage: + * int _Py_NO_INLINE x(void) { return 3; } + */ +#if defined(__GNUC__) || defined(__clang__) +# define _Py_NO_INLINE __attribute__((noinline)) +#else +# define _Py_NO_INLINE +#endif + +/************************************************************************** +Prototypes that are missing from the standard include files on some systems +(and possibly only some versions of such systems.) + +Please be conservative with adding new ones, document them and enclose them +in platform-specific #ifdefs. +**************************************************************************/ + +#ifdef SOLARIS +/* Unchecked */ +extern int gethostname(char *, int); +#endif + +#ifdef HAVE__GETPTY +#include /* we need to import mode_t */ +extern char * _getpty(int *, int, mode_t, int); +#endif + +/* On QNX 6, struct termio must be declared by including sys/termio.h + if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must + be included before termios.h or it will generate an error. */ +#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux) +#include +#endif + + +/* On 4.4BSD-descendants, ctype functions serves the whole range of + * wchar_t character set rather than single byte code points only. + * This characteristic can break some operations of string object + * including str.upper() and str.split() on UTF-8 locales. This + * workaround was provided by Tim Robbins of FreeBSD project. + */ + +#if defined(__APPLE__) +# define _PY_PORT_CTYPE_UTF8_ISSUE +#endif + +#ifdef _PY_PORT_CTYPE_UTF8_ISSUE +#ifndef __cplusplus + /* The workaround below is unsafe in C++ because + * the defines these symbols as real functions, + * with a slightly different signature. + * See issue #10910 + */ +#include +#include +#undef isalnum +#define isalnum(c) iswalnum(btowc(c)) +#undef isalpha +#define isalpha(c) iswalpha(btowc(c)) +#undef islower +#define islower(c) iswlower(btowc(c)) +#undef isspace +#define isspace(c) iswspace(btowc(c)) +#undef isupper +#define isupper(c) iswupper(btowc(c)) +#undef tolower +#define tolower(c) towlower(btowc(c)) +#undef toupper +#define toupper(c) towupper(btowc(c)) +#endif +#endif + + +/* Declarations for symbol visibility. + + PyAPI_FUNC(type): Declares a public Python API function and return type + PyAPI_DATA(type): Declares public Python data and its type + PyMODINIT_FUNC: A Python module init function. If these functions are + inside the Python core, they are private to the core. + If in an extension module, it may be declared with + external linkage depending on the platform. + + As a number of platforms support/require "__declspec(dllimport/dllexport)", + we support a HAVE_DECLSPEC_DLL macro to save duplication. +*/ + +/* + All windows ports, except cygwin, are handled in PC/pyconfig.h. + + Cygwin is the only other autoconf platform requiring special + linkage handling and it uses __declspec(). +*/ +#if defined(__CYGWIN__) +# define HAVE_DECLSPEC_DLL +#endif + +/* only get special linkage if built as shared or platform is Cygwin */ +#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) +# if defined(HAVE_DECLSPEC_DLL) +# if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) +# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE +# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE + /* module init functions inside the core need no external linkage */ + /* except for Cygwin to handle embedding */ +# if defined(__CYGWIN__) +# define PyMODINIT_FUNC __declspec(dllexport) PyObject* +# else /* __CYGWIN__ */ +# define PyMODINIT_FUNC PyObject* +# endif /* __CYGWIN__ */ +# else /* Py_BUILD_CORE */ + /* Building an extension module, or an embedded situation */ + /* public Python functions and data are imported */ + /* Under Cygwin, auto-import functions to prevent compilation */ + /* failures similar to those described at the bottom of 4.1: */ + /* http://docs.python.org/extending/windows.html#a-cookbook-approach */ +# if !defined(__CYGWIN__) +# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE +# endif /* !__CYGWIN__ */ +# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE + /* module init functions outside the core must be exported */ +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" __declspec(dllexport) PyObject* +# else /* __cplusplus */ +# define PyMODINIT_FUNC __declspec(dllexport) PyObject* +# endif /* __cplusplus */ +# endif /* Py_BUILD_CORE */ +# endif /* HAVE_DECLSPEC_DLL */ +#endif /* Py_ENABLE_SHARED */ + +/* If no external linkage macros defined by now, create defaults */ +#ifndef PyAPI_FUNC +# define PyAPI_FUNC(RTYPE) RTYPE +#endif +#ifndef PyAPI_DATA +# define PyAPI_DATA(RTYPE) extern RTYPE +#endif +#ifndef PyMODINIT_FUNC +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" PyObject* +# else /* __cplusplus */ +# define PyMODINIT_FUNC PyObject* +# endif /* __cplusplus */ +#endif + +/* limits.h constants that may be missing */ + +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif + +#ifndef LONG_MAX +#if SIZEOF_LONG == 4 +#define LONG_MAX 0X7FFFFFFFL +#elif SIZEOF_LONG == 8 +#define LONG_MAX 0X7FFFFFFFFFFFFFFFL +#else +#error "could not set LONG_MAX in pyport.h" +#endif +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * SIZEOF_LONG) +#endif + +#if LONG_BIT != 8 * SIZEOF_LONG +/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent + * 32-bit platforms using gcc. We try to catch that here at compile-time + * rather than waiting for integer multiplication to trigger bogus + * overflows. + */ +#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." +#endif + +#ifdef __cplusplus +} +#endif + +/* + * Hide GCC attributes from compilers that don't support them. + */ +#if (!defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) +#define Py_GCC_ATTRIBUTE(x) +#else +#define Py_GCC_ATTRIBUTE(x) __attribute__(x) +#endif + +/* + * Specify alignment on compilers that support it. + */ +#if defined(__GNUC__) && __GNUC__ >= 3 +#define Py_ALIGNED(x) __attribute__((aligned(x))) +#else +#define Py_ALIGNED(x) +#endif + +/* Eliminate end-of-loop code not reached warnings from SunPro C + * when using do{...}while(0) macros + */ +#ifdef __SUNPRO_C +#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED) +#endif + +#ifndef Py_LL +#define Py_LL(x) x##LL +#endif + +#ifndef Py_ULL +#define Py_ULL(x) Py_LL(x##U) +#endif + +#define Py_VA_COPY va_copy + +/* + * Convenient macros to deal with endianness of the platform. WORDS_BIGENDIAN is + * detected by configure and defined in pyconfig.h. The code in pyconfig.h + * also takes care of Apple's universal builds. + */ + +#ifdef WORDS_BIGENDIAN +#define PY_BIG_ENDIAN 1 +#define PY_LITTLE_ENDIAN 0 +#else +#define PY_BIG_ENDIAN 0 +#define PY_LITTLE_ENDIAN 1 +#endif + +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) +/* + * Macros to protect CRT calls against instant termination when passed an + * invalid parameter (issue23524). + */ +#if defined _MSC_VER && _MSC_VER >= 1900 + +extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; +#define _Py_BEGIN_SUPPRESS_IPH { _invalid_parameter_handler _Py_old_handler = \ + _set_thread_local_invalid_parameter_handler(_Py_silent_invalid_parameter_handler); +#define _Py_END_SUPPRESS_IPH _set_thread_local_invalid_parameter_handler(_Py_old_handler); } + +#else + +#define _Py_BEGIN_SUPPRESS_IPH +#define _Py_END_SUPPRESS_IPH + +#endif /* _MSC_VER >= 1900 */ +#endif /* Py_BUILD_CORE */ + +#ifdef __ANDROID__ +/* The Android langinfo.h header is not used. */ +#undef HAVE_LANGINFO_H +#undef CODESET +#endif + +/* Maximum value of the Windows DWORD type */ +#define PY_DWORD_MAX 4294967295U + +/* This macro used to tell whether Python was built with multithreading + * enabled. Now multithreading is always enabled, but keep the macro + * for compatibility. + */ +#ifndef WITH_THREAD +#define WITH_THREAD +#endif + +#endif /* Py_PYPORT_H */ diff --git a/Include/pystate.h b/Include/pystate.h new file mode 100644 index 0000000..29d7148 --- /dev/null +++ b/Include/pystate.h @@ -0,0 +1,452 @@ + +/* Thread and interpreter state structures and their interfaces */ + + +#ifndef Py_PYSTATE_H +#define Py_PYSTATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "pythread.h" + +/* This limitation is for performance and simplicity. If needed it can be +removed (with effort). */ +#define MAX_CO_EXTRA_USERS 255 + +/* State shared between threads */ + +struct _ts; /* Forward */ +struct _is; /* Forward */ +struct _frame; /* Forward declaration for PyFrameObject. */ + +#ifdef Py_LIMITED_API +typedef struct _is PyInterpreterState; +#else +typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); + + +typedef struct { + int install_signal_handlers; /* Install signal handlers? -1 means unset */ + + int ignore_environment; /* -E, Py_IgnoreEnvironmentFlag */ + int use_hash_seed; /* PYTHONHASHSEED=x */ + unsigned long hash_seed; + const char *allocator; /* Memory allocator: _PyMem_SetupAllocators() */ + int dev_mode; /* PYTHONDEVMODE, -X dev */ + int faulthandler; /* PYTHONFAULTHANDLER, -X faulthandler */ + int tracemalloc; /* PYTHONTRACEMALLOC, -X tracemalloc=N */ + int import_time; /* PYTHONPROFILEIMPORTTIME, -X importtime */ + int show_ref_count; /* -X showrefcount */ + int show_alloc_count; /* -X showalloccount */ + int dump_refs; /* PYTHONDUMPREFS */ + int malloc_stats; /* PYTHONMALLOCSTATS */ + int coerce_c_locale; /* PYTHONCOERCECLOCALE, -1 means unknown */ + int coerce_c_locale_warn; /* PYTHONCOERCECLOCALE=warn */ + int utf8_mode; /* PYTHONUTF8, -X utf8; -1 means unknown */ + + wchar_t *program_name; /* Program name, see also Py_GetProgramName() */ + int argc; /* Number of command line arguments, + -1 means unset */ + wchar_t **argv; /* Command line arguments */ + wchar_t *program; /* argv[0] or "" */ + + int nxoption; /* Number of -X options */ + wchar_t **xoptions; /* -X options */ + + int nwarnoption; /* Number of warnings options */ + wchar_t **warnoptions; /* Warnings options */ + + /* Path configuration inputs */ + wchar_t *module_search_path_env; /* PYTHONPATH environment variable */ + wchar_t *home; /* PYTHONHOME environment variable, + see also Py_SetPythonHome(). */ + + /* Path configuration outputs */ + int nmodule_search_path; /* Number of sys.path paths, + -1 means unset */ + wchar_t **module_search_paths; /* sys.path paths */ + wchar_t *executable; /* sys.executable */ + wchar_t *prefix; /* sys.prefix */ + wchar_t *base_prefix; /* sys.base_prefix */ + wchar_t *exec_prefix; /* sys.exec_prefix */ + wchar_t *base_exec_prefix; /* sys.base_exec_prefix */ + + /* Private fields */ + int _disable_importlib; /* Needed by freeze_importlib */ +} _PyCoreConfig; + +#define _PyCoreConfig_INIT \ + (_PyCoreConfig){ \ + .install_signal_handlers = -1, \ + .use_hash_seed = -1, \ + .coerce_c_locale = -1, \ + .utf8_mode = -1, \ + .argc = -1, \ + .nmodule_search_path = -1} +/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */ + +/* Placeholders while working on the new configuration API + * + * See PEP 432 for final anticipated contents + */ +typedef struct { + int install_signal_handlers; /* Install signal handlers? -1 means unset */ + PyObject *argv; /* sys.argv list, can be NULL */ + PyObject *executable; /* sys.executable str */ + PyObject *prefix; /* sys.prefix str */ + PyObject *base_prefix; /* sys.base_prefix str, can be NULL */ + PyObject *exec_prefix; /* sys.exec_prefix str */ + PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */ + PyObject *warnoptions; /* sys.warnoptions list, can be NULL */ + PyObject *xoptions; /* sys._xoptions dict, can be NULL */ + PyObject *module_search_path; /* sys.path list */ +} _PyMainInterpreterConfig; + +#define _PyMainInterpreterConfig_INIT \ + (_PyMainInterpreterConfig){.install_signal_handlers = -1} +/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */ + +typedef struct _is { + + struct _is *next; + struct _ts *tstate_head; + + int64_t id; + int64_t id_refcount; + PyThread_type_lock id_mutex; + + PyObject *modules; + PyObject *modules_by_index; + PyObject *sysdict; + PyObject *builtins; + PyObject *importlib; + + /* Used in Python/sysmodule.c. */ + int check_interval; + + /* Used in Modules/_threadmodule.c. */ + long num_threads; + /* Support for runtime thread stack size tuning. + A value of 0 means using the platform's default stack size + or the size specified by the THREAD_STACK_SIZE macro. */ + /* Used in Python/thread.c. */ + size_t pythread_stacksize; + + PyObject *codec_search_path; + PyObject *codec_search_cache; + PyObject *codec_error_registry; + int codecs_initialized; + int fscodec_initialized; + + _PyCoreConfig core_config; + _PyMainInterpreterConfig config; +#ifdef HAVE_DLOPEN + int dlopenflags; +#endif + + PyObject *builtins_copy; + PyObject *import_func; + /* Initialized to PyEval_EvalFrameDefault(). */ + _PyFrameEvalFunction eval_frame; + + Py_ssize_t co_extra_user_count; + freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; + +#ifdef HAVE_FORK + PyObject *before_forkers; + PyObject *after_forkers_parent; + PyObject *after_forkers_child; +#endif + /* AtExit module */ + void (*pyexitfunc)(PyObject *); + PyObject *pyexitmodule; + + uint64_t tstate_next_unique_id; +} PyInterpreterState; +#endif /* !Py_LIMITED_API */ + + +/* State unique per thread */ + +#ifndef Py_LIMITED_API +/* Py_tracefunc return -1 when raising an exception, or 0 for success. */ +typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); + +/* The following values are used for 'what' for tracefunc functions + * + * To add a new kind of trace event, also update "trace_init" in + * Python/sysmodule.c to define the Python level event name + */ +#define PyTrace_CALL 0 +#define PyTrace_EXCEPTION 1 +#define PyTrace_LINE 2 +#define PyTrace_RETURN 3 +#define PyTrace_C_CALL 4 +#define PyTrace_C_EXCEPTION 5 +#define PyTrace_C_RETURN 6 +#define PyTrace_OPCODE 7 +#endif /* Py_LIMITED_API */ + +#ifdef Py_LIMITED_API +typedef struct _ts PyThreadState; +#else + +typedef struct _err_stackitem { + /* This struct represents an entry on the exception stack, which is a + * per-coroutine state. (Coroutine in the computer science sense, + * including the thread and generators). + * This ensures that the exception state is not impacted by "yields" + * from an except handler. + */ + PyObject *exc_type, *exc_value, *exc_traceback; + + struct _err_stackitem *previous_item; + +} _PyErr_StackItem; + + +typedef struct _ts { + /* See Python/ceval.c for comments explaining most fields */ + + struct _ts *prev; + struct _ts *next; + PyInterpreterState *interp; + + struct _frame *frame; + int recursion_depth; + char overflowed; /* The stack has overflowed. Allow 50 more calls + to handle the runtime error. */ + char recursion_critical; /* The current calls must not cause + a stack overflow. */ + int stackcheck_counter; + + /* 'tracing' keeps track of the execution depth when tracing/profiling. + This is to prevent the actual trace/profile code from being recorded in + the trace/profile. */ + int tracing; + int use_tracing; + + Py_tracefunc c_profilefunc; + Py_tracefunc c_tracefunc; + PyObject *c_profileobj; + PyObject *c_traceobj; + + /* The exception currently being raised */ + PyObject *curexc_type; + PyObject *curexc_value; + PyObject *curexc_traceback; + + /* The exception currently being handled, if no coroutines/generators + * are present. Always last element on the stack referred to be exc_info. + */ + _PyErr_StackItem exc_state; + + /* Pointer to the top of the stack of the exceptions currently + * being handled */ + _PyErr_StackItem *exc_info; + + PyObject *dict; /* Stores per-thread state */ + + int gilstate_counter; + + PyObject *async_exc; /* Asynchronous exception to raise */ + unsigned long thread_id; /* Thread id where this tstate was created */ + + int trash_delete_nesting; + PyObject *trash_delete_later; + + /* Called when a thread state is deleted normally, but not when it + * is destroyed after fork(). + * Pain: to prevent rare but fatal shutdown errors (issue 18808), + * Thread.join() must wait for the join'ed thread's tstate to be unlinked + * from the tstate chain. That happens at the end of a thread's life, + * in pystate.c. + * The obvious way doesn't quite work: create a lock which the tstate + * unlinking code releases, and have Thread.join() wait to acquire that + * lock. The problem is that we _are_ at the end of the thread's life: + * if the thread holds the last reference to the lock, decref'ing the + * lock will delete the lock, and that may trigger arbitrary Python code + * if there's a weakref, with a callback, to the lock. But by this time + * _PyThreadState_Current is already NULL, so only the simplest of C code + * can be allowed to run (in particular it must not be possible to + * release the GIL). + * So instead of holding the lock directly, the tstate holds a weakref to + * the lock: that's the value of on_delete_data below. Decref'ing a + * weakref is harmless. + * on_delete points to _threadmodule.c's static release_sentinel() function. + * After the tstate is unlinked, release_sentinel is called with the + * weakref-to-lock (on_delete_data) argument, and release_sentinel releases + * the indirectly held lock. + */ + void (*on_delete)(void *); + void *on_delete_data; + + int coroutine_origin_tracking_depth; + + PyObject *coroutine_wrapper; + int in_coroutine_wrapper; + + PyObject *async_gen_firstiter; + PyObject *async_gen_finalizer; + + PyObject *context; + uint64_t context_ver; + + /* Unique thread state id. */ + uint64_t id; + + /* XXX signal handlers should also be here */ + +} PyThreadState; +#endif /* !Py_LIMITED_API */ + + +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); +PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); +PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +/* New in 3.7 */ +PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); +#endif /* !Py_LIMITED_API */ +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* New in 3.3 */ +PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*); +PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*); +#endif +PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyState_ClearModules(void); +#endif + +PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); +PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyGILState_Reinit(void); +#endif /* !Py_LIMITED_API */ + +/* Return the current thread state. The global interpreter lock must be held. + * When the current thread state is NULL, this issues a fatal error (so that + * the caller needn't check for NULL). */ +PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); + +#ifndef Py_LIMITED_API +/* Similar to PyThreadState_Get(), but don't issue a fatal error + * if it is NULL. */ +PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); +#endif /* !Py_LIMITED_API */ + +PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); +PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); +PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *); + + +/* Variable and macro for in-line access to current thread state */ + +/* Assuming the current thread holds the GIL, this is the + PyThreadState for the current thread. */ +#ifdef Py_BUILD_CORE +# define _PyThreadState_Current _PyRuntime.gilstate.tstate_current +# define PyThreadState_GET() \ + ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) +#else +# define PyThreadState_GET() PyThreadState_Get() +#endif + +typedef + enum {PyGILState_LOCKED, PyGILState_UNLOCKED} + PyGILState_STATE; + + +/* Ensure that the current thread is ready to call the Python + C API, regardless of the current state of Python, or of its + thread lock. This may be called as many times as desired + by a thread so long as each call is matched with a call to + PyGILState_Release(). In general, other thread-state APIs may + be used between _Ensure() and _Release() calls, so long as the + thread-state is restored to its previous state before the Release(). + For example, normal use of the Py_BEGIN_ALLOW_THREADS/ + Py_END_ALLOW_THREADS macros are acceptable. + + The return value is an opaque "handle" to the thread state when + PyGILState_Ensure() was called, and must be passed to + PyGILState_Release() to ensure Python is left in the same state. Even + though recursive calls are allowed, these handles can *not* be shared - + each unique call to PyGILState_Ensure must save the handle for its + call to PyGILState_Release. + + When the function returns, the current thread will hold the GIL. + + Failure is a fatal error. +*/ +PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure(void); + +/* Release any resources previously acquired. After this call, Python's + state will be the same as it was prior to the corresponding + PyGILState_Ensure() call (but generally this state will be unknown to + the caller, hence the use of the GILState API.) + + Every call to PyGILState_Ensure must be matched by a call to + PyGILState_Release on the same thread. +*/ +PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE); + +/* Helper/diagnostic function - get the current thread state for + this thread. May return NULL if no GILState API has been used + on the current thread. Note that the main thread always has such a + thread-state, even if no auto-thread-state call has been made + on the main thread. +*/ +PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); + +#ifndef Py_LIMITED_API +/* Helper/diagnostic function - return 1 if the current thread + currently holds the GIL, 0 otherwise. + + The function returns 1 if _PyGILState_check_enabled is non-zero. */ +PyAPI_FUNC(int) PyGILState_Check(void); + +/* Unsafe function to get the single PyInterpreterState used by this process' + GILState implementation. + + Return NULL before _PyGILState_Init() is called and after _PyGILState_Fini() + is called. */ +PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); +#endif /* !Py_LIMITED_API */ + + +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); +#endif + +/* Routines for advanced debuggers, requested by David Beazley. + Don't use unless you know what you are doing! */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); + +typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYSTATE_H */ diff --git a/Include/pystrcmp.h b/Include/pystrcmp.h new file mode 100644 index 0000000..edb1239 --- /dev/null +++ b/Include/pystrcmp.h @@ -0,0 +1,23 @@ +#ifndef Py_STRCMP_H +#define Py_STRCMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyOS_mystrnicmp(const char *, const char *, Py_ssize_t); +PyAPI_FUNC(int) PyOS_mystricmp(const char *, const char *); + +#ifdef MS_WINDOWS +#define PyOS_strnicmp strnicmp +#define PyOS_stricmp stricmp +#else +#define PyOS_strnicmp PyOS_mystrnicmp +#define PyOS_stricmp PyOS_mystricmp +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRCMP_H */ diff --git a/Include/pystrhex.h b/Include/pystrhex.h new file mode 100644 index 0000000..66a30e2 --- /dev/null +++ b/Include/pystrhex.h @@ -0,0 +1,19 @@ +#ifndef Py_STRHEX_H +#define Py_STRHEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +/* Returns a str() containing the hex representation of argbuf. */ +PyAPI_FUNC(PyObject*) _Py_strhex(const char* argbuf, const Py_ssize_t arglen); +/* Returns a bytes() containing the ASCII hex representation of argbuf. */ +PyAPI_FUNC(PyObject*) _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen); +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRHEX_H */ diff --git a/Include/pystrtod.h b/Include/pystrtod.h new file mode 100644 index 0000000..c1e84de --- /dev/null +++ b/Include/pystrtod.h @@ -0,0 +1,45 @@ +#ifndef Py_STRTOD_H +#define Py_STRTOD_H + +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_FUNC(double) PyOS_string_to_double(const char *str, + char **endptr, + PyObject *overflow_exception); + +/* The caller is responsible for calling PyMem_Free to free the buffer + that's is returned. */ +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _Py_string_to_number_with_underscores( + const char *str, Py_ssize_t len, const char *what, PyObject *obj, void *arg, + PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)); + +PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr); +#endif + + +/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ +#define Py_DTSF_SIGN 0x01 /* always add the sign */ +#define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ +#define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code + specific */ + +/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ +#define Py_DTST_FINITE 0 +#define Py_DTST_INFINITE 1 +#define Py_DTST_NAN 2 + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRTOD_H */ diff --git a/Include/pythonrun.h b/Include/pythonrun.h new file mode 100644 index 0000000..6f0c6fc --- /dev/null +++ b/Include/pythonrun.h @@ -0,0 +1,181 @@ + +/* Interfaces to parse and execute pieces of python code */ + +#ifndef Py_PYTHONRUN_H +#define Py_PYTHONRUN_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_AnyFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_SimpleFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); + +PyAPI_FUNC(struct _mod *) PyParser_ASTFromString( + const char *s, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyCompilerFlags *flags, + PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromStringObject( + const char *s, + PyObject *filename, + int start, + PyCompilerFlags *flags, + PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + const char* enc, + int start, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromFileObject( + FILE *fp, + PyObject *filename, + const char* enc, + int start, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); +#endif + +#ifndef PyParser_SimpleParseString +#define PyParser_SimpleParseString(S, B) \ + PyParser_SimpleParseStringFlags(S, B, 0) +#define PyParser_SimpleParseFile(FP, S, B) \ + PyParser_SimpleParseFileFlags(FP, S, B, 0) +#endif +PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, + int); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlagsFilename(const char *, + const char *, + int, int); +#endif +PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, + int, int); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, + PyObject *, PyCompilerFlags *); + +PyAPI_FUNC(PyObject *) PyRun_FileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyObject *globals, + PyObject *locals, + int closeit, + PyCompilerFlags *flags); +#endif + +#ifdef Py_LIMITED_API +PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int); +#else +#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1) +#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1) +PyAPI_FUNC(PyObject *) Py_CompileStringExFlags( + const char *str, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyCompilerFlags *flags, + int optimize); +PyAPI_FUNC(PyObject *) Py_CompileStringObject( + const char *str, + PyObject *filename, int start, + PyCompilerFlags *flags, + int optimize); +#endif +PyAPI_FUNC(struct symtable *) Py_SymtableString( + const char *str, + const char *filename, /* decoded from the filesystem encoding */ + int start); +#ifndef Py_LIMITED_API +PyAPI_FUNC(struct symtable *) Py_SymtableStringObject( + const char *str, + PyObject *filename, + int start); +#endif + +PyAPI_FUNC(void) PyErr_Print(void); +PyAPI_FUNC(void) PyErr_PrintEx(int); +PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); + +#ifndef Py_LIMITED_API +/* Use macros for a bunch of old variants */ +#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) +#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) +#define PyRun_AnyFileEx(fp, name, closeit) \ + PyRun_AnyFileExFlags(fp, name, closeit, NULL) +#define PyRun_AnyFileFlags(fp, name, flags) \ + PyRun_AnyFileExFlags(fp, name, 0, flags) +#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL) +#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL) +#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL) +#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL) +#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL) +#define PyRun_File(fp, p, s, g, l) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, NULL) +#define PyRun_FileEx(fp, p, s, g, l, c) \ + PyRun_FileExFlags(fp, p, s, g, l, c, NULL) +#define PyRun_FileFlags(fp, p, s, g, l, flags) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, flags) +#endif + +/* Stuff with no proper home (yet) */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); +#endif +PyAPI_DATA(int) (*PyOS_InputHook)(void); +PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *); +#ifndef Py_LIMITED_API +PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; +#endif + +/* Stack size, in "pointers" (so we get extra safety margins + on 64-bit platforms). On a 32-bit platform, this translates + to an 8k margin. */ +#define PYOS_STACK_MARGIN 2048 + +#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1300 +/* Enable stack checking under Microsoft C */ +#define USE_STACKCHECK +#endif + +#ifdef USE_STACKCHECK +/* Check that we aren't overflowing our stack */ +PyAPI_FUNC(int) PyOS_CheckStack(void); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYTHONRUN_H */ diff --git a/Include/pythread.h b/Include/pythread.h new file mode 100644 index 0000000..eb61033 --- /dev/null +++ b/Include/pythread.h @@ -0,0 +1,155 @@ + +#ifndef Py_PYTHREAD_H +#define Py_PYTHREAD_H + +typedef void *PyThread_type_lock; +typedef void *PyThread_type_sema; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return status codes for Python lock acquisition. Chosen for maximum + * backwards compatibility, ie failure -> 0, success -> 1. */ +typedef enum PyLockStatus { + PY_LOCK_FAILURE = 0, + PY_LOCK_ACQUIRED = 1, + PY_LOCK_INTR +} PyLockStatus; + +#ifndef Py_LIMITED_API +#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) +#endif + +PyAPI_FUNC(void) PyThread_init_thread(void); +PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); +PyAPI_FUNC(void) PyThread_exit_thread(void); +PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); + +PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); +PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); +PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); +#define WAIT_LOCK 1 +#define NOWAIT_LOCK 0 + +/* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting + on a lock (see PyThread_acquire_lock_timed() below). + PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that + type, and depends on the system threading API. + + NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread + module exposes a higher-level API, with timeouts expressed in seconds + and floating-point numbers allowed. +*/ +#define PY_TIMEOUT_T long long + +#if defined(_POSIX_THREADS) + /* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000), + convert microseconds to nanoseconds. */ +# define PY_TIMEOUT_MAX (PY_LLONG_MAX / 1000) +#elif defined (NT_THREADS) + /* In the NT API, the timeout is a DWORD and is expressed in milliseconds */ +# if 0xFFFFFFFFLL * 1000 < PY_LLONG_MAX +# define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000) +# else +# define PY_TIMEOUT_MAX PY_LLONG_MAX +# endif +#else +# define PY_TIMEOUT_MAX PY_LLONG_MAX +#endif + + +/* If microseconds == 0, the call is non-blocking: it returns immediately + even when the lock can't be acquired. + If microseconds > 0, the call waits up to the specified duration. + If microseconds < 0, the call waits until success (or abnormal failure) + + microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is + undefined. + + If intr_flag is true and the acquire is interrupted by a signal, then the + call will return PY_LOCK_INTR. The caller may reattempt to acquire the + lock. +*/ +PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed(PyThread_type_lock, + PY_TIMEOUT_T microseconds, + int intr_flag); + +PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock); + +PyAPI_FUNC(size_t) PyThread_get_stacksize(void); +PyAPI_FUNC(int) PyThread_set_stacksize(size_t); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyThread_GetInfo(void); +#endif + + +/* Thread Local Storage (TLS) API + TLS API is DEPRECATED. Use Thread Specific Storage (TSS) API. + + The existing TLS API has used int to represent TLS keys across all + platforms, but it is not POSIX-compliant. Therefore, the new TSS API uses + opaque data type to represent TSS keys to be compatible (see PEP 539). +*/ +PyAPI_FUNC(int) PyThread_create_key(void) Py_DEPRECATED(3.7); +PyAPI_FUNC(void) PyThread_delete_key(int key) Py_DEPRECATED(3.7); +PyAPI_FUNC(int) PyThread_set_key_value(int key, void *value) Py_DEPRECATED(3.7); +PyAPI_FUNC(void *) PyThread_get_key_value(int key) Py_DEPRECATED(3.7); +PyAPI_FUNC(void) PyThread_delete_key_value(int key) Py_DEPRECATED(3.7); + +/* Cleanup after a fork */ +PyAPI_FUNC(void) PyThread_ReInitTLS(void) Py_DEPRECATED(3.7); + + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +/* New in 3.7 */ +/* Thread Specific Storage (TSS) API */ + +typedef struct _Py_tss_t Py_tss_t; /* opaque */ + +#ifndef Py_LIMITED_API +#if defined(_POSIX_THREADS) + /* Darwin needs pthread.h to know type name the pthread_key_t. */ +# include +# define NATIVE_TSS_KEY_T pthread_key_t +#elif defined(NT_THREADS) + /* In Windows, native TSS key type is DWORD, + but hardcode the unsigned long to avoid errors for include directive. + */ +# define NATIVE_TSS_KEY_T unsigned long +#else +# error "Require native threads. See https://bugs.python.org/issue31370" +#endif + +/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is + exposed to allow static allocation in the API clients. Even in this case, + you must handle TSS keys through API functions due to compatibility. +*/ +struct _Py_tss_t { + int _is_initialized; + NATIVE_TSS_KEY_T _key; +}; + +#undef NATIVE_TSS_KEY_T + +/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */ +#define Py_tss_NEEDS_INIT {0} +#endif /* !Py_LIMITED_API */ + +PyAPI_FUNC(Py_tss_t *) PyThread_tss_alloc(void); +PyAPI_FUNC(void) PyThread_tss_free(Py_tss_t *key); + +/* The parameter key must not be NULL. */ +PyAPI_FUNC(int) PyThread_tss_is_created(Py_tss_t *key); +PyAPI_FUNC(int) PyThread_tss_create(Py_tss_t *key); +PyAPI_FUNC(void) PyThread_tss_delete(Py_tss_t *key); +PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t *key, void *value); +PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t *key); +#endif /* New in 3.7 */ + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYTHREAD_H */ diff --git a/Include/pytime.h b/Include/pytime.h new file mode 100644 index 0000000..4870a9d --- /dev/null +++ b/Include/pytime.h @@ -0,0 +1,246 @@ +#ifndef Py_LIMITED_API +#ifndef Py_PYTIME_H +#define Py_PYTIME_H + +#include "pyconfig.h" /* include for defines */ +#include "object.h" + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to time related +functions and constants +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +/* _PyTime_t: Python timestamp with subsecond precision. It can be used to + store a duration, and so indirectly a date (related to another date, like + UNIX epoch). */ +typedef int64_t _PyTime_t; +#define _PyTime_MIN PY_LLONG_MIN +#define _PyTime_MAX PY_LLONG_MAX + +typedef enum { + /* Round towards minus infinity (-inf). + For example, used to read a clock. */ + _PyTime_ROUND_FLOOR=0, + /* Round towards infinity (+inf). + For example, used for timeout to wait "at least" N seconds. */ + _PyTime_ROUND_CEILING=1, + /* Round to nearest with ties going to nearest even integer. + For example, used to round from a Python float. */ + _PyTime_ROUND_HALF_EVEN=2, + /* Round away from zero + For example, used for timeout. _PyTime_ROUND_CEILING rounds + -1e-9 to 0 milliseconds which causes bpo-31786 issue. + _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps + the timeout sign as expected. select.poll(timeout) must block + for negative values." */ + _PyTime_ROUND_UP=3, + /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be + used for timeouts. */ + _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP +} _PyTime_round_t; + + +/* Convert a time_t to a PyLong. */ +PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( + time_t sec); + +/* Convert a PyLong to a time_t. */ +PyAPI_FUNC(time_t) _PyLong_AsTime_t( + PyObject *obj); + +/* Convert a number of seconds, int or float, to time_t. */ +PyAPI_FUNC(int) _PyTime_ObjectToTime_t( + PyObject *obj, + time_t *sec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timeval structure. + usec is in the range [0; 999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimeval( + PyObject *obj, + time_t *sec, + long *usec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timespec structure. + nsec is in the range [0; 999999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimespec( + PyObject *obj, + time_t *sec, + long *nsec, + _PyTime_round_t); + + +/* Create a timestamp from a number of seconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); + +/* Macro to create a timestamp from a number of seconds, no integer overflow. + Only use the macro for small values, prefer _PyTime_FromSeconds(). */ +#define _PYTIME_FROMSECONDS(seconds) \ + ((_PyTime_t)(seconds) * (1000 * 1000 * 1000)) + +/* Create a timestamp from a number of nanoseconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); + +/* Create a timestamp from nanoseconds (Python int). */ +PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, + PyObject *obj); + +/* Convert a number of seconds (Python float or int) to a timetamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a number of milliseconds (Python float or int, 10^-3) to a timetamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds as a C double. */ +PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); + +/* Convert timestamp to a number of milliseconds (10^-3 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of microseconds (10^-6 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int + object. */ +PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t); + +/* Create a timestamp from a timeval structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); + +/* Convert a timestamp to a timeval structure (microsecond resolution). + tv_usec is always positive. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Similar to _PyTime_AsTimeval(), but don't raise an exception on error. */ +PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds (secs) and microseconds (us). + us is always positive. This function is similar to _PyTime_AsTimeval() + except that secs is always a time_t type, whereas the timeval structure + uses a C long for tv_sec on Windows. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( + _PyTime_t t, + time_t *secs, + int *us, + _PyTime_round_t round); + +#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) +/* Create a timestamp from a timespec structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts); + +/* Convert a timestamp to a timespec structure (nanosecond resolution). + tv_nsec is always positive. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts); +#endif + +/* Compute ticks * mul / div. + The caller must ensure that ((div - 1) * mul) cannot overflow. */ +PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks, + _PyTime_t mul, + _PyTime_t div); + +/* Get the current time from the system clock. + + The function cannot fail. _PyTime_Init() ensures that the system clock + works. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + The function cannot fail. _PyTime_Init() ensures that a monotonic clock + is available and works. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); + + +/* Structure used by time.get_clock_info() */ +typedef struct { + const char *implementation; + int monotonic; + int adjustable; + double resolution; +} _Py_clock_info_t; + +/* Get the current time from the system clock. + * Fill clock information if info is not NULL. + * Raise an exception and return -1 on error, return 0 on success. + */ +PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + + +/* Initialize time. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_Init(void); + +/* Converts a timestamp to the Gregorian time, using the local time zone. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); + +/* Converts a timestamp to the Gregorian time, assuming UTC. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + The function cannot fail. _PyTime_Init() ensures that the system clock + works. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + +#ifdef __cplusplus +} +#endif + +#endif /* Py_PYTIME_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/rangeobject.h b/Include/rangeobject.h new file mode 100644 index 0000000..7e4dc28 --- /dev/null +++ b/Include/rangeobject.h @@ -0,0 +1,27 @@ + +/* Range object interface */ + +#ifndef Py_RANGEOBJECT_H +#define Py_RANGEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* +A range object represents an integer range. This is an immutable object; +a range cannot change its value after creation. + +Range objects behave like the corresponding tuple objects except that +they are represented by a start, stop, and step datamembers. +*/ + +PyAPI_DATA(PyTypeObject) PyRange_Type; +PyAPI_DATA(PyTypeObject) PyRangeIter_Type; +PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type; + +#define PyRange_Check(op) (Py_TYPE(op) == &PyRange_Type) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_RANGEOBJECT_H */ diff --git a/Include/setobject.h b/Include/setobject.h new file mode 100644 index 0000000..fc0ea83 --- /dev/null +++ b/Include/setobject.h @@ -0,0 +1,108 @@ +/* Set object interface */ + +#ifndef Py_SETOBJECT_H +#define Py_SETOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + +/* There are three kinds of entries in the table: + +1. Unused: key == NULL and hash == 0 +2. Dummy: key == dummy and hash == -1 +3. Active: key != NULL and key != dummy and hash != -1 + +The hash field of Unused slots is always zero. + +The hash field of Dummy slots are set to -1 +meaning that dummy entries can be detected by +either entry->key==dummy or by entry->hash==-1. +*/ + +#define PySet_MINSIZE 8 + +typedef struct { + PyObject *key; + Py_hash_t hash; /* Cached hash code of the key */ +} setentry; + +/* The SetObject data structure is shared by set and frozenset objects. + +Invariant for sets: + - hash is -1 + +Invariants for frozensets: + - data is immutable. + - hash is the hash of the frozenset or -1 if not computed yet. + +*/ + +typedef struct { + PyObject_HEAD + + Py_ssize_t fill; /* Number active and dummy entries*/ + Py_ssize_t used; /* Number active entries */ + + /* The table contains mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t mask; + + /* The table points to a fixed-size smalltable for small tables + * or to additional malloc'ed memory for bigger tables. + * The table pointer is never NULL which saves us from repeated + * runtime null-tests. + */ + setentry *table; + Py_hash_t hash; /* Only used by frozenset objects */ + Py_ssize_t finger; /* Search finger for pop() */ + + setentry smalltable[PySet_MINSIZE]; + PyObject *weakreflist; /* List of weak references */ +} PySetObject; + +#define PySet_GET_SIZE(so) (assert(PyAnySet_Check(so)),(((PySetObject *)(so))->used)) + +PyAPI_DATA(PyObject *) _PySet_Dummy; + +PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); +PyAPI_FUNC(int) PySet_ClearFreeList(void); + +#endif /* Section excluded by Py_LIMITED_API */ + +PyAPI_DATA(PyTypeObject) PySet_Type; +PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; +PyAPI_DATA(PyTypeObject) PySetIter_Type; + +PyAPI_FUNC(PyObject *) PySet_New(PyObject *); +PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); + +PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); +PyAPI_FUNC(int) PySet_Clear(PyObject *set); +PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); +PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); +PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); +PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); + +#define PyFrozenSet_CheckExact(ob) (Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyAnySet_CheckExact(ob) \ + (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyAnySet_Check(ob) \ + (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ + PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) +#define PySet_Check(ob) \ + (Py_TYPE(ob) == &PySet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) +#define PyFrozenSet_Check(ob) \ + (Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SETOBJECT_H */ diff --git a/Include/sliceobject.h b/Include/sliceobject.h new file mode 100644 index 0000000..c238b09 --- /dev/null +++ b/Include/sliceobject.h @@ -0,0 +1,63 @@ +#ifndef Py_SLICEOBJECT_H +#define Py_SLICEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* The unique ellipsis object "..." */ + +PyAPI_DATA(PyObject) _Py_EllipsisObject; /* Don't use this directly */ + +#define Py_Ellipsis (&_Py_EllipsisObject) + +/* Slice object interface */ + +/* + +A slice object containing start, stop, and step data members (the +names are from range). After much talk with Guido, it was decided to +let these be any arbitrary python type. Py_None stands for omitted values. +*/ +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + PyObject *start, *stop, *step; /* not NULL */ +} PySliceObject; +#endif + +PyAPI_DATA(PyTypeObject) PySlice_Type; +PyAPI_DATA(PyTypeObject) PyEllipsis_Type; + +#define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) + +PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, + PyObject* step); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop); +PyAPI_FUNC(int) _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, + PyObject **start_ptr, PyObject **stop_ptr, + PyObject **step_ptr); +#endif +PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t *step, Py_ssize_t *slicelength) Py_DEPRECATED(3.7); + +#if !defined(Py_LIMITED_API) || (Py_LIMITED_API+0 >= 0x03050400 && Py_LIMITED_API+0 < 0x03060000) || Py_LIMITED_API+0 >= 0x03060100 +#define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \ + PySlice_Unpack((slice), (start), (stop), (step)) < 0 ? \ + ((*(slicelen) = 0), -1) : \ + ((*(slicelen) = PySlice_AdjustIndices((length), (start), (stop), *(step))), \ + 0)) +PyAPI_FUNC(int) PySlice_Unpack(PyObject *slice, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +PyAPI_FUNC(Py_ssize_t) PySlice_AdjustIndices(Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t step); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SLICEOBJECT_H */ diff --git a/Include/structmember.h b/Include/structmember.h new file mode 100644 index 0000000..b54f708 --- /dev/null +++ b/Include/structmember.h @@ -0,0 +1,74 @@ +#ifndef Py_STRUCTMEMBER_H +#define Py_STRUCTMEMBER_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to map C struct members to Python object attributes */ + +#include /* For offsetof */ + +/* An array of PyMemberDef structures defines the name, type and offset + of selected members of a C structure. These can be read by + PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY + flag is set). The array must be terminated with an entry whose name + pointer is NULL. */ + +typedef struct PyMemberDef { + const char *name; + int type; + Py_ssize_t offset; + int flags; + const char *doc; +} PyMemberDef; + +/* Types */ +#define T_SHORT 0 +#define T_INT 1 +#define T_LONG 2 +#define T_FLOAT 3 +#define T_DOUBLE 4 +#define T_STRING 5 +#define T_OBJECT 6 +/* XXX the ordering here is weird for binary compatibility */ +#define T_CHAR 7 /* 1-character string */ +#define T_BYTE 8 /* 8-bit signed int */ +/* unsigned variants: */ +#define T_UBYTE 9 +#define T_USHORT 10 +#define T_UINT 11 +#define T_ULONG 12 + +/* Added by Jack: strings contained in the structure */ +#define T_STRING_INPLACE 13 + +/* Added by Lillo: bools contained in the structure (assumed char) */ +#define T_BOOL 14 + +#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError + when the value is NULL, instead of + converting to None. */ +#define T_LONGLONG 17 +#define T_ULONGLONG 18 + +#define T_PYSSIZET 19 /* Py_ssize_t */ +#define T_NONE 20 /* Value is always None */ + + +/* Flags */ +#define READONLY 1 +#define READ_RESTRICTED 2 +#define PY_WRITE_RESTRICTED 4 +#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED) + + +/* Current API, use this */ +PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *); +PyAPI_FUNC(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTMEMBER_H */ diff --git a/Include/structseq.h b/Include/structseq.h new file mode 100644 index 0000000..e5e5d5c --- /dev/null +++ b/Include/structseq.h @@ -0,0 +1,49 @@ + +/* Named tuple object interface */ + +#ifndef Py_STRUCTSEQ_H +#define Py_STRUCTSEQ_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PyStructSequence_Field { + const char *name; + const char *doc; +} PyStructSequence_Field; + +typedef struct PyStructSequence_Desc { + const char *name; + const char *doc; + struct PyStructSequence_Field *fields; + int n_in_sequence; +} PyStructSequence_Desc; + +extern char* PyStructSequence_UnnamedField; + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, + PyStructSequence_Desc *desc); +PyAPI_FUNC(int) PyStructSequence_InitType2(PyTypeObject *type, + PyStructSequence_Desc *desc); +#endif +PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc); + +PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); + +#ifndef Py_LIMITED_API +typedef PyTupleObject PyStructSequence; + +/* Macro, *only* to be used to fill in brand new objects */ +#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) + +#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) +#endif + +PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*); +PyAPI_FUNC(PyObject*) PyStructSequence_GetItem(PyObject*, Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTSEQ_H */ diff --git a/Include/symtable.h b/Include/symtable.h new file mode 100644 index 0000000..007f88d --- /dev/null +++ b/Include/symtable.h @@ -0,0 +1,118 @@ +#ifndef Py_LIMITED_API +#ifndef Py_SYMTABLE_H +#define Py_SYMTABLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* XXX(ncoghlan): This is a weird mix of public names and interpreter internal + * names. + */ + +typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock } + _Py_block_ty; + +struct _symtable_entry; + +struct symtable { + PyObject *st_filename; /* name of file being compiled, + decoded from the filesystem encoding */ + struct _symtable_entry *st_cur; /* current symbol table entry */ + struct _symtable_entry *st_top; /* symbol table entry for module */ + PyObject *st_blocks; /* dict: map AST node addresses + * to symbol table entries */ + PyObject *st_stack; /* list: stack of namespace info */ + PyObject *st_global; /* borrowed ref to st_top->ste_symbols */ + int st_nblocks; /* number of blocks used. kept for + consistency with the corresponding + compiler structure */ + PyObject *st_private; /* name of current class or NULL */ + PyFutureFeatures *st_future; /* module's future features that affect + the symbol table */ + int recursion_depth; /* current recursion depth */ + int recursion_limit; /* recursion limit */ +}; + +typedef struct _symtable_entry { + PyObject_HEAD + PyObject *ste_id; /* int: key in ste_table->st_blocks */ + PyObject *ste_symbols; /* dict: variable names to flags */ + PyObject *ste_name; /* string: name of current block */ + PyObject *ste_varnames; /* list of function parameters */ + PyObject *ste_children; /* list of child blocks */ + PyObject *ste_directives;/* locations of global and nonlocal statements */ + _Py_block_ty ste_type; /* module, class, or function */ + int ste_nested; /* true if block is nested */ + unsigned ste_free : 1; /* true if block has free variables */ + unsigned ste_child_free : 1; /* true if a child block has free vars, + including free refs to globals */ + unsigned ste_generator : 1; /* true if namespace is a generator */ + unsigned ste_coroutine : 1; /* true if namespace is a coroutine */ + unsigned ste_varargs : 1; /* true if block has varargs */ + unsigned ste_varkeywords : 1; /* true if block has varkeywords */ + unsigned ste_returns_value : 1; /* true if namespace uses return with + an argument */ + unsigned ste_needs_class_closure : 1; /* for class scopes, true if a + closure over __class__ + should be created */ + int ste_lineno; /* first line of block */ + int ste_col_offset; /* offset of first line of block */ + int ste_opt_lineno; /* lineno of last exec or import * */ + int ste_opt_col_offset; /* offset of last exec or import * */ + struct symtable *ste_table; +} PySTEntryObject; + +PyAPI_DATA(PyTypeObject) PySTEntry_Type; + +#define PySTEntry_Check(op) (Py_TYPE(op) == &PySTEntry_Type) + +PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *); + +PyAPI_FUNC(struct symtable *) PySymtable_Build( + mod_ty mod, + const char *filename, /* decoded from the filesystem encoding */ + PyFutureFeatures *future); +PyAPI_FUNC(struct symtable *) PySymtable_BuildObject( + mod_ty mod, + PyObject *filename, + PyFutureFeatures *future); +PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); + +PyAPI_FUNC(void) PySymtable_Free(struct symtable *); + +/* Flags for def-use information */ + +#define DEF_GLOBAL 1 /* global stmt */ +#define DEF_LOCAL 2 /* assignment in code block */ +#define DEF_PARAM 2<<1 /* formal parameter */ +#define DEF_NONLOCAL 2<<2 /* nonlocal stmt */ +#define USE 2<<3 /* name is used */ +#define DEF_FREE 2<<4 /* name used but not defined in nested block */ +#define DEF_FREE_CLASS 2<<5 /* free variable from class's method */ +#define DEF_IMPORT 2<<6 /* assignment occurred via import */ +#define DEF_ANNOT 2<<7 /* this name is annotated */ + +#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) + +/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol + table. GLOBAL is returned from PyST_GetScope() for either of them. + It is stored in ste_symbols at bits 12-15. +*/ +#define SCOPE_OFFSET 11 +#define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL) + +#define LOCAL 1 +#define GLOBAL_EXPLICIT 2 +#define GLOBAL_IMPLICIT 3 +#define FREE 4 +#define CELL 5 + +#define GENERATOR 1 +#define GENERATOR_EXPRESSION 2 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYMTABLE_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/sysmodule.h b/Include/sysmodule.h new file mode 100644 index 0000000..719ecfc --- /dev/null +++ b/Include/sysmodule.h @@ -0,0 +1,48 @@ + +/* System module interface */ + +#ifndef Py_SYSMODULE_H +#define Py_SYSMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); +PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); +PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); +#endif + +PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); +PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); +PyAPI_FUNC(void) PySys_SetPath(const wchar_t *); + +PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...); +PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...); + +PyAPI_FUNC(void) PySys_ResetWarnOptions(void); +PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *); +PyAPI_FUNC(void) PySys_AddWarnOptionUnicode(PyObject *); +PyAPI_FUNC(int) PySys_HasWarnOptions(void); + +PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *); +PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); +#endif + +#ifdef Py_BUILD_CORE +PyAPI_FUNC(int) _PySys_AddXOptionWithError(const wchar_t *s); +PyAPI_FUNC(int) _PySys_AddWarnOptionWithError(PyObject *option); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYSMODULE_H */ diff --git a/Include/token.h b/Include/token.h new file mode 100644 index 0000000..cd1cd00 --- /dev/null +++ b/Include/token.h @@ -0,0 +1,92 @@ + +/* Token types */ +#ifndef Py_LIMITED_API +#ifndef Py_TOKEN_H +#define Py_TOKEN_H +#ifdef __cplusplus +extern "C" { +#endif + +#undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ + +#define ENDMARKER 0 +#define NAME 1 +#define NUMBER 2 +#define STRING 3 +#define NEWLINE 4 +#define INDENT 5 +#define DEDENT 6 +#define LPAR 7 +#define RPAR 8 +#define LSQB 9 +#define RSQB 10 +#define COLON 11 +#define COMMA 12 +#define SEMI 13 +#define PLUS 14 +#define MINUS 15 +#define STAR 16 +#define SLASH 17 +#define VBAR 18 +#define AMPER 19 +#define LESS 20 +#define GREATER 21 +#define EQUAL 22 +#define DOT 23 +#define PERCENT 24 +#define LBRACE 25 +#define RBRACE 26 +#define EQEQUAL 27 +#define NOTEQUAL 28 +#define LESSEQUAL 29 +#define GREATEREQUAL 30 +#define TILDE 31 +#define CIRCUMFLEX 32 +#define LEFTSHIFT 33 +#define RIGHTSHIFT 34 +#define DOUBLESTAR 35 +#define PLUSEQUAL 36 +#define MINEQUAL 37 +#define STAREQUAL 38 +#define SLASHEQUAL 39 +#define PERCENTEQUAL 40 +#define AMPEREQUAL 41 +#define VBAREQUAL 42 +#define CIRCUMFLEXEQUAL 43 +#define LEFTSHIFTEQUAL 44 +#define RIGHTSHIFTEQUAL 45 +#define DOUBLESTAREQUAL 46 +#define DOUBLESLASH 47 +#define DOUBLESLASHEQUAL 48 +#define AT 49 +#define ATEQUAL 50 +#define RARROW 51 +#define ELLIPSIS 52 +/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ +#define OP 53 +#define ERRORTOKEN 54 +/* These aren't used by the C tokenizer but are needed for tokenize.py */ +#define COMMENT 55 +#define NL 56 +#define ENCODING 57 +#define N_TOKENS 58 + +/* Special definitions for cooperation with parser */ + +#define NT_OFFSET 256 + +#define ISTERMINAL(x) ((x) < NT_OFFSET) +#define ISNONTERMINAL(x) ((x) >= NT_OFFSET) +#define ISEOF(x) ((x) == ENDMARKER) + + +PyAPI_DATA(const char *) _PyParser_TokenNames[]; /* Token names */ +PyAPI_FUNC(int) PyToken_OneChar(int); +PyAPI_FUNC(int) PyToken_TwoChars(int, int); +PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TOKEN_H */ +#endif /* Py_LIMITED_API */ diff --git a/Include/traceback.h b/Include/traceback.h new file mode 100644 index 0000000..b587410 --- /dev/null +++ b/Include/traceback.h @@ -0,0 +1,119 @@ + +#ifndef Py_TRACEBACK_H +#define Py_TRACEBACK_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "pystate.h" + +struct _frame; + +/* Traceback interface */ +#ifndef Py_LIMITED_API +typedef struct _traceback { + PyObject_HEAD + struct _traceback *tb_next; + struct _frame *tb_frame; + int tb_lasti; + int tb_lineno; +} PyTracebackObject; +#endif + +PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); +PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); +PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); +#endif + +/* Reveal traceback type so we can typecheck traceback objects */ +PyAPI_DATA(PyTypeObject) PyTraceBack_Type; +#define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type) + +#ifndef Py_LIMITED_API +/* Write the Python traceback into the file 'fd'. For example: + + Traceback (most recent call first): + File "xxx", line xxx in + File "xxx", line xxx in + ... + File "xxx", line xxx in + + This function is written for debug purpose only, to dump the traceback in + the worst case: after a segmentation fault, at fatal error, etc. That's why, + it is very limited. Strings are truncated to 100 characters and encoded to + ASCII with backslashreplace. It doesn't write the source code, only the + function name, filename and line number of each frame. Write only the first + 100 frames: if the traceback is truncated, write the line " ...". + + This function is signal safe. */ + +PyAPI_FUNC(void) _Py_DumpTraceback( + int fd, + PyThreadState *tstate); + +/* Write the traceback of all threads into the file 'fd'. current_thread can be + NULL. + + Return NULL on success, or an error message on error. + + This function is written for debug purpose only. It calls + _Py_DumpTraceback() for each thread, and so has the same limitations. It + only write the traceback of the first 100 threads: write "..." if there are + more threads. + + If current_tstate is NULL, the function tries to get the Python thread state + of the current thread. It is not an error if the function is unable to get + the current Python thread state. + + If interp is NULL, the function tries to get the interpreter state from + the current Python thread state, or from + _PyGILState_GetInterpreterStateUnsafe() in last resort. + + It is better to pass NULL to interp and current_tstate, the function tries + different options to retrieve these informations. + + This function is signal safe. */ + +PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( + int fd, + PyInterpreterState *interp, + PyThreadState *current_tstate); +#endif /* !Py_LIMITED_API */ + +#ifndef Py_LIMITED_API + +/* Write a Unicode object into the file descriptor fd. Encode the string to + ASCII using the backslashreplace error handler. + + Do nothing if text is not a Unicode object. The function accepts Unicode + string which is not ready (PyUnicode_WCHAR_KIND). + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text); + +/* Format an integer as decimal into the file descriptor fd. + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpDecimal( + int fd, + unsigned long value); + +/* Format an integer as hexadecimal into the file descriptor fd with at least + width digits. + + The maximum width is sizeof(unsigned long)*2 digits. + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpHexadecimal( + int fd, + unsigned long value, + Py_ssize_t width); + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TRACEBACK_H */ diff --git a/Include/tupleobject.h b/Include/tupleobject.h new file mode 100644 index 0000000..72a7d8d --- /dev/null +++ b/Include/tupleobject.h @@ -0,0 +1,73 @@ + +/* Tuple object interface */ + +#ifndef Py_TUPLEOBJECT_H +#define Py_TUPLEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* +Another generally useful object type is a tuple of object pointers. +For Python, this is an immutable type. C code can change the tuple items +(but not their number), and even use tuples as general-purpose arrays of +object references, but in general only brand new tuples should be mutated, +not ones that might already have been exposed to Python code. + +*** WARNING *** PyTuple_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the tuple. Similarly, PyTuple_GetItem does not increment the +returned item's reference count. +*/ + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_VAR_HEAD + PyObject *ob_item[1]; + + /* ob_item contains space for 'ob_size' elements. + * Items must normally not be NULL, except during construction when + * the tuple is not yet visible outside the function that builds it. + */ +} PyTupleObject; +#endif + +PyAPI_DATA(PyTypeObject) PyTuple_Type; +PyAPI_DATA(PyTypeObject) PyTupleIter_Type; + +#define PyTuple_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) +#define PyTuple_CheckExact(op) (Py_TYPE(op) == &PyTuple_Type) + +PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); +#endif +PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); +#endif + +/* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API +#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i]) +#define PyTuple_GET_SIZE(op) (assert(PyTuple_Check(op)),Py_SIZE(op)) + +/* Macro, *only* to be used to fill in brand new tuples */ +#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v) +#endif + +PyAPI_FUNC(int) PyTuple_ClearFreeList(void); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ diff --git a/Include/typeslots.h b/Include/typeslots.h new file mode 100644 index 0000000..0ce6a37 --- /dev/null +++ b/Include/typeslots.h @@ -0,0 +1,85 @@ +/* Do not renumber the file; these numbers are part of the stable ABI. */ +/* Disabled, see #10181 */ +#undef Py_bf_getbuffer +#undef Py_bf_releasebuffer +#define Py_mp_ass_subscript 3 +#define Py_mp_length 4 +#define Py_mp_subscript 5 +#define Py_nb_absolute 6 +#define Py_nb_add 7 +#define Py_nb_and 8 +#define Py_nb_bool 9 +#define Py_nb_divmod 10 +#define Py_nb_float 11 +#define Py_nb_floor_divide 12 +#define Py_nb_index 13 +#define Py_nb_inplace_add 14 +#define Py_nb_inplace_and 15 +#define Py_nb_inplace_floor_divide 16 +#define Py_nb_inplace_lshift 17 +#define Py_nb_inplace_multiply 18 +#define Py_nb_inplace_or 19 +#define Py_nb_inplace_power 20 +#define Py_nb_inplace_remainder 21 +#define Py_nb_inplace_rshift 22 +#define Py_nb_inplace_subtract 23 +#define Py_nb_inplace_true_divide 24 +#define Py_nb_inplace_xor 25 +#define Py_nb_int 26 +#define Py_nb_invert 27 +#define Py_nb_lshift 28 +#define Py_nb_multiply 29 +#define Py_nb_negative 30 +#define Py_nb_or 31 +#define Py_nb_positive 32 +#define Py_nb_power 33 +#define Py_nb_remainder 34 +#define Py_nb_rshift 35 +#define Py_nb_subtract 36 +#define Py_nb_true_divide 37 +#define Py_nb_xor 38 +#define Py_sq_ass_item 39 +#define Py_sq_concat 40 +#define Py_sq_contains 41 +#define Py_sq_inplace_concat 42 +#define Py_sq_inplace_repeat 43 +#define Py_sq_item 44 +#define Py_sq_length 45 +#define Py_sq_repeat 46 +#define Py_tp_alloc 47 +#define Py_tp_base 48 +#define Py_tp_bases 49 +#define Py_tp_call 50 +#define Py_tp_clear 51 +#define Py_tp_dealloc 52 +#define Py_tp_del 53 +#define Py_tp_descr_get 54 +#define Py_tp_descr_set 55 +#define Py_tp_doc 56 +#define Py_tp_getattr 57 +#define Py_tp_getattro 58 +#define Py_tp_hash 59 +#define Py_tp_init 60 +#define Py_tp_is_gc 61 +#define Py_tp_iter 62 +#define Py_tp_iternext 63 +#define Py_tp_methods 64 +#define Py_tp_new 65 +#define Py_tp_repr 66 +#define Py_tp_richcompare 67 +#define Py_tp_setattr 68 +#define Py_tp_setattro 69 +#define Py_tp_str 70 +#define Py_tp_traverse 71 +#define Py_tp_members 72 +#define Py_tp_getset 73 +#define Py_tp_free 74 +#define Py_nb_matrix_multiply 75 +#define Py_nb_inplace_matrix_multiply 76 +#define Py_am_await 77 +#define Py_am_aiter 78 +#define Py_am_anext 79 +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +#define Py_tp_finalize 80 +#endif diff --git a/Include/ucnhash.h b/Include/ucnhash.h new file mode 100644 index 0000000..45362e9 --- /dev/null +++ b/Include/ucnhash.h @@ -0,0 +1,36 @@ +/* Unicode name database interface */ +#ifndef Py_LIMITED_API +#ifndef Py_UCNHASH_H +#define Py_UCNHASH_H +#ifdef __cplusplus +extern "C" { +#endif + +/* revised ucnhash CAPI interface (exported through a "wrapper") */ + +#define PyUnicodeData_CAPSULE_NAME "unicodedata.ucnhash_CAPI" + +typedef struct { + + /* Size of this struct */ + int size; + + /* Get name for a given character code. Returns non-zero if + success, zero if not. Does not set Python exceptions. + If self is NULL, data come from the default version of the database. + If it is not NULL, it should be a unicodedata.ucd_X_Y_Z object */ + int (*getname)(PyObject *self, Py_UCS4 code, char* buffer, int buflen, + int with_alias_and_seq); + + /* Get character code for a given name. Same error handling + as for getname. */ + int (*getcode)(PyObject *self, const char* name, int namelen, Py_UCS4* code, + int with_named_seq); + +} _PyUnicode_Name_CAPI; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_UCNHASH_H */ +#endif /* !Py_LIMITED_API */ diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h new file mode 100644 index 0000000..0274de6 --- /dev/null +++ b/Include/unicodeobject.h @@ -0,0 +1,2334 @@ +#ifndef Py_UNICODEOBJECT_H +#define Py_UNICODEOBJECT_H + +#include + +/* + +Unicode implementation based on original code by Fredrik Lundh, +modified by Marc-Andre Lemburg (mal@lemburg.com) according to the +Unicode Integration Proposal. (See +http://www.egenix.com/files/python/unicode-proposal.txt). + +Copyright (c) Corporation for National Research Initiatives. + + + Original header: + -------------------------------------------------------------------- + + * Yet another Unicode string type for Python. This type supports the + * 16-bit Basic Multilingual Plane (BMP) only. + * + * Written by Fredrik Lundh, January 1999. + * + * Copyright (c) 1999 by Secret Labs AB. + * Copyright (c) 1999 by Fredrik Lundh. + * + * fredrik@pythonware.com + * http://www.pythonware.com + * + * -------------------------------------------------------------------- + * This Unicode String Type is + * + * Copyright (c) 1999 by Secret Labs AB + * Copyright (c) 1999 by Fredrik Lundh + * + * By obtaining, using, and/or copying this software and/or its + * associated documentation, you agree that you have read, understood, + * and will comply with the following terms and conditions: + * + * Permission to use, copy, modify, and distribute this software and its + * associated documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appears in all + * copies, and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of Secret Labs + * AB or the author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. + * + * SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * -------------------------------------------------------------------- */ + +#include + +/* === Internal API ======================================================= */ + +/* --- Internal Unicode Format -------------------------------------------- */ + +/* Python 3.x requires unicode */ +#define Py_USING_UNICODE + +#ifndef SIZEOF_WCHAR_T +#error Must define SIZEOF_WCHAR_T +#endif + +#define Py_UNICODE_SIZE SIZEOF_WCHAR_T + +/* If wchar_t can be used for UCS-4 storage, set Py_UNICODE_WIDE. + Otherwise, Unicode strings are stored as UCS-2 (with limited support + for UTF-16) */ + +#if Py_UNICODE_SIZE >= 4 +#define Py_UNICODE_WIDE +#endif + +/* Set these flags if the platform has "wchar.h" and the + wchar_t type is a 16-bit unsigned type */ +/* #define HAVE_WCHAR_H */ +/* #define HAVE_USABLE_WCHAR_T */ + +/* Py_UNICODE was the native Unicode storage format (code unit) used by + Python and represents a single Unicode element in the Unicode type. + With PEP 393, Py_UNICODE is deprecated and replaced with a + typedef to wchar_t. */ + +#ifndef Py_LIMITED_API +#define PY_UNICODE_TYPE wchar_t +typedef wchar_t Py_UNICODE /* Py_DEPRECATED(3.3) */; +#endif + +/* If the compiler provides a wchar_t type we try to support it + through the interface functions PyUnicode_FromWideChar(), + PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(). */ + +#ifdef HAVE_USABLE_WCHAR_T +# ifndef HAVE_WCHAR_H +# define HAVE_WCHAR_H +# endif +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +/* Py_UCS4 and Py_UCS2 are typedefs for the respective + unicode representations. */ +typedef uint32_t Py_UCS4; +typedef uint16_t Py_UCS2; +typedef uint8_t Py_UCS1; + +/* --- Internal Unicode Operations ---------------------------------------- */ + +/* Since splitting on whitespace is an important use case, and + whitespace in most situations is solely ASCII whitespace, we + optimize for the common case by using a quick look-up table + _Py_ascii_whitespace (see below) with an inlined check. + + */ +#ifndef Py_LIMITED_API +#define Py_UNICODE_ISSPACE(ch) \ + ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) +#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +#define Py_UNICODE_ISALNUM(ch) \ + (Py_UNICODE_ISALPHA(ch) || \ + Py_UNICODE_ISDECIMAL(ch) || \ + Py_UNICODE_ISDIGIT(ch) || \ + Py_UNICODE_ISNUMERIC(ch)) + +#define Py_UNICODE_COPY(target, source, length) \ + memcpy((target), (source), (length)*sizeof(Py_UNICODE)) + +#define Py_UNICODE_FILL(target, value, length) \ + do {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\ + for (i_ = 0; i_ < (length); i_++) t_[i_] = v_;\ + } while (0) + +/* macros to work with surrogates */ +#define Py_UNICODE_IS_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDFFF) +#define Py_UNICODE_IS_HIGH_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDBFF) +#define Py_UNICODE_IS_LOW_SURROGATE(ch) (0xDC00 <= (ch) && (ch) <= 0xDFFF) +/* Join two surrogate characters and return a single Py_UCS4 value. */ +#define Py_UNICODE_JOIN_SURROGATES(high, low) \ + (((((Py_UCS4)(high) & 0x03FF) << 10) | \ + ((Py_UCS4)(low) & 0x03FF)) + 0x10000) +/* high surrogate = top 10 bits added to D800 */ +#define Py_UNICODE_HIGH_SURROGATE(ch) (0xD800 - (0x10000 >> 10) + ((ch) >> 10)) +/* low surrogate = bottom 10 bits added to DC00 */ +#define Py_UNICODE_LOW_SURROGATE(ch) (0xDC00 + ((ch) & 0x3FF)) + +/* Check if substring matches at given offset. The offset must be + valid, and the substring must not be empty. */ + +#define Py_UNICODE_MATCH(string, offset, substring) \ + ((*((string)->wstr + (offset)) == *((substring)->wstr)) && \ + ((*((string)->wstr + (offset) + (substring)->wstr_length-1) == *((substring)->wstr + (substring)->wstr_length-1))) && \ + !memcmp((string)->wstr + (offset), (substring)->wstr, (substring)->wstr_length*sizeof(Py_UNICODE))) + +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Unicode Type ------------------------------------------------------- */ + +#ifndef Py_LIMITED_API + +/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject + structure. state.ascii and state.compact are set, and the data + immediately follow the structure. utf8_length and wstr_length can be found + in the length field; the utf8 pointer is equal to the data pointer. */ +typedef struct { + /* There are 4 forms of Unicode strings: + + - compact ascii: + + * structure = PyASCIIObject + * test: PyUnicode_IS_COMPACT_ASCII(op) + * kind = PyUnicode_1BYTE_KIND + * compact = 1 + * ascii = 1 + * ready = 1 + * (length is the length of the utf8 and wstr strings) + * (data starts just after the structure) + * (since ASCII is decoded from UTF-8, the utf8 string are the data) + + - compact: + + * structure = PyCompactUnicodeObject + * test: PyUnicode_IS_COMPACT(op) && !PyUnicode_IS_ASCII(op) + * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or + PyUnicode_4BYTE_KIND + * compact = 1 + * ready = 1 + * ascii = 0 + * utf8 is not shared with data + * utf8_length = 0 if utf8 is NULL + * wstr is shared with data and wstr_length=length + if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 + or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_t)=4 + * wstr_length = 0 if wstr is NULL + * (data starts just after the structure) + + - legacy string, not ready: + + * structure = PyUnicodeObject + * test: kind == PyUnicode_WCHAR_KIND + * length = 0 (use wstr_length) + * hash = -1 + * kind = PyUnicode_WCHAR_KIND + * compact = 0 + * ascii = 0 + * ready = 0 + * interned = SSTATE_NOT_INTERNED + * wstr is not NULL + * data.any is NULL + * utf8 is NULL + * utf8_length = 0 + + - legacy string, ready: + + * structure = PyUnicodeObject structure + * test: !PyUnicode_IS_COMPACT(op) && kind != PyUnicode_WCHAR_KIND + * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or + PyUnicode_4BYTE_KIND + * compact = 0 + * ready = 1 + * data.any is not NULL + * utf8 is shared and utf8_length = length with data.any if ascii = 1 + * utf8_length = 0 if utf8 is NULL + * wstr is shared with data.any and wstr_length = length + if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 + or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_4)=4 + * wstr_length = 0 if wstr is NULL + + Compact strings use only one memory block (structure + characters), + whereas legacy strings use one block for the structure and one block + for characters. + + Legacy strings are created by PyUnicode_FromUnicode() and + PyUnicode_FromStringAndSize(NULL, size) functions. They become ready + when PyUnicode_READY() is called. + + See also _PyUnicode_CheckConsistency(). + */ + PyObject_HEAD + Py_ssize_t length; /* Number of code points in the string */ + Py_hash_t hash; /* Hash value; -1 if not set */ + struct { + /* + SSTATE_NOT_INTERNED (0) + SSTATE_INTERNED_MORTAL (1) + SSTATE_INTERNED_IMMORTAL (2) + + If interned != SSTATE_NOT_INTERNED, the two references from the + dictionary to this object are *not* counted in ob_refcnt. + */ + unsigned int interned:2; + /* Character size: + + - PyUnicode_WCHAR_KIND (0): + + * character type = wchar_t (16 or 32 bits, depending on the + platform) + + - PyUnicode_1BYTE_KIND (1): + + * character type = Py_UCS1 (8 bits, unsigned) + * all characters are in the range U+0000-U+00FF (latin1) + * if ascii is set, all characters are in the range U+0000-U+007F + (ASCII), otherwise at least one character is in the range + U+0080-U+00FF + + - PyUnicode_2BYTE_KIND (2): + + * character type = Py_UCS2 (16 bits, unsigned) + * all characters are in the range U+0000-U+FFFF (BMP) + * at least one character is in the range U+0100-U+FFFF + + - PyUnicode_4BYTE_KIND (4): + + * character type = Py_UCS4 (32 bits, unsigned) + * all characters are in the range U+0000-U+10FFFF + * at least one character is in the range U+10000-U+10FFFF + */ + unsigned int kind:3; + /* Compact is with respect to the allocation scheme. Compact unicode + objects only require one memory block while non-compact objects use + one block for the PyUnicodeObject struct and another for its data + buffer. */ + unsigned int compact:1; + /* The string only contains characters in the range U+0000-U+007F (ASCII) + and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is + set, use the PyASCIIObject structure. */ + unsigned int ascii:1; + /* The ready flag indicates whether the object layout is initialized + completely. This means that this is either a compact object, or + the data pointer is filled out. The bit is redundant, and helps + to minimize the test in PyUnicode_IS_READY(). */ + unsigned int ready:1; + /* Padding to ensure that PyUnicode_DATA() is always aligned to + 4 bytes (see issue #19537 on m68k). */ + unsigned int :24; + } state; + wchar_t *wstr; /* wchar_t representation (null-terminated) */ +} PyASCIIObject; + +/* Non-ASCII strings allocated through PyUnicode_New use the + PyCompactUnicodeObject structure. state.compact is set, and the data + immediately follow the structure. */ +typedef struct { + PyASCIIObject _base; + Py_ssize_t utf8_length; /* Number of bytes in utf8, excluding the + * terminating \0. */ + char *utf8; /* UTF-8 representation (null-terminated) */ + Py_ssize_t wstr_length; /* Number of code points in wstr, possible + * surrogates count as two code points. */ +} PyCompactUnicodeObject; + +/* Strings allocated through PyUnicode_FromUnicode(NULL, len) use the + PyUnicodeObject structure. The actual string data is initially in the wstr + block, and copied into the data block using _PyUnicode_Ready. */ +typedef struct { + PyCompactUnicodeObject _base; + union { + void *any; + Py_UCS1 *latin1; + Py_UCS2 *ucs2; + Py_UCS4 *ucs4; + } data; /* Canonical, smallest-form Unicode buffer */ +} PyUnicodeObject; +#endif + +PyAPI_DATA(PyTypeObject) PyUnicode_Type; +PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; + +#define PyUnicode_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) +#define PyUnicode_CheckExact(op) (Py_TYPE(op) == &PyUnicode_Type) + +/* Fast access macros */ +#ifndef Py_LIMITED_API + +#define PyUnicode_WSTR_LENGTH(op) \ + (PyUnicode_IS_COMPACT_ASCII(op) ? \ + ((PyASCIIObject*)op)->length : \ + ((PyCompactUnicodeObject*)op)->wstr_length) + +/* Returns the deprecated Py_UNICODE representation's size in code units + (this includes surrogate pairs as 2 units). + If the Py_UNICODE representation is not available, it will be computed + on request. Use PyUnicode_GET_LENGTH() for the length in code points. */ + +#define PyUnicode_GET_SIZE(op) \ + (assert(PyUnicode_Check(op)), \ + (((PyASCIIObject *)(op))->wstr) ? \ + PyUnicode_WSTR_LENGTH(op) : \ + ((void)PyUnicode_AsUnicode((PyObject *)(op)), \ + assert(((PyASCIIObject *)(op))->wstr), \ + PyUnicode_WSTR_LENGTH(op))) + /* Py_DEPRECATED(3.3) */ + +#define PyUnicode_GET_DATA_SIZE(op) \ + (PyUnicode_GET_SIZE(op) * Py_UNICODE_SIZE) + /* Py_DEPRECATED(3.3) */ + +/* Alias for PyUnicode_AsUnicode(). This will create a wchar_t/Py_UNICODE + representation on demand. Using this macro is very inefficient now, + try to port your code to use the new PyUnicode_*BYTE_DATA() macros or + use PyUnicode_WRITE() and PyUnicode_READ(). */ + +#define PyUnicode_AS_UNICODE(op) \ + (assert(PyUnicode_Check(op)), \ + (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ + PyUnicode_AsUnicode((PyObject *)(op))) + /* Py_DEPRECATED(3.3) */ + +#define PyUnicode_AS_DATA(op) \ + ((const char *)(PyUnicode_AS_UNICODE(op))) + /* Py_DEPRECATED(3.3) */ + + +/* --- Flexible String Representation Helper Macros (PEP 393) -------------- */ + +/* Values for PyASCIIObject.state: */ + +/* Interning state. */ +#define SSTATE_NOT_INTERNED 0 +#define SSTATE_INTERNED_MORTAL 1 +#define SSTATE_INTERNED_IMMORTAL 2 + +/* Return true if the string contains only ASCII characters, or 0 if not. The + string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be + ready. */ +#define PyUnicode_IS_ASCII(op) \ + (assert(PyUnicode_Check(op)), \ + assert(PyUnicode_IS_READY(op)), \ + ((PyASCIIObject*)op)->state.ascii) + +/* Return true if the string is compact or 0 if not. + No type checks or Ready calls are performed. */ +#define PyUnicode_IS_COMPACT(op) \ + (((PyASCIIObject*)(op))->state.compact) + +/* Return true if the string is a compact ASCII string (use PyASCIIObject + structure), or 0 if not. No type checks or Ready calls are performed. */ +#define PyUnicode_IS_COMPACT_ASCII(op) \ + (((PyASCIIObject*)op)->state.ascii && PyUnicode_IS_COMPACT(op)) + +enum PyUnicode_Kind { +/* String contains only wstr byte characters. This is only possible + when the string was created with a legacy API and _PyUnicode_Ready() + has not been called yet. */ + PyUnicode_WCHAR_KIND = 0, +/* Return values of the PyUnicode_KIND() macro: */ + PyUnicode_1BYTE_KIND = 1, + PyUnicode_2BYTE_KIND = 2, + PyUnicode_4BYTE_KIND = 4 +}; + +/* Return pointers to the canonical representation cast to unsigned char, + Py_UCS2, or Py_UCS4 for direct character access. + No checks are performed, use PyUnicode_KIND() before to ensure + these will work correctly. */ + +#define PyUnicode_1BYTE_DATA(op) ((Py_UCS1*)PyUnicode_DATA(op)) +#define PyUnicode_2BYTE_DATA(op) ((Py_UCS2*)PyUnicode_DATA(op)) +#define PyUnicode_4BYTE_DATA(op) ((Py_UCS4*)PyUnicode_DATA(op)) + +/* Return one of the PyUnicode_*_KIND values defined above. */ +#define PyUnicode_KIND(op) \ + (assert(PyUnicode_Check(op)), \ + assert(PyUnicode_IS_READY(op)), \ + ((PyASCIIObject *)(op))->state.kind) + +/* Return a void pointer to the raw unicode buffer. */ +#define _PyUnicode_COMPACT_DATA(op) \ + (PyUnicode_IS_ASCII(op) ? \ + ((void*)((PyASCIIObject*)(op) + 1)) : \ + ((void*)((PyCompactUnicodeObject*)(op) + 1))) + +#define _PyUnicode_NONCOMPACT_DATA(op) \ + (assert(((PyUnicodeObject*)(op))->data.any), \ + ((((PyUnicodeObject *)(op))->data.any))) + +#define PyUnicode_DATA(op) \ + (assert(PyUnicode_Check(op)), \ + PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \ + _PyUnicode_NONCOMPACT_DATA(op)) + +/* In the access macros below, "kind" may be evaluated more than once. + All other macro parameters are evaluated exactly once, so it is safe + to put side effects into them (such as increasing the index). */ + +/* Write into the canonical representation, this macro does not do any sanity + checks and is intended for usage in loops. The caller should cache the + kind and data pointers obtained from other macro calls. + index is the index in the string (starts at 0) and value is the new + code point value which should be written to that location. */ +#define PyUnicode_WRITE(kind, data, index, value) \ + do { \ + switch ((kind)) { \ + case PyUnicode_1BYTE_KIND: { \ + ((Py_UCS1 *)(data))[(index)] = (Py_UCS1)(value); \ + break; \ + } \ + case PyUnicode_2BYTE_KIND: { \ + ((Py_UCS2 *)(data))[(index)] = (Py_UCS2)(value); \ + break; \ + } \ + default: { \ + assert((kind) == PyUnicode_4BYTE_KIND); \ + ((Py_UCS4 *)(data))[(index)] = (Py_UCS4)(value); \ + } \ + } \ + } while (0) + +/* Read a code point from the string's canonical representation. No checks + or ready calls are performed. */ +#define PyUnicode_READ(kind, data, index) \ + ((Py_UCS4) \ + ((kind) == PyUnicode_1BYTE_KIND ? \ + ((const Py_UCS1 *)(data))[(index)] : \ + ((kind) == PyUnicode_2BYTE_KIND ? \ + ((const Py_UCS2 *)(data))[(index)] : \ + ((const Py_UCS4 *)(data))[(index)] \ + ) \ + )) + +/* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it + calls PyUnicode_KIND() and might call it twice. For single reads, use + PyUnicode_READ_CHAR, for multiple consecutive reads callers should + cache kind and use PyUnicode_READ instead. */ +#define PyUnicode_READ_CHAR(unicode, index) \ + (assert(PyUnicode_Check(unicode)), \ + assert(PyUnicode_IS_READY(unicode)), \ + (Py_UCS4) \ + (PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \ + ((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \ + (PyUnicode_KIND((unicode)) == PyUnicode_2BYTE_KIND ? \ + ((const Py_UCS2 *)(PyUnicode_DATA((unicode))))[(index)] : \ + ((const Py_UCS4 *)(PyUnicode_DATA((unicode))))[(index)] \ + ) \ + )) + +/* Returns the length of the unicode string. The caller has to make sure that + the string has it's canonical representation set before calling + this macro. Call PyUnicode_(FAST_)Ready to ensure that. */ +#define PyUnicode_GET_LENGTH(op) \ + (assert(PyUnicode_Check(op)), \ + assert(PyUnicode_IS_READY(op)), \ + ((PyASCIIObject *)(op))->length) + + +/* Fast check to determine whether an object is ready. Equivalent to + PyUnicode_IS_COMPACT(op) || ((PyUnicodeObject*)(op))->data.any) */ + +#define PyUnicode_IS_READY(op) (((PyASCIIObject*)op)->state.ready) + +/* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best + case. If the canonical representation is not yet set, it will still call + _PyUnicode_Ready(). + Returns 0 on success and -1 on errors. */ +#define PyUnicode_READY(op) \ + (assert(PyUnicode_Check(op)), \ + (PyUnicode_IS_READY(op) ? \ + 0 : _PyUnicode_Ready((PyObject *)(op)))) + +/* Return a maximum character value which is suitable for creating another + string based on op. This is always an approximation but more efficient + than iterating over the string. */ +#define PyUnicode_MAX_CHAR_VALUE(op) \ + (assert(PyUnicode_IS_READY(op)), \ + (PyUnicode_IS_ASCII(op) ? \ + (0x7f) : \ + (PyUnicode_KIND(op) == PyUnicode_1BYTE_KIND ? \ + (0xffU) : \ + (PyUnicode_KIND(op) == PyUnicode_2BYTE_KIND ? \ + (0xffffU) : \ + (0x10ffffU))))) + +#endif + +/* --- Constants ---------------------------------------------------------- */ + +/* This Unicode character will be used as replacement character during + decoding if the errors argument is set to "replace". Note: the + Unicode character U+FFFD is the official REPLACEMENT CHARACTER in + Unicode 3.0. */ + +#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UCS4) 0xFFFD) + +/* === Public API ========================================================= */ + +/* --- Plain Py_UNICODE --------------------------------------------------- */ + +/* With PEP 393, this is the recommended way to allocate a new unicode object. + This function will allocate the object and its buffer in a single memory + block. Objects created using this function are not resizable. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_New( + Py_ssize_t size, /* Number of code points in the new string */ + Py_UCS4 maxchar /* maximum code point value in the string */ + ); +#endif + +/* Initializes the canonical string representation from the deprecated + wstr/Py_UNICODE representation. This function is used to convert Unicode + objects which were created using the old API to the new flexible format + introduced with PEP 393. + + Don't call this function directly, use the public PyUnicode_READY() macro + instead. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyUnicode_Ready( + PyObject *unicode /* Unicode object */ + ); +#endif + +/* Get a copy of a Unicode string. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) _PyUnicode_Copy( + PyObject *unicode + ); +#endif + +/* Copy character from one unicode object into another, this function performs + character conversion when necessary and falls back to memcpy() if possible. + + Fail if to is too small (smaller than *how_many* or smaller than + len(from)-from_start), or if kind(from[from_start:from_start+how_many]) > + kind(to), or if *to* has more than 1 reference. + + Return the number of written character, or return -1 and raise an exception + on error. + + Pseudo-code: + + how_many = min(how_many, len(from) - from_start) + to[to_start:to_start+how_many] = from[from_start:from_start+how_many] + return how_many + + Note: The function doesn't write a terminating null character. + */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) PyUnicode_CopyCharacters( + PyObject *to, + Py_ssize_t to_start, + PyObject *from, + Py_ssize_t from_start, + Py_ssize_t how_many + ); + +/* Unsafe version of PyUnicode_CopyCharacters(): don't check arguments and so + may crash if parameters are invalid (e.g. if the output string + is too short). */ +PyAPI_FUNC(void) _PyUnicode_FastCopyCharacters( + PyObject *to, + Py_ssize_t to_start, + PyObject *from, + Py_ssize_t from_start, + Py_ssize_t how_many + ); +#endif + +#ifndef Py_LIMITED_API +/* Fill a string with a character: write fill_char into + unicode[start:start+length]. + + Fail if fill_char is bigger than the string maximum character, or if the + string has more than 1 reference. + + Return the number of written character, or return -1 and raise an exception + on error. */ +PyAPI_FUNC(Py_ssize_t) PyUnicode_Fill( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t length, + Py_UCS4 fill_char + ); + +/* Unsafe version of PyUnicode_Fill(): don't check arguments and so may crash + if parameters are invalid (e.g. if length is longer than the string). */ +PyAPI_FUNC(void) _PyUnicode_FastFill( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t length, + Py_UCS4 fill_char + ); +#endif + +/* Create a Unicode Object from the Py_UNICODE buffer u of the given + size. + + u may be NULL which causes the contents to be undefined. It is the + user's responsibility to fill in the needed data afterwards. Note + that modifying the Unicode object contents after construction is + only allowed if u was set to NULL. + + The buffer is copied into the new object. */ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( + const Py_UNICODE *u, /* Unicode buffer */ + Py_ssize_t size /* size of buffer */ + ) /* Py_DEPRECATED(3.3) */; +#endif + +/* Similar to PyUnicode_FromUnicode(), but u points to UTF-8 encoded bytes */ +PyAPI_FUNC(PyObject*) PyUnicode_FromStringAndSize( + const char *u, /* UTF-8 encoded string */ + Py_ssize_t size /* size of buffer */ + ); + +/* Similar to PyUnicode_FromUnicode(), but u points to null-terminated + UTF-8 encoded bytes. The size is determined with strlen(). */ +PyAPI_FUNC(PyObject*) PyUnicode_FromString( + const char *u /* UTF-8 encoded string */ + ); + +#ifndef Py_LIMITED_API +/* Create a new string from a buffer of Py_UCS1, Py_UCS2 or Py_UCS4 characters. + Scan the string to find the maximum character. */ +PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData( + int kind, + const void *buffer, + Py_ssize_t size); + +/* Create a new string from a buffer of ASCII characters. + WARNING: Don't check if the string contains any non-ASCII character. */ +PyAPI_FUNC(PyObject*) _PyUnicode_FromASCII( + const char *buffer, + Py_ssize_t size); +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyUnicode_Substring( + PyObject *str, + Py_ssize_t start, + Py_ssize_t end); +#endif + +#ifndef Py_LIMITED_API +/* Compute the maximum character of the substring unicode[start:end]. + Return 127 for an empty string. */ +PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t end); +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Copy the string into a UCS4 buffer including the null character if copy_null + is set. Return NULL and raise an exception on error. Raise a SystemError if + the buffer is smaller than the string. Return buffer on success. + + buflen is the length of the buffer in (Py_UCS4) characters. */ +PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4( + PyObject *unicode, + Py_UCS4* buffer, + Py_ssize_t buflen, + int copy_null); + +/* Copy the string into a UCS4 buffer. A new buffer is allocated using + * PyMem_Malloc; if this fails, NULL is returned with a memory error + exception set. */ +PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4Copy(PyObject *unicode); +#endif + +#ifndef Py_LIMITED_API +/* Return a read-only pointer to the Unicode object's internal + Py_UNICODE buffer. + If the wchar_t/Py_UNICODE representation is not yet available, this + function will calculate it. */ + +PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( + PyObject *unicode /* Unicode object */ + ) /* Py_DEPRECATED(3.3) */; + +/* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string + contains null characters. */ +PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( + PyObject *unicode /* Unicode object */ + ); + +/* Return a read-only pointer to the Unicode object's internal + Py_UNICODE buffer and save the length at size. + If the wchar_t/Py_UNICODE representation is not yet available, this + function will calculate it. */ + +PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( + PyObject *unicode, /* Unicode object */ + Py_ssize_t *size /* location where to save the length */ + ) /* Py_DEPRECATED(3.3) */; +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Get the length of the Unicode object. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetLength( + PyObject *unicode +); +#endif + +/* Get the number of Py_UNICODE units in the + string representation. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( + PyObject *unicode /* Unicode object */ + ) Py_DEPRECATED(3.3); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Read a character from the string. */ + +PyAPI_FUNC(Py_UCS4) PyUnicode_ReadChar( + PyObject *unicode, + Py_ssize_t index + ); + +/* Write a character to the string. The string must have been created through + PyUnicode_New, must not be shared, and must not have been hashed yet. + + Return 0 on success, -1 on error. */ + +PyAPI_FUNC(int) PyUnicode_WriteChar( + PyObject *unicode, + Py_ssize_t index, + Py_UCS4 character + ); +#endif + +#ifndef Py_LIMITED_API +/* Get the maximum ordinal for a Unicode character. */ +PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void) Py_DEPRECATED(3.3); +#endif + +/* Resize a Unicode object. The length is the number of characters, except + if the kind of the string is PyUnicode_WCHAR_KIND: in this case, the length + is the number of Py_UNICODE characters. + + *unicode is modified to point to the new (resized) object and 0 + returned on success. + + Try to resize the string in place (which is usually faster than allocating + a new string and copy characters), or create a new string. + + Error handling is implemented as follows: an exception is set, -1 + is returned and *unicode left untouched. + + WARNING: The function doesn't check string content, the result may not be a + string in canonical representation. */ + +PyAPI_FUNC(int) PyUnicode_Resize( + PyObject **unicode, /* Pointer to the Unicode object */ + Py_ssize_t length /* New length */ + ); + +/* Decode obj to a Unicode object. + + bytes, bytearray and other bytes-like objects are decoded according to the + given encoding and error handler. The encoding and error handler can be + NULL to have the interface use UTF-8 and "strict". + + All other objects (including Unicode objects) raise an exception. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromEncodedObject( + PyObject *obj, /* Object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Copy an instance of a Unicode subtype to a new true Unicode object if + necessary. If obj is already a true Unicode object (not a subtype), return + the reference with *incremented* refcount. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromObject( + PyObject *obj /* Object */ + ); + +PyAPI_FUNC(PyObject *) PyUnicode_FromFormatV( + const char *format, /* ASCII-encoded string */ + va_list vargs + ); +PyAPI_FUNC(PyObject *) PyUnicode_FromFormat( + const char *format, /* ASCII-encoded string */ + ... + ); + +#ifndef Py_LIMITED_API +typedef struct { + PyObject *buffer; + void *data; + enum PyUnicode_Kind kind; + Py_UCS4 maxchar; + Py_ssize_t size; + Py_ssize_t pos; + + /* minimum number of allocated characters (default: 0) */ + Py_ssize_t min_length; + + /* minimum character (default: 127, ASCII) */ + Py_UCS4 min_char; + + /* If non-zero, overallocate the buffer (default: 0). */ + unsigned char overallocate; + + /* If readonly is 1, buffer is a shared string (cannot be modified) + and size is set to 0. */ + unsigned char readonly; +} _PyUnicodeWriter ; + +/* Initialize a Unicode writer. + * + * By default, the minimum buffer size is 0 character and overallocation is + * disabled. Set min_length, min_char and overallocate attributes to control + * the allocation of the buffer. */ +PyAPI_FUNC(void) +_PyUnicodeWriter_Init(_PyUnicodeWriter *writer); + +/* Prepare the buffer to write 'length' characters + with the specified maximum character. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \ + (((MAXCHAR) <= (WRITER)->maxchar \ + && (LENGTH) <= (WRITER)->size - (WRITER)->pos) \ + ? 0 \ + : (((LENGTH) == 0) \ + ? 0 \ + : _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR)))) + +/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro + instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, + Py_ssize_t length, Py_UCS4 maxchar); + +/* Prepare the buffer to have at least the kind KIND. + For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will + support characters in range U+000-U+FFFF. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ + (assert((KIND) != PyUnicode_WCHAR_KIND), \ + (KIND) <= (WRITER)->kind \ + ? 0 \ + : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) + +/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind() + macro instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, + enum PyUnicode_Kind kind); + +/* Append a Unicode character. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, + Py_UCS4 ch + ); + +/* Append a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, + PyObject *str /* Unicode string */ + ); + +/* Append a substring of a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, + PyObject *str, /* Unicode string */ + Py_ssize_t start, + Py_ssize_t end + ); + +/* Append an ASCII-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, + const char *str, /* ASCII-encoded byte string */ + Py_ssize_t len /* number of bytes, or -1 if unknown */ + ); + +/* Append a latin1-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, + const char *str, /* latin1-encoded byte string */ + Py_ssize_t len /* length in bytes */ + ); + +/* Get the value of the writer as a Unicode string. Clear the + buffer of the writer. Raise an exception and return NULL + on error. */ +PyAPI_FUNC(PyObject *) +_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) +_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer); +#endif + +#ifndef Py_LIMITED_API +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(int) _PyUnicode_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif + +PyAPI_FUNC(void) PyUnicode_InternInPlace(PyObject **); +PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); +PyAPI_FUNC(PyObject *) PyUnicode_InternFromString( + const char *u /* UTF-8 encoded string */ + ); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_ReleaseInternedUnicodeStrings(void); +#endif + +/* Use only if you know it's a string */ +#define PyUnicode_CHECK_INTERNED(op) \ + (((PyASCIIObject *)(op))->state.interned) + +/* --- wchar_t support for platforms which support it --------------------- */ + +#ifdef HAVE_WCHAR_H + +/* Create a Unicode Object from the wchar_t buffer w of the given + size. + + The buffer is copied into the new object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_FromWideChar( + const wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Copies the Unicode Object contents into the wchar_t buffer w. At + most size wchar_t characters are copied. + + Note that the resulting wchar_t string may or may not be + 0-terminated. It is the responsibility of the caller to make sure + that the wchar_t string is 0-terminated in case this is required by + the application. + + Returns the number of wchar_t characters copied (excluding a + possibly trailing 0-termination character) or -1 in case of an + error. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( + PyObject *unicode, /* Unicode object */ + wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Convert the Unicode object to a wide character string. The output string + always ends with a nul character. If size is not NULL, write the number of + wide characters (excluding the null character) into *size. + + Returns a buffer allocated by PyMem_Malloc() (use PyMem_Free() to free it) + on success. On error, returns NULL, *size is undefined and raises a + MemoryError. */ + +PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString( + PyObject *unicode, /* Unicode object */ + Py_ssize_t *size /* number of characters of the result */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void*) _PyUnicode_AsKind(PyObject *s, unsigned int kind); +#endif + +#endif + +/* --- Unicode ordinals --------------------------------------------------- */ + +/* Create a Unicode Object from the given Unicode code point ordinal. + + The ordinal must be in range(0x110000). A ValueError is + raised in case it is not. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal); + +/* --- Free-list management ----------------------------------------------- */ + +/* Clear the free list used by the Unicode implementation. + + This can be used to release memory used for objects on the free + list back to the Python memory allocator. + +*/ + +PyAPI_FUNC(int) PyUnicode_ClearFreeList(void); + +/* === Builtin Codecs ===================================================== + + Many of these APIs take two arguments encoding and errors. These + parameters encoding and errors have the same semantics as the ones + of the builtin str() API. + + Setting encoding to NULL causes the default encoding (UTF-8) to be used. + + Error handling is set by errors which may also be set to NULL + meaning to use the default handling defined for the codec. Default + error handling for all builtin codecs is "strict" (ValueErrors are + raised). + + The codecs all use a similar interface. Only deviation from the + generic ones are documented. + +*/ + +/* --- Manage the default encoding ---------------------------------------- */ + +/* Returns a pointer to the default encoding (UTF-8) of the + Unicode object unicode and the size of the encoded representation + in bytes stored in *size. + + In case of an error, no *size is set. + + This function caches the UTF-8 encoded string in the unicodeobject + and subsequent calls will return the same string. The memory is released + when the unicodeobject is deallocated. + + _PyUnicode_AsStringAndSize is a #define for PyUnicode_AsUTF8AndSize to + support the previous internal function with the same behaviour. + + *** This API is for interpreter INTERNAL USE ONLY and will likely + *** be removed or changed in the future. + + *** If you need to access the Unicode object as UTF-8 bytes string, + *** please use PyUnicode_AsUTF8String() instead. +*/ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(const char *) PyUnicode_AsUTF8AndSize( + PyObject *unicode, + Py_ssize_t *size); +#define _PyUnicode_AsStringAndSize PyUnicode_AsUTF8AndSize +#endif + +/* Returns a pointer to the default encoding (UTF-8) of the + Unicode object unicode. + + Like PyUnicode_AsUTF8AndSize(), this also caches the UTF-8 representation + in the unicodeobject. + + _PyUnicode_AsString is a #define for PyUnicode_AsUTF8 to + support the previous internal function with the same behaviour. + + Use of this API is DEPRECATED since no size information can be + extracted from the returned data. + + *** This API is for interpreter INTERNAL USE ONLY and will likely + *** be removed or changed for Python 3.1. + + *** If you need to access the Unicode object as UTF-8 bytes string, + *** please use PyUnicode_AsUTF8String() instead. + +*/ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode); +#define _PyUnicode_AsString PyUnicode_AsUTF8 +#endif + +/* Returns "utf-8". */ + +PyAPI_FUNC(const char*) PyUnicode_GetDefaultEncoding(void); + +/* --- Generic Codecs ----------------------------------------------------- */ + +/* Create a Unicode object by decoding the encoded string s of the + given size. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Decode( + const char *s, /* encoded string */ + Py_ssize_t size, /* size of buffer */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Decode a Unicode object unicode and return the result as Python + object. + + This API is DEPRECATED. The only supported standard encoding is rot13. + Use PyCodec_Decode() to decode with rot13 and non-standard codecs + that decode from str. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedObject( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.6); + +/* Decode a Unicode object unicode and return the result as Unicode + object. + + This API is DEPRECATED. The only supported standard encoding is rot13. + Use PyCodec_Decode() to decode with rot13 and non-standard codecs + that decode from str to str. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedUnicode( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.6); + +/* Encodes a Py_UNICODE buffer of the given size and returns a + Python string object. */ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_Encode( + const Py_UNICODE *s, /* Unicode char buffer */ + Py_ssize_t size, /* number of Py_UNICODE chars to encode */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +#endif + +/* Encodes a Unicode object and returns the result as Python + object. + + This API is DEPRECATED. It is superseded by PyUnicode_AsEncodedString() + since all standard encodings (except rot13) encode str to bytes. + Use PyCodec_Encode() for encoding with rot13 and non-standard codecs + that encode form str to non-bytes. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.6); + +/* Encodes a Unicode object and returns the result as Python string + object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedString( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Unicode + object. + + This API is DEPRECATED. The only supported standard encodings is rot13. + Use PyCodec_Encode() to encode with rot13 and non-standard codecs + that encode from str to str. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedUnicode( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.6); + +/* Build an encoding map. */ + +PyAPI_FUNC(PyObject*) PyUnicode_BuildEncodingMap( + PyObject* string /* 256 character map */ + ); + +/* --- UTF-7 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7( + const char *string, /* UTF-7 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7Stateful( + const char *string, /* UTF-7 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + int base64SetO, /* Encode RFC2152 Set O characters in base64 */ + int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF7( + PyObject *unicode, /* Unicode object */ + int base64SetO, /* Encode RFC2152 Set O characters in base64 */ + int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ + const char *errors /* error handling */ + ); +#endif + +/* --- UTF-8 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8Stateful( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String( + PyObject *unicode /* Unicode object */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) _PyUnicode_AsUTF8String( + PyObject *unicode, + const char *errors); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +#endif + +/* --- UTF-32 Codecs ------------------------------------------------------ */ + +/* Decodes length bytes from a UTF-32 encoded buffer string and returns + the corresponding Unicode object. + + errors (if non-NULL) defines the error handling. It defaults + to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the + given byte order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + In native mode, the first four bytes of the stream are checked for a + BOM mark. If found, the BOM mark is analysed, the byte order + adjusted and the BOM skipped. In the other modes, no BOM mark + interpretation is done. After completion, *byteorder is set to the + current byte order at the end of input data. + + If byteorder is NULL, the codec starts in native order mode. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32( + const char *string, /* UTF-32 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32Stateful( + const char *string, /* UTF-32 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* Returns a Python string using the UTF-32 encoding in native byte + order. The string always starts with a BOM mark. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF32String( + PyObject *unicode /* Unicode object */ + ); + +/* Returns a Python string object holding the UTF-32 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. + +*/ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ) Py_DEPRECATED(3.3); +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( + PyObject *object, /* Unicode object */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); +#endif + +/* --- UTF-16 Codecs ------------------------------------------------------ */ + +/* Decodes length bytes from a UTF-16 encoded buffer string and returns + the corresponding Unicode object. + + errors (if non-NULL) defines the error handling. It defaults + to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the + given byte order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + In native mode, the first two bytes of the stream are checked for a + BOM mark. If found, the BOM mark is analysed, the byte order + adjusted and the BOM skipped. In the other modes, no BOM mark + interpretation is done. After completion, *byteorder is set to the + current byte order at the end of input data. + + If byteorder is NULL, the codec starts in native order mode. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16Stateful( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* Returns a Python string using the UTF-16 encoding in native byte + order. The string always starts with a BOM mark. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF16String( + PyObject *unicode /* Unicode object */ + ); + +/* Returns a Python string object holding the UTF-16 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. + + Note that Py_UNICODE data is being interpreted as UTF-16 reduced to + UCS-2. This trick makes it possible to add full UTF-16 capabilities + at a later point without compromising the APIs. + +*/ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ) Py_DEPRECATED(3.3); +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF16( + PyObject* unicode, /* Unicode object */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); +#endif + +/* --- Unicode-Escape Codecs ---------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUnicodeEscape( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +#ifndef Py_LIMITED_API +/* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape + chars. */ +PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscape( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + const char **first_invalid_escape /* on return, points to first + invalid escaped char in + string. */ +); +#endif + +PyAPI_FUNC(PyObject*) PyUnicode_AsUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ) Py_DEPRECATED(3.3); +#endif + +/* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeRawUnicodeEscape( + const char *string, /* Raw-Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsRawUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ) Py_DEPRECATED(3.3); +#endif + +/* --- Unicode Internal Codec --------------------------------------------- + + Only for internal use in _codecsmodule.c */ + +#ifndef Py_LIMITED_API +PyObject *_PyUnicode_DecodeUnicodeInternal( + const char *string, + Py_ssize_t length, + const char *errors + ); +#endif + +/* --- Latin-1 Codecs ----------------------------------------------------- + + Note: Latin-1 corresponds to the first 256 Unicode ordinals. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLatin1( + const char *string, /* Latin-1 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsLatin1String( + PyObject *unicode /* Unicode object */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) _PyUnicode_AsLatin1String( + PyObject* unicode, + const char* errors); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +#endif + +/* --- ASCII Codecs ------------------------------------------------------- + + Only 7-bit ASCII data is excepted. All other codes generate errors. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeASCII( + const char *string, /* ASCII encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsASCIIString( + PyObject *unicode /* Unicode object */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) _PyUnicode_AsASCIIString( + PyObject* unicode, + const char* errors); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +#endif + +/* --- Character Map Codecs ----------------------------------------------- + + This codec uses mappings to encode and decode characters. + + Decoding mappings must map byte ordinals (integers in the range from 0 to + 255) to Unicode strings, integers (which are then interpreted as Unicode + ordinals) or None. Unmapped data bytes (ones which cause a LookupError) + as well as mapped to None, 0xFFFE or '\ufffe' are treated as "undefined + mapping" and cause an error. + + Encoding mappings must map Unicode ordinal integers to bytes objects, + integers in the range from 0 to 255 or None. Unmapped character + ordinals (ones which cause a LookupError) as well as mapped to + None are treated as "undefined mapping" and cause an error. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeCharmap( + const char *string, /* Encoded string */ + Py_ssize_t length, /* size of string */ + PyObject *mapping, /* decoding mapping */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsCharmapString( + PyObject *unicode, /* Unicode object */ + PyObject *mapping /* encoding mapping */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *mapping, /* encoding mapping */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( + PyObject *unicode, /* Unicode object */ + PyObject *mapping, /* encoding mapping */ + const char *errors /* error handling */ + ); +#endif + +/* Translate a Py_UNICODE buffer of the given length by applying a + character mapping table to it and return the resulting Unicode + object. + + The mapping table must map Unicode ordinal integers to Unicode strings, + Unicode ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +#endif + +#ifdef MS_WINDOWS + +/* --- MBCS codecs for Windows -------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCS( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCSStateful( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyUnicode_DecodeCodePageStateful( + int code_page, /* code page number */ + const char *string, /* encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); +#endif + +PyAPI_FUNC(PyObject*) PyUnicode_AsMBCSString( + PyObject *unicode /* Unicode object */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ) Py_DEPRECATED(3.3); +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyUnicode_EncodeCodePage( + int code_page, /* code page number */ + PyObject *unicode, /* Unicode object */ + const char *errors /* error handling */ + ); +#endif + +#endif /* MS_WINDOWS */ + +#ifndef Py_LIMITED_API +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters except + \0 as-is. Characters outside this range (Unicode ordinals 1-256) + are treated as errors. This includes embedded NULL bytes. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +PyAPI_FUNC(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ) /* Py_DEPRECATED(3.3) */; + +/* Transforms code points that have decimal digit property to the + corresponding ASCII digit code points. + + Returns a new Unicode string on success, NULL on failure. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_TransformDecimalToASCII( + Py_UNICODE *s, /* Unicode buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to transform */ + ) /* Py_DEPRECATED(3.3) */; + +/* Coverts a Unicode object holding a decimal value to an ASCII string + for using in int, float and complex parsers. + Transforms code points that have decimal digit property to the + corresponding ASCII digit code points. Transforms spaces to ASCII. + Transforms code points starting from the first non-ASCII code point that + is neither a decimal digit nor a space to the end into '?'. */ + +PyAPI_FUNC(PyObject*) _PyUnicode_TransformDecimalAndSpaceToASCII( + PyObject *unicode /* Unicode object */ + ); +#endif + +/* --- Locale encoding --------------------------------------------------- */ + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Decode a string from the current locale encoding. The decoder is strict if + *surrogateescape* is equal to zero, otherwise it uses the 'surrogateescape' + error handler (PEP 383) to escape undecodable bytes. If a byte sequence can + be decoded as a surrogate character and *surrogateescape* is not equal to + zero, the byte sequence is escaped using the 'surrogateescape' error handler + instead of being decoded. *str* must end with a null character but cannot + contain embedded null characters. */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLocaleAndSize( + const char *str, + Py_ssize_t len, + const char *errors); + +/* Similar to PyUnicode_DecodeLocaleAndSize(), but compute the string + length using strlen(). */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLocale( + const char *str, + const char *errors); + +/* Encode a Unicode object to the current locale encoding. The encoder is + strict is *surrogateescape* is equal to zero, otherwise the + "surrogateescape" error handler is used. Return a bytes object. The string + cannot contain embedded null characters. */ + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeLocale( + PyObject *unicode, + const char *errors + ); +#endif + +/* --- File system encoding ---------------------------------------------- */ + +/* ParseTuple converter: encode str objects to bytes using + PyUnicode_EncodeFSDefault(); bytes objects are output as-is. */ + +PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); + +/* ParseTuple converter: decode bytes objects to unicode using + PyUnicode_DecodeFSDefaultAndSize(); str objects are output as-is. */ + +PyAPI_FUNC(int) PyUnicode_FSDecoder(PyObject*, void*); + +/* Decode a null-terminated string using Py_FileSystemDefaultEncoding + and the "surrogateescape" error handler. + + If Py_FileSystemDefaultEncoding is not set, fall back to the locale + encoding. + + Use PyUnicode_DecodeFSDefaultAndSize() if the string length is known. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefault( + const char *s /* encoded string */ + ); + +/* Decode a string using Py_FileSystemDefaultEncoding + and the "surrogateescape" error handler. + + If Py_FileSystemDefaultEncoding is not set, fall back to the locale + encoding. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize( + const char *s, /* encoded string */ + Py_ssize_t size /* size */ + ); + +/* Encode a Unicode object to Py_FileSystemDefaultEncoding with the + "surrogateescape" error handler, and return bytes. + + If Py_FileSystemDefaultEncoding is not set, fall back to the locale + encoding. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeFSDefault( + PyObject *unicode + ); + +/* --- Methods & Slots ---------------------------------------------------- + + These are capable of handling Unicode objects and strings on input + (we refer to them as strings in the descriptions) and return + Unicode objects or integers as appropriate. */ + +/* Concat two strings giving a new Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Concat( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +/* Concat two strings and put the result in *pleft + (sets *pleft to NULL on error) */ + +PyAPI_FUNC(void) PyUnicode_Append( + PyObject **pleft, /* Pointer to left string */ + PyObject *right /* Right string */ + ); + +/* Concat two strings, put the result in *pleft and drop the right object + (sets *pleft to NULL on error) */ + +PyAPI_FUNC(void) PyUnicode_AppendAndDel( + PyObject **pleft, /* Pointer to left string */ + PyObject *right /* Right string */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. If negative, no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_Split( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Dito, but split at line breaks. + + CRLF is considered to be one line break. Line breaks are not + included in the resulting list. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Splitlines( + PyObject *s, /* String to split */ + int keepends /* If true, line end markers are included */ + ); + +/* Partition a string using a given separator. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Partition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Partition a string using a given separator, searching from the end of the + string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_RPartition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. But unlike PyUnicode_Split + PyUnicode_RSplit splits from the end of the string. If negative, + no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_RSplit( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Translate a string by applying a character mapping table to it and + return the resulting Unicode object. + + The mapping table must map Unicode ordinal integers to Unicode strings, + Unicode ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_Translate( + PyObject *str, /* String */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ); + +/* Join a sequence of strings using the given separator and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Join( + PyObject *separator, /* Separator string */ + PyObject *seq /* Sequence object */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyUnicode_JoinArray( + PyObject *separator, + PyObject *const *items, + Py_ssize_t seqlen + ); +#endif /* Py_LIMITED_API */ + +/* Return 1 if substr matches str[start:end] at the given tail end, 0 + otherwise. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Tailmatch( + PyObject *str, /* String */ + PyObject *substr, /* Prefix or Suffix string */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Tail end: -1 prefix, +1 suffix */ + ); + +/* Return the first position of substr in str[start:end] using the + given search direction or -1 if not found. -2 is returned in case + an error occurred and an exception is set. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Find( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Find direction: +1 forward, -1 backward */ + ); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Like PyUnicode_Find, but search for single character only. */ +PyAPI_FUNC(Py_ssize_t) PyUnicode_FindChar( + PyObject *str, + Py_UCS4 ch, + Py_ssize_t start, + Py_ssize_t end, + int direction + ); +#endif + +/* Count the number of occurrences of substr in str[start:end]. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Count( + PyObject *str, /* String */ + PyObject *substr, /* Substring to count */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end /* Stop index */ + ); + +/* Replace at most maxcount occurrences of substr in str with replstr + and return the resulting Unicode object. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Replace( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + PyObject *replstr, /* Substring to replace */ + Py_ssize_t maxcount /* Max. number of replacements to apply; + -1 = all */ + ); + +/* Compare two strings and return -1, 0, 1 for less than, equal, + greater than resp. + Raise an exception and return -1 on error. */ + +PyAPI_FUNC(int) PyUnicode_Compare( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +#ifndef Py_LIMITED_API +/* Test whether a unicode is equal to ASCII identifier. Return 1 if true, + 0 otherwise. The right argument must be ASCII identifier. + Any error occurs inside will be cleared before return. */ + +PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId( + PyObject *left, /* Left string */ + _Py_Identifier *right /* Right identifier */ + ); +#endif + +/* Compare a Unicode object with C string and return -1, 0, 1 for less than, + equal, and greater than, respectively. It is best to pass only + ASCII-encoded strings, but the function interprets the input string as + ISO-8859-1 if it contains non-ASCII characters. + This function does not raise exceptions. */ + +PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( + PyObject *left, + const char *right /* ASCII-encoded string */ + ); + +#ifndef Py_LIMITED_API +/* Test whether a unicode is equal to ASCII string. Return 1 if true, + 0 otherwise. The right argument must be ASCII-encoded string. + Any error occurs inside will be cleared before return. */ + +PyAPI_FUNC(int) _PyUnicode_EqualToASCIIString( + PyObject *left, + const char *right /* ASCII-encoded string */ + ); +#endif + +/* Rich compare two strings and return one of the following: + + - NULL in case an exception was raised + - Py_True or Py_False for successful comparisons + - Py_NotImplemented in case the type combination is unknown + + Possible values for op: + + Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_RichCompare( + PyObject *left, /* Left string */ + PyObject *right, /* Right string */ + int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ + ); + +/* Apply an argument tuple or dictionary to a format string and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Format( + PyObject *format, /* Format string */ + PyObject *args /* Argument tuple or dictionary */ + ); + +/* Checks whether element is contained in container and return 1/0 + accordingly. + + element has to coerce to a one element Unicode string. -1 is + returned in case of an error. */ + +PyAPI_FUNC(int) PyUnicode_Contains( + PyObject *container, /* Container string */ + PyObject *element /* Element string */ + ); + +/* Checks whether argument is a valid identifier. */ + +PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s); + +#ifndef Py_LIMITED_API +/* Externally visible for str.strip(unicode) */ +PyAPI_FUNC(PyObject *) _PyUnicode_XStrip( + PyObject *self, + int striptype, + PyObject *sepobj + ); +#endif + +/* Using explicit passed-in values, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping( + PyObject *unicode, + Py_ssize_t index, + Py_ssize_t n_buffer, + void *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + PyObject *thousands_sep, + Py_UCS4 *maxchar); +#endif +/* === Characters Type APIs =============================================== */ + +/* Helper array used by Py_UNICODE_ISSPACE(). */ + +#ifndef Py_LIMITED_API +PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; + +/* These should not be used directly. Use the Py_UNICODE_IS* and + Py_UNICODE_TO* macros instead. + + These APIs are implemented in Objects/unicodectype.c. + +*/ + +PyAPI_FUNC(int) _PyUnicode_IsLowercase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsUppercase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsTitlecase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsXidStart( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsXidContinue( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsWhitespace( + const Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsLinebreak( + const Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UCS4) _PyUnicode_ToLowercase( + Py_UCS4 ch /* Unicode character */ + ) /* Py_DEPRECATED(3.3) */; + +PyAPI_FUNC(Py_UCS4) _PyUnicode_ToUppercase( + Py_UCS4 ch /* Unicode character */ + ) /* Py_DEPRECATED(3.3) */; + +PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase( + Py_UCS4 ch /* Unicode character */ + ) Py_DEPRECATED(3.3); + +PyAPI_FUNC(int) _PyUnicode_ToLowerFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToTitleFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToUpperFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToFoldedFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_IsCaseIgnorable( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsCased( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(double) _PyUnicode_ToNumeric( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsNumeric( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsPrintable( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsAlpha( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(size_t) Py_UNICODE_strlen( + const Py_UNICODE *u + ) Py_DEPRECATED(3.3); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcpy( + Py_UNICODE *s1, + const Py_UNICODE *s2) Py_DEPRECATED(3.3); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcat( + Py_UNICODE *s1, const Py_UNICODE *s2) Py_DEPRECATED(3.3); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy( + Py_UNICODE *s1, + const Py_UNICODE *s2, + size_t n) Py_DEPRECATED(3.3); + +PyAPI_FUNC(int) Py_UNICODE_strcmp( + const Py_UNICODE *s1, + const Py_UNICODE *s2 + ) Py_DEPRECATED(3.3); + +PyAPI_FUNC(int) Py_UNICODE_strncmp( + const Py_UNICODE *s1, + const Py_UNICODE *s2, + size_t n + ) Py_DEPRECATED(3.3); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( + const Py_UNICODE *s, + Py_UNICODE c + ) Py_DEPRECATED(3.3); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( + const Py_UNICODE *s, + Py_UNICODE c + ) Py_DEPRECATED(3.3); + +PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); + +/* Create a copy of a unicode string ending with a nul character. Return NULL + and raise a MemoryError exception on memory allocation failure, otherwise + return a new allocated buffer (use PyMem_Free() to free the buffer). */ + +PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( + PyObject *unicode + ) Py_DEPRECATED(3.3); +#endif /* Py_LIMITED_API */ + +#if defined(Py_DEBUG) && !defined(Py_LIMITED_API) +PyAPI_FUNC(int) _PyUnicode_CheckConsistency( + PyObject *op, + int check_content); +#elif !defined(NDEBUG) +/* For asserts that call _PyUnicode_CheckConsistency(), which would + * otherwise be a problem when building with asserts but without Py_DEBUG. */ +#define _PyUnicode_CheckConsistency(op, check_content) PyUnicode_Check(op) +#endif + +#ifndef Py_LIMITED_API +/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ +PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); +/* Clear all static strings. */ +PyAPI_FUNC(void) _PyUnicode_ClearStaticStrings(void); + +/* Fast equality check when the inputs are known to be exact unicode types + and where the hash values are equal (i.e. a very probable match) */ +PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_UNICODEOBJECT_H */ diff --git a/Include/warnings.h b/Include/warnings.h new file mode 100644 index 0000000..a675bb5 --- /dev/null +++ b/Include/warnings.h @@ -0,0 +1,67 @@ +#ifndef Py_WARNINGS_H +#define Py_WARNINGS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) _PyWarnings_Init(void); +#endif + +PyAPI_FUNC(int) PyErr_WarnEx( + PyObject *category, + const char *message, /* UTF-8 encoded string */ + Py_ssize_t stack_level); +PyAPI_FUNC(int) PyErr_WarnFormat( + PyObject *category, + Py_ssize_t stack_level, + const char *format, /* ASCII-encoded string */ + ...); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +/* Emit a ResourceWarning warning */ +PyAPI_FUNC(int) PyErr_ResourceWarning( + PyObject *source, + Py_ssize_t stack_level, + const char *format, /* ASCII-encoded string */ + ...); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) PyErr_WarnExplicitObject( + PyObject *category, + PyObject *message, + PyObject *filename, + int lineno, + PyObject *module, + PyObject *registry); +#endif +PyAPI_FUNC(int) PyErr_WarnExplicit( + PyObject *category, + const char *message, /* UTF-8 encoded string */ + const char *filename, /* decoded from the filesystem encoding */ + int lineno, + const char *module, /* UTF-8 encoded string */ + PyObject *registry); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) +PyErr_WarnExplicitFormat(PyObject *category, + const char *filename, int lineno, + const char *module, PyObject *registry, + const char *format, ...); +#endif + +/* DEPRECATED: Use PyErr_WarnEx() instead. */ +#ifndef Py_LIMITED_API +#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) +#endif + +#ifndef Py_LIMITED_API +void _PyErr_WarnUnawaitedCoroutine(PyObject *coro); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_WARNINGS_H */ + diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h new file mode 100644 index 0000000..1705156 --- /dev/null +++ b/Include/weakrefobject.h @@ -0,0 +1,86 @@ +/* Weak references objects for Python. */ + +#ifndef Py_WEAKREFOBJECT_H +#define Py_WEAKREFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct _PyWeakReference PyWeakReference; + +/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType, + * and CallableProxyType. + */ +#ifndef Py_LIMITED_API +struct _PyWeakReference { + PyObject_HEAD + + /* The object to which this is a weak reference, or Py_None if none. + * Note that this is a stealth reference: wr_object's refcount is + * not incremented to reflect this pointer. + */ + PyObject *wr_object; + + /* A callable to invoke when wr_object dies, or NULL if none. */ + PyObject *wr_callback; + + /* A cache for wr_object's hash code. As usual for hashes, this is -1 + * if the hash code isn't known yet. + */ + Py_hash_t hash; + + /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL- + * terminated list of weak references to it. These are the list pointers. + * If wr_object goes away, wr_object is set to Py_None, and these pointers + * have no meaning then. + */ + PyWeakReference *wr_prev; + PyWeakReference *wr_next; +}; +#endif + +PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; +PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; +PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; + +#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) +#define PyWeakref_CheckRefExact(op) \ + (Py_TYPE(op) == &_PyWeakref_RefType) +#define PyWeakref_CheckProxy(op) \ + ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \ + (Py_TYPE(op) == &_PyWeakref_CallableProxyType)) + +#define PyWeakref_Check(op) \ + (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) + + +PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); + +PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); +#endif + +/* Explanation for the Py_REFCNT() check: when a weakref's target is part + of a long chain of deallocations which triggers the trashcan mechanism, + clearing the weakrefs can be delayed long after the target's refcount + has dropped to zero. In the meantime, code accessing the weakref will + be able to "see" the target object even though it is supposed to be + unreachable. See issue #16602. */ + +#define PyWeakref_GET_OBJECT(ref) \ + (Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \ + ? ((PyWeakReference *)(ref))->wr_object \ + : Py_None) + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_WEAKREFOBJECT_H */ diff --git a/Lib/__future__.py b/Lib/__future__.py new file mode 100644 index 0000000..ce8bed7 --- /dev/null +++ b/Lib/__future__.py @@ -0,0 +1,146 @@ +"""Record of phased-in incompatible language changes. + +Each line is of the form: + + FeatureName = "_Feature(" OptionalRelease "," MandatoryRelease "," + CompilerFlag ")" + +where, normally, OptionalRelease < MandatoryRelease, and both are 5-tuples +of the same form as sys.version_info: + + (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int + PY_MINOR_VERSION, # the 1; an int + PY_MICRO_VERSION, # the 0; an int + PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string + PY_RELEASE_SERIAL # the 3; an int + ) + +OptionalRelease records the first release in which + + from __future__ import FeatureName + +was accepted. + +In the case of MandatoryReleases that have not yet occurred, +MandatoryRelease predicts the release in which the feature will become part +of the language. + +Else MandatoryRelease records when the feature became part of the language; +in releases at or after that, modules no longer need + + from __future__ import FeatureName + +to use the feature in question, but may continue to use such imports. + +MandatoryRelease may also be None, meaning that a planned feature got +dropped. + +Instances of class _Feature have two corresponding methods, +.getOptionalRelease() and .getMandatoryRelease(). + +CompilerFlag is the (bitfield) flag that should be passed in the fourth +argument to the builtin function compile() to enable the feature in +dynamically compiled code. This flag is stored in the .compiler_flag +attribute on _Future instances. These values must match the appropriate +#defines of CO_xxx flags in Include/compile.h. + +No feature line is ever to be deleted from this file. +""" + +all_feature_names = [ + "nested_scopes", + "generators", + "division", + "absolute_import", + "with_statement", + "print_function", + "unicode_literals", + "barry_as_FLUFL", + "generator_stop", + "annotations", +] + +__all__ = ["all_feature_names"] + all_feature_names + +# The CO_xxx symbols are defined here under the same names defined in +# code.h and used by compile.h, so that an editor search will find them here. +# However, they're not exported in __all__, because they don't really belong to +# this module. +CO_NESTED = 0x0010 # nested_scopes +CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000) +CO_FUTURE_DIVISION = 0x2000 # division +CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 # perform absolute imports by default +CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement +CO_FUTURE_PRINT_FUNCTION = 0x10000 # print function +CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals +CO_FUTURE_BARRY_AS_BDFL = 0x40000 +CO_FUTURE_GENERATOR_STOP = 0x80000 # StopIteration becomes RuntimeError in generators +CO_FUTURE_ANNOTATIONS = 0x100000 # annotations become strings at runtime + +class _Feature: + def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): + self.optional = optionalRelease + self.mandatory = mandatoryRelease + self.compiler_flag = compiler_flag + + def getOptionalRelease(self): + """Return first release in which this feature was recognized. + + This is a 5-tuple, of the same form as sys.version_info. + """ + + return self.optional + + def getMandatoryRelease(self): + """Return release in which this feature will become mandatory. + + This is a 5-tuple, of the same form as sys.version_info, or, if + the feature was dropped, is None. + """ + + return self.mandatory + + def __repr__(self): + return "_Feature" + repr((self.optional, + self.mandatory, + self.compiler_flag)) + +nested_scopes = _Feature((2, 1, 0, "beta", 1), + (2, 2, 0, "alpha", 0), + CO_NESTED) + +generators = _Feature((2, 2, 0, "alpha", 1), + (2, 3, 0, "final", 0), + CO_GENERATOR_ALLOWED) + +division = _Feature((2, 2, 0, "alpha", 2), + (3, 0, 0, "alpha", 0), + CO_FUTURE_DIVISION) + +absolute_import = _Feature((2, 5, 0, "alpha", 1), + (3, 0, 0, "alpha", 0), + CO_FUTURE_ABSOLUTE_IMPORT) + +with_statement = _Feature((2, 5, 0, "alpha", 1), + (2, 6, 0, "alpha", 0), + CO_FUTURE_WITH_STATEMENT) + +print_function = _Feature((2, 6, 0, "alpha", 2), + (3, 0, 0, "alpha", 0), + CO_FUTURE_PRINT_FUNCTION) + +unicode_literals = _Feature((2, 6, 0, "alpha", 2), + (3, 0, 0, "alpha", 0), + CO_FUTURE_UNICODE_LITERALS) + +barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2), + (3, 9, 0, "alpha", 0), + CO_FUTURE_BARRY_AS_BDFL) + +generator_stop = _Feature((3, 5, 0, "beta", 1), + (3, 7, 0, "alpha", 0), + CO_FUTURE_GENERATOR_STOP) + +annotations = _Feature((3, 7, 0, "beta", 1), + (4, 0, 0, "alpha", 0), + CO_FUTURE_ANNOTATIONS) diff --git a/Lib/__pycache__/__future__.cpython-37.pyc b/Lib/__pycache__/__future__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1abffeaffa778bb112cf993ba508472823b5d46b GIT binary patch literal 4146 zcmbtX>uwvz6<%IMQEN+cMms}to#iew zv$QP3Knpm1m_9*YrQpx@mtLX2`kmQbijtflXqVvG!#QWp{hS#-Szos;Jf(j<{L^1< zSk}MkNA?iqF~0hr0K#%CkrR1Q5Jj;fN@7)%#hS23wv!W=Mmd?=vYfoQ>=eYhQxqG{ zin!vG#HO<*MKvumw{hT@ipK#fPW?`(guDL_+9b2yafCf z@Lz~8F@0d>rP`o3VG0zfrK(v zsa4oB9ts{u>Ue3*r`s#w78iQhX z7{z18m1MuU7tf}F)OPBRChN&5#x>K&y8cQk4dY!u97d_5+j}qEXN^B}d+zgQuixr+ zYV58F#zTaVJ*+>d-{-%61U>i}CqB`RR_Ef52k&9q>2=QwzJGzO*K9W%{ifS)K5w>3 ze}xCgWTnO`hcY&A503hXv8=F2vC7a#1}cx3j+Gyd7G`CF`psUe(M}yXYkk$W&u37X z^3h2N_)5o2rMX1}j>f(>PHJMPq6u@|;fyN7b(uezMk-z|6(kXn=AI{~u@tDXR%oPp zR47Qw`8pw;JZ5A5N+RzuJC-qvJa49y6gB%iH=APF_u|CT^EM{tCuPfy{2*Y5@CyYn zS=`Ph1`jZ$C1!AyFQZfxiZ|Ynr0@-c}useF#pWJz|5j>Y#;jZ(3gRz zvLVe8Q%!mt%>qmXN|wenq&`lj+f2n{o2$`mBEy)XM9YUWKS0>na29$LPnc{b6YK$p z3^@(Zv$40uamXjWM`J2u7eIupGd38*IAaao8bk5af_f@ixkR^ljP6D9&>A5^XW9zJ zrcpJbB=Y`>2S_!W%+Qz<9wVn@4WCYt3FTuX*ms4*Ku8j?({*3Jer*iU$g#2xTW)q%=DLBt|3oi>L`SKf0Hhc8`rW7}Rxpz77>2xY~=RQqS#?45gy6ujggq zzw&9c&ad!89R+a8O)77`apcEi7f!{J!am=C(P4}!l7xG{ISYLXog4UQ8Pwx^~ihyw)c12^Nocfh>522OQ^~S@}N%7uObOrkUO^;k>bFn2|QCFev@0Plb*MA=Ge0i|1ar_-LJI`OR2fsZKQh$eN9`s}Geb+_$ zhe337uZ<)$_F4yle|T^@>g&^E_=aQCk6rhVlufaBPt$x)7N-U zTi#kPjkj<9){{6z&~@)UZ&2aXMAN(am<r94>&r*(=iVoZO(=>F{1|ik(gb7&-niHB512`K3Wdi`8j_kYAe`f z>gF~Ok&CHz&^s^DIWG&t!aH2q(Kq>y+8}Gt7D`T)Nv9(FO!fbWktk(icHI#e(^4+y zif2nX;pkLXsq$&CxbEC`-Q+L_e%W=upYb4}sGFpc`de)gxI=&%ZwXLM8DsZ==rTY# zS6(TX%WH`XD<@P~C)6)$9bjIh%b)rLXmv$>Ov?rs+KRa$8omoe#fW!l-${WMl6~gp z_*45x2Sk3BZ85xwNRp6hJE8O}k(RYlqc4$`cB#+Ll9qLmgr!|eq?5I?q*S1>@a}^2 zDPgG@L^@erkXVLgetnTGsHI&eG^-N}NW-bio$BrRs_Tl#L)}~giGINTwH?hp2RP4{W*d5ivFICoCh8c+J&_Wq#hww~>E zdjse8De2qR;2XC;XbhUqnw>M0y;fW&=px@W)B+UY*UABolgcC`D>)+y~t zqt|=kHu~<9r@QTCMW;sh2i-mA=ING3r_+T2P|`Ogs!VNCl`2zFCSaxzOv+8bsjiht x82tlZDu2@rX0DdMN}A~R_ramZ0L4N+cm7i<*rg(x^4urC@lg@HrTqT_{|j%MV#ELd literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/_bootlocale.cpython-37.pyc b/Lib/__pycache__/_bootlocale.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25c4a8029a20852a86f36fcba93b77124f94ef37 GIT binary patch literal 1263 zcmZ`(UvJws5GN_wRuskkgJM`;2K8wZ&;(d8v_&@z^U@4hQKSQs{&NkevX4sW$f9wi z8#u^bwtbM~ao=XodfcA+75da8m2_#*(&q8*MBe@Gca(l!TZTf5GbHIfFjLtqo$AWmk^>8Kg5+t65Q{W-&I>rn*e+ zflMnsDJq%HG%RRY7zt@%Q&n4ubCe`gV+*v4dHju<%{5xuFkbqjxzgw7vfFeb)d;lR z>J%j`Ci3E7YSm0`#PI`Ne@&5nkQ5ZkiLI7tiF!uS6vFzP@+{Md2Kl`M;&Z%e@x8hL zsA^+n0k`5e#3V1t!3EnI)#r7>JvU7zuWcJ5Tn0 zS-e*1M)sqrWuYkeMO zW4>%|P%dJ>lt@&{nkZ5A{;DggOM>x;ha8~NQz@2 z6Bm_xv>8WtNxj|*cbk3eFGw+tO~&7cbY?))hy03^%LIb}Rt3NF6Mh<=urrtJJHxr_tr>kp#Opt?gFP8dd({lP6Ye;VKo-~RBl zW5a3pj5~y8lb-cJ917e7@41Y&=|X{Yv$Ck^4-ECvDqU|QYW%1Gq&J=oSL-UTih5tw zrEYp#j~{IBZtpeGyee#|aduu<(?x0M_I#?gTNK9hNx0fvcN5<4g*@YX|NmF$GUlKs zdESC>sqrd_CibtWIa2n(Gl^H6w?D8J)p%j0N8a=f3R95lQhv{}Yj_j=(0&1abiFaI V^`RgnBH>9#@R;{`93;Wj=pEJDDDD6N literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/_collections_abc.cpython-37.pyc b/Lib/__pycache__/_collections_abc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8a10199e16e23ca8daaabf6d4d731d39e6cfb14 GIT binary patch literal 28956 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

stgxz?@sTb=6g#+A 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 VRK67d6LguTARcnYE;@6^{|Q9+hCKiP literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/abc.cpython-37.pyc b/Lib/__pycache__/abc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff8efe253fefa3ab9ab8356a9e88a82bf00596ba GIT binary patch literal 6465 zcmdT|TW{RP6(+e{Ewx%*Z28i}F*?1V+D+vJoB%E2Hic~^XkFBD;9T0U0tkvTl4x_u z%?wxaZr3lBfuKNLw0$)KG%o@A7y489(1-S^f1ywP&hWC-TD~L&f|d);a%Rq)IWu!E z-_$O7$$HB*Syy|Z#xZxVy+!oex!)>76 zMib|?uZ4{TjNc>$lH-KSacT$ZMQvGa+d}jw=-CFmj^5E%3#%99jv)) zrtwQ7e%&_2nfq<|XVah`MlMBX2kY)SjYhpA*1dBd8}Zp+8JK68uV9`PaUS!mqrS@5 zP+t@4{LJHqdx4*Q-{`GR-n_A^Qt1aNyXh;zwjy6Cp;-6E%`Meqeh?&*hw(m36ZYP_ z@3A+pUVW<{m{>JE^l#za!mDVvxH&aEV`_l4<^LVsHy9US;irjYVa&t8Pl=mfPC5|j zLBdtP-DY_1icdzN#PsQbpP~>9{eD0)u~0F{bQ^UBUR=oVP;j;ERn{G!$|}lS265z>h;UC^zUs1-`cvi^Pv(_?Yz7F(Z}rS4|ljw_tRv! z^FEIF{vB-NUX&bN`9+wD8}HrPiNf6-e>dn4$JxqB_ASyj8-=m9U`qN3s8T+S;zNBG z9|ATB`?R>}Hn`>5pBj6nwou1yerni;y8u;fX6xk)dPDP7_&mr>wz<)Yxg(lGcE8eAXnwW)A@(&y@Mov{0CXLM5k>Vr;K;FAmJizrInAU&C>>pQ5;)b;XdCtK53xkQ6IR4h}mLPe#Pa+Ru@|5M7i zhORg8)|HXkPADUBx=uvrP|SN%-hlVCv$ayhp-d3G(y_k>9ez>hFNi}?YTf@!^q&d- zVgOL1{hz@AB$AoQ!~HVn8XC zAeazoNqHm@?lqrMhpKS}Od@==5hd~d2HOKnBFI#7CTxjF3x}7)UjY;m@YxsXgJOvl zsv(3!5B00Ef0G^h(Ma^JJw^6_yPVcoEqcV0j|RhR6{E4G1rIp}%e+C)s1Vj$ z1%Q?7kSA+k!V~TYenmg(F8=E7NCP{IHy$~z&28R9GKR#9xA4Ef9lnVF7C*z6c;}Jn zI(c&BF6K#*+tyHU3C`@Sr10$j5gT{ANsmsu%duc5wf*G_~1$y=ScvV zeOx!Q@{}r0qgaYaCpJM6Lk@_c&xn#eaR|P?S;4@?VJik%#l|qb`(Z=nnPPe2~iTO5Q!O*qH6J~%!i%{UcxQtE>T{r_st~ zuy}}9BM8I1U^?bxwJ=~n6g|&Vuz!mN5F}1ArRg2V-xnNdVL5-IZ`2<>y+K| z!kwWMrsj%0?{}4y*5s8^%BQHlqPXQAb<2;LxEE*Q%5UNO6iLfLIzV{d3Prb*z5X_g?iFysAH(0g*!j9kM!0kU@6SM&y98@; zsgibvm*hC7dufq3XCmj|=tTm*`fP#E%nnWEVtif`cjg;N+w@xZbQdPh6 z$rYx71<3EC_yTW^wi~voTj;i`0*2eYi+R>g0X|#O!sqZp-wkD*`fY_I`^cO!Pte%i zwds5{V%AYzM>8EYB>7@((^{V;=}5M8YcNb?`mU6TbX(q#?tTNk>)IJ)b~=XJBEf5l nPtmT3fiavp;hbB$h~GCYbF;Bxu9+Qc?Fat>u%xn? literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/base64.cpython-37.pyc b/Lib/__pycache__/base64.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..365994cf9e5b0277b8ead4d8f744925a77166e13 GIT binary patch literal 17073 zcmds8TWlQHd7hb_-JM-7DT<=0i)CjdOCnbiX_C5Fwq@DWg^_H9b}U)4*OKYso*}v9 za+f?aE0OD66_A`*PIGP3^cDn^(QBFlMNyn{Bo2Q&AqGV^N$?0c_sKh& zt_kCkmcLLxd)o2bk>iJL`aLqLevcou2VNaNV;?zo^h912oj7JY6=9Eg#Zn1*;rNd2 zR*F?os?2z6wD%K1iVNHzC0smkgAR2+wc@*8(4h*|O=jx&(XcXQ!}^)2BcpNYkCnd1k9xku zhS-jrsV%q_-}Yv!wX(2_)r#+wDt5I}Ua`k6ow;zqF3vjADf+JT>ZdkVpK@)-=A9ZW zm*!o&IyL7OeY+~dw(2d1?Ml_R_se`okS%$o3axU{4H9@N4Xj7d^ID}ugm8}N#62fv zRR-BBPPrE5JNOlo{>mcgBfH=(ROQNzl6x~q`_+(6F5{VMn3pD@!BQdDbBxq!dnE6 zCEp!;<-)acY3kY(i2nG|p~aP8`=lDow5%>ns-2!BBHxRyy&Xt2J*ykIy6~UXP2_XP znYyGJMVc@DC2*y1F;SdF#@FWb2D8Ag7)_(0i^P0JzThK=Z8YZ%Z^%#hCfyNPG>p}x zpIS|eWJAAa5cxFdn5LYApf#=~)oHuzR%ZNJd(^%;TPn`l-lAJ9O_y8`Z{g0+hbt?N zU%COhDKE}CQ?74MgIZ{){fGK_H2qKZx6#~?ZC{=(p@%ZIq}9>lV!2dAN7ah$S8aD_ zX2_m#E3R~W*T&%_3Y;#LU2nzn-36P@YBXUrT5pI4G!DW@SKOQBQpKHEqrLGcIrL=S z3aqJ8g%3-Rof>r}6$Jzd%rWR1^FTlJc13cgbQfii@ugGo${0eB45@O#nRmG~pOBwH z$AJ|sV~|!%Nia>SWDjacB8nrpJQkekF5S|1=so&)ktl}#)=|zh3W%ND(VH4*MhDHD z#yx1Hsrx$9jse;k_6n2gw!^$0UL|{0Ge8;dA=P}l=m=ZVz<#5_qLJNh?X`b zw3_D%o4Akb2&)r_O#V%uYOL@`557Tmxo z@mr_4caMrnU~*D|O@hNNIzqT2eAR_%`-W34ftk2eZ`>(+u024b6z;Tx5kSJW#)siM zKKQq5SKJaRNpwt8;ulq_asg+SXm*eed34rL&ePs>eW)){@`{junBk%+ddPkNN5n9N~k;`t;f@iHi|pj3-TB*% zCq=1dzmOH*D2)Ga9~mMzCa_S1sS^{5vBOM?Ec$TB9DA``0}()d#2lf2d9yb58I|sr zXW;?k-qy=ArI}m?t^W+PMehsg%9MLIp{vkNXrn9nkkh;kJ&>K~5s7LY7Nmz~BR6*X z%-M6}pFMx!#g{IAZsO%vKL6^a%dcIz`uZD%(IZEX9e*mOLh75^(qZ>bgUEas7W0-o zEDXX3eElpa@O|w)Z5pNpO02sYl{l#Nz6O&6G1y(x2C8L?QzZMeCe%tf z1ydzO#>Wn=SKCg{(|5F{;ahW=X2RE+=JK4M73rweoy1w~`juv~0ordQ8%dGeu6@DS zsR`?j(M&arhS^Ao%=6k#jdR)OHPP_`?zXG@+=lz`*;9Dq(z{nl@$H;9VR;|Q`?&lWu^r_=X{aB+qX9b{r*&uj zrI0z&@qDm=Caw6$C{ySI>?$&=CgQy!9&O^fM0-UV&J1|P^)9IInAbEE`EM9Y<|QSV z!Hh_2$s2(&G#u!q4bu9rBztV>vee{vi32Du! zZ0)~Lw8oT936=aemC$p3#dB-8{V1OU8lc8C8ssP!opbpJYRa9I5W|*_Qqqqk$j~l3 zQaUR^qEzvNEZh9N^+6K0-i)iZBh9K)!797ceii6}9HK5RA}OT9SIXnmp}m($vP2o7F{#Vjkajud8r**qryeM4hD}WZF~C)JfJgXU;2BA9i`4RM ze~ZXQqhW4QX{Ny|(v7q*6|ZPoBHPTY>|Ng7ut1N!&1@qhI!J2tQwS5oDcv@Cf_Mi-0jA`X8UkI2@Al?R<|oFubbtjUrOqqim(tI*rnT8wPl z*y0UU$Ou)&3mEtzl&BhEQ47xEA`K`s;+4TSY!B33SM+UyW&zmJfqOMCaxcLcflTTS5N^%3QI1cq?`|x(|DK>TFTvE%)=wJgcU|ZVXwkm zZXsj}#R$8jcd1E@wBWX=mqqBtP~HZ(E7dD@ix5`TXRGlrZ)5qUv*OvbWZaOuX`9T; zH0(|HhfR?XdZ3=dA(M&X_}tAfujq(EAxIUYy~11CZTwGblztK%g@&&H1Ptqbi;Om= z#P|+0K&2+O@CY7w3zGoO0mK3T`1&!gm(e6x*2(A+%jj!H6Wo!c;;*)3^m>UnALuuf z9JJ8~b9_i?Q7S4a{nx~*+oW`8#I~e#Tyu@&M1AXp2t1157&#VoF+9TJ?qxYnZz91d zpQSc2Gy>Mp293z)sK#fJto-Z_EXB8qX%c{mQAG7$mM&2G|5cq-Uu>o1ug?Z zTIB_*xt9`>mkgfB5z0LfYDv~WhB8P=f?*fsi&Xh@NCN96cSXT2mS0s6JHQ)-nMPcx z0FVZUDA3CV3)(wvq8Fsqnu!8w9T*==+Cpln=D?E?B%ESVPT&Ov6NZ7mVJjqw%Rj^A zk+9Ytu^@Ua2;QuzkefaTUJH2$V?znyZj=zXzXO7~NAE=`#5C^v+Aj$2SgE3YAo8K* z^_0!M3Y`C*zG~bfmyG@?)XI_LAE#DA6C(txke+py%cbcR`3CMDV8W7q^-~%Z(Vv!x zJri_G#Lgoor9`0wgfGipGGke=8>jzusa7*oro0kWZ^)OynY;L=vPt zXucsJ%4fQesZ~O%${PwRyiT?4IN3wF4kRXa-Xm>P%UX1T_=GT-oxH_Aw@ww=v_%aX z9$5o)M!fGKA!;M%sMkk^D9q19OOfn=feHgO)kw*sFhGq)Dl|Sx!3z~jq3_cA=zKwa zgu)&v-8}ZNk(|zH2qoqyjfB^zlI>;eF7sL<)vz8V2N-@4_HOKGUmF=}As; z4;8b6%~e$@va43ZVxLIIgyNPbG4Q&%XTP`*AACASG|6qayjPI0HFX}=l!0TUd%Z%d z9KV~8`(StKc=m`y^oLwpX z>suLZ?KQlt^z`m zMi^1y9V3KWK(&Bl6!=0OI^;q136X}cF7-Z45_#S??_$f}2SLd1`bm^r5mvo~?u7+H(&tguNWypAc~3`pM;E9W zzCM22_wQTy5fF%<&DQK-kqxsqG-#d;}%3?hA=4Gl)l8P6s4 zjx}Srun?CZ5uM;J)gU?GBwpzc8C?wb9;KiKGA`JytO(d1P_YZc%cH}2GDJM+9q0(U z>C}qdKjl}Q{vmcOb8pkG0}nWR-AIpKSD6O0H$w3D+GDiaN{Yb(36c3C;jmMXbo>%*C%D;sa)7grUl}A5=dkTM zaIc3QlkeKTSt`Tb=h|>SEL7o3r6%0hf>T*(>mQa|JZc=A%|{%o)^xO#wc*$ca6pz8 zVb;OuI*M1pj#9oxmguw=Fc9Fm(pVMt}>%ghn>CHYZ{5#v-Lv>{fq0^^*R;*lfZDySy|!S zC98<>U!; zpjfC)IZo(xjLBVW4e>I=YHUu#gIFiSAW)PH>m@`GRu9;WLT1_!O71@tIlM5yDpN{T zlHUFAzZ}0`R|13V5jls11zI+rl{cw`O@wSbw^8QDnC#ezW0x+Ey?QxFEI7*wv`dkp zTM@E?b}(8{kx25)XzO#o+Rx@BnTvGYLy)B0OPAWj^hA72M}-00NQFK z=d#Tda)8p1gZ?wu(ad~ZUxs!iQrn4|{=EsPzL7N{wB~jBO<~RJ0J?G&=y4UlVKuUM zASe7>BMk|XVUTJOP+SLqIOtLY!~rtvfX;+ob`TKPvGjwh+DbQoIkVA0P@x{da_PBF z2Ih3C0?zX;Ezp9De)h?2K&762d%@43-XQLDKzthMe8m3d} zea&1W2YJ}%d=V$2&8CSYUpuFIc<{-g<%hrhFry- zAH?hP;VQNrtVq6+3}oap3QG$k8VN3>6R08?S-A44gfOWtkd)v_hj=ANoQ3Plk&sbX zB*Y6sR7po}>rCN_kToGz#yy2CIB<=^;qGt7^QQ>QPm7Ro|Mih*)!KIQR_Qo$)iJXRgi?I29a1KDDqux@`0to zFL4cOctK7gU+4;Prb#7V3MSBOS?HiND$4Q=zah|<<=becB+4S?>^NcBvIV!3BwMZ^ zqji%+p}0|!Bk=4PxnvG`0-ebJ)2;7<%puDp3wdKO_|%P(ES^zHULyL<8m7_BzM~ZE z7?1XPctkmePdxo#_pvio1nthumgeTm3zh2P65zSojho9W^*vAQ+kapnfAG-YvnQWB z_52HOO}_n3qj_r`SVU5f#n>n^p}7NVmQ9<`-$deR6GKP81J7nYS^wcVjs@AoV=+ai zgkk^?N*=O@k25o%Fq38r-T`w`g`}YqQo&IaYP766LirvBS0y#ui$YgXWu2Z!Fav!cj{y7nd(!$`yeVFAP>ud>Z!q22QqWe#-IR2nDFqp-^jCYb# z^~ABrsTySIj{8%}8k8%x<5};rQD2=0J_-aC{V{b&7`K)oLhouJsDx9-noD3%dtFYUe>2HZr>PGCq0U`VjFA>R`UKZ16|5wYa{ zoJ%*8%YWws{|ViZ33f;R6~Z1^=@p649hnlTW}4lRDb|7vxGK}Vq{l%kgBFxt`X;+0 zUxYg{g8=>iP&&`@DB^NcJk|pks|EKex8MMcA0cSMf@%#rox}Ixuw44lRqeK>g7{Z@ z8Ybd#lcb4}?S55T^3i*8F2`EcXsA_XMWz9q44M@?JeT~}Q4iWqcD1u%LfgqS60ALC zfZ!%V4F}Fn9L0|MQk#0C&fQ?UfcY5hrWHl=iQrK_T@!22`IP8krT-QQr#2z<#1u|* z$O2*sPKGX=h$W5y-!JNi!U~a~BDO&|5XDL&P#eM@4d@ix`vuFDd>45%_{$IZIw(wj znG(|Tl`kWf9`cJ+Mh1u^3y6gd%My8)ZdrO{6>XD`pPdbo7=Dm|fiB;t956SGg#|*O z&ncN;Q)N#040Pi5hja!`BBNQv%wb>vfa-#oL4Z^rn0(}Wpb!BnC2xg+6afS9MUXJ) z($_Acy+S34DaV|ectXsn-^R^y0cHlERuF{IFua~uv}J^elW*VG=QVj+Jyj(;2ue)= zEp@EOro2T) z#S2WrL^cXsVx#{;E8K^SW{?+$)|106@Jn8tc(F(|B1TFp=p9C~e1Mh%NHi@~_bXVo zRpfY4fKWFQ8z&x~qE9n%Gq7mlJoNo|r6h4Ge;o-p>~B#1H!1mTN;V7CrSX19^CNaj z^COjlW*LhHniX+Vp4G1)gAa*-w$rx)2%9(oPNIWPoz*c*U90aR|IVB-$J`P;D{%*o z&fB!P_-`7w@L7`LN)3GuA1lqL<;+ zD5WOqd);MxIHIsRh~4%u=aK#G5NJTg%zk_l zLc0Ebk3o+5K-^|z@GO6)7SfjC@o-r*ior31PSPr z03*Da4b&HGon%_&Zib%e;N$QBa$w z1C?p&%O?Q;LI~1!B6<(-@AZ8kRywT!mP3(+?Fm2q0KqcJK921);40xS(DI4;mH5Q6 z%A-CKL+n%44#TjcPrTa9su&q0(p9J*yb+?A+y!_rD3>ut1{O!$b8qG+jZ=*jWQ(b122A8j6gS;~=& ztMIq@hA{6X0C7Mm;K-U}{qc+Lj8j}eL_-M%HKwD4ATP>5Ud?BsKBh{^mtC0|$diKU zzzT#%4&Nq`EzYe$lCT$#42>KnRC0Y!Y?Hw&W8HLQ1)YF*Q7-5?8}@<_E&s`L|W*()plEIu%ccWzyW z;m%3kiQmQOM<12m0#65;S04u71%I9dir6p-A@eDS7hGQGJ6Yq@ArIgg zN)dA))*y_gdCQDAy>CG`9&f;Vb^R3H0{s_ZyW~0j4n0BMLjJpchVwuQ<@dvU7Wpsv z+30iPr7t1ej&x9G0%4hwpI7JJI2>~fmJ4fK5BE&Z|^`N(ReV|Ci>f#~C`);L7M{TB;j^E-rzqhRgp@AH3_~&A9kP)elTWmEB<7 z6Fz!hki4N^s6asy-)tdF)pVCjK7Uv%6QH2Lgb+n3y%3?fwdrXD;3Uz6ovVL@8uEKw z4ZVZ?pnFf=gl$m(>lSVS2PzJq~ z%1GiNPW7yB-qu;6Febch=x>u{&nM-d;EDPqj2I9fUXESLCkpszGBCUmT%#K%F8>sD zU#58zh_7LmIY?}E@iY4FnAV2AJD$iJ6XSVfd?K%p=M&@O_~LXtKMLDpQdEnRlN@ZJ zpsM}oi^@U1C_jWd6&|&da(gKu;m_X<$ZpDQrG%7Id4v)Q)se)?CCyjGX3V``FaXi+`}x&pia literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/bisect.cpython-37.pyc b/Lib/__pycache__/bisect.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0c78237e71db5b827fcba758c1d0e5dd8608513 GIT binary patch literal 2712 zcmds(L2uhO6vs(PRvg($Gc;|mors>IZ8f%D3ItiVH7GCxK{_;D+c+K!+N3ScwB(X< z;sgp%wEH02abHQt?Uci?`%ZgLik&uXhYf3iU=l<<@lo%Qk3awAyGu&}fy4jx*8Uz? zzv08|sDkkoT($*`AT1*5!WG_+v_-{|s0be{M=Xm4Q3cBtSHz+S!19jjf{L21JS2}v zyy_9@4+FDJ37&f-cAgOFv=$_7RfV%l!jG z3S4M!!DR(BnIq_sn3a?W=LLOEGgr97s$nV3$P0SnPH$yS=E8^vcwZyJ`-q%)8F(}A zLjwKZWZsGU^hV~1${IOwp5Ay&GV+rHqv_8MCBlWt`Nw}WV=GO{R4PYo%2dp>vMJ-A zG9C*ylyVF%W)qW2!ML@Pk%|Y5GiA>@8$rO}X!h}K3oA5|iz5sKG1M$LOB0qxk{LCK zQkL}3A4UnJo1R6vKgKd~&A1s@rW3XuT%03H=2}SC>OUrnjhau}G6PPMQFD7EO z>PgJNF=tmYE4k@KQZx#;p-|i7H3&VLKw|L6NqjSw1D>h_xpV4(`xM87ZXP`1dLr)` zlbGCvY`I^qC#>X@=X9DoI?0_#Feb1<~CIP>u;NFt-9@Q0Z3zfl-D5x)VfpD$%S}!6&kWwrR5pWI;|5Q zTC)uOui%5jx8Sl*pm{I&AkRL32IYAm(}{_TT~x7IzQu`a~dlvBn3D28fuxW|u%wOy<-&Y&+F?Rqh#&%&^$ma}B zJ{|)U79%2*NIV2;lv7`yhU`#jT?9K@%@4>5@23)ee=~|paOW|h-^j~?u|bRt0ued} zWyPSrgcY-ZHcFpa#0KTj)UZKz%Vr6zyj~(%a(EqjN)Bsp;P47~U*Ygw$XFp_84BR` zxqy{|_C^`|y*X2w*RXpZGNxsJu3~6kE)jca_ucc|H$H6Czd)b{?4uOn`aYQxa6yRz z&?U2SkpQIczbet+6L86t=pP6Xh}An&qOR;GsJ5tGbNc?LN>n>jB3$T~a||yCQGwwH z;0MxLk(6kSXpd*7dbzVZ zJG1JZA-R*`B@vax=R5hFy9@F-M-VR`4)?{t0f&6B1NeZ$As-ST0WP=%jr)-JfaHuj zBtU#Y0tc}3`~9oBx_fqZMM;$G1G0;$epOfftLk6>cU7MnA1`O{SN!3TxAy!-CiCaK zi2e@Zm8oQuqq0q>;>a;u$*zszEZ59k&Rof~X7U*?zg+g`oJ^(QWO|cc zQRThD&dhD+9p_3$WmUFPc&qT0%$u23_A41xP(?MON@`S<)fP3T#?^${swUMowO!q( zcBuQ+PPI$zR(sR~>Ou98dRRT89#yV-OzlIBuzosb?$W>bc5IJpy-Hh7h?Yf<-?8fy`wHw#FZ)YoeaP^|vgR4E> z19Ot8t{;%+599jt>SbKN>^+RgABQhiO$sRMZPbE>LdQ&TuQs4l2q!m~r_ zqPm3R%-XZwQ|k0>r*as_%Q!xbzCA9sv_4fsqCf9^w)duyY;s6>VbRckb7aRv)FFAv%KM6^sY66j=y%$J$d1rTWcwI z(QB@HelSxmm#_GZPRDDx^K0&_HNSr7WJ~#;d)`}_@A}u=sg+vuL{neP)Y~i5cx9?S zje=L#{KmD#jypSd@f-?nHro$oZ{oEdac0d;JE8Mr zZ~xg^qv&cs@Dp)oN2MC z>MRNgbEjT=H7p{jo;stC=g)*CTt9P!cg&f&_x!WbJ)D_))z>edJsOU(1e`tnd^l!L znI&PHbyRx(Tx+2n7UVSCey&yby%n$3sWmnDe(K(7k4^H!u}dA_ ztF2u0YKbcj5}s{OJ~Q{mqkH=G@-+{m8J}bPrP%v%zY#+aWf`~~XAD05HF&HZs8Tch5odcNQGgK)fYt=0Cu=yJmMR-3iDz21FurCDFB`M$R> z@MPC~t-c&IYr*2cgYB)_3TjRkQ$exBa?jWGgku_GOszTK-v9Xi4+7Bg%+G!*hoAl| z$jcRIJWn#2pZ*MZhS|{c>T+$80*)u}3&;|@3^+ihl2uM6huND41<$GccN|jmcXO2j zsXAyzQROfv%l`d%rFVE%rlImW!1}|s9enhU>|@n6KnPma$XyZSmPPH^?i+#7GYPrq0_l(@LfjN2&HAW~+PJ zTWGYrKqgP4g=xP4k|MnsbZQ;1=>>uAS763d1`)~cT=RDs9A`$;uBqv#W^|6JX?Mi~ z<5YpWQd@Jof#<5m!UBn0#}#U3-(Lh9ZE^w!^+izifc$gSZ(nb4q6$=+`nfg#T9;IR z#zmEZXA2;WM9%BAW*2YQz;jo9Pf4rPu^3MGfF`B~+(WKkYXG8}`v%`RL*lA|a;I=s zbA#@@Ak4I_!#$u$FJIPYn%IEa*6Qdpkp=4Q7C1xKb8j>{i}Jh$qLV1Y5L$si(_EdE zH8wi6`KAZLCA66BbVaFX6Rlji^Po*|@wGBKB(1g>otyZ#>b^MLxTuk;PTTojC z`k+9T_mx-A$515tE^%sm8GSDZ3hbY1x0-7yiUM)XzH?xZn;vin;jlR%n&~FHf%kS7 zUE^Wy#3d!zFA9;rffikz`&%~q7E?4{HfO< z!Fnzb*K0vAbgwsRhMPtLftmYZQO~D3$q)Z{BpIK@FCc^MWZr>}M`B&u2XVnYBhr+n zG=^w5TC3fTAdl~Lx_%4u*A-rgA?SAS%tFk@>6Z?=O|NwgGYs=B07Xy~rIT$p^g@#W zU7g%=EvbRD3@mA`&A8_}F7nm7O(0ySohruCi|Dn1YS@RG$O(;WwL5Omfp~_Ls0RU@ z*eL7)7r2SRpK-xqQ?*K8}&s%d>s?J?Jj%XYFuvHhden5?n-SL z!)62=*AqfOYMJgE0xg+Pz)CmhaIA&!pb}}P=k`1w%7pG>J3c9x^;lupTyJHyvlek+ zAQM}x2QIqVSz9%I(Fjt71dUF&)@igc!|i=aYxm8yJLgs)E|CU$N~rU6PMC675O~6( z9^pZ5xeqw^O(Gv<)6BNsnDo8jO?QQ+|C4BXS_J)1A5C@N+CgYVJ*G!qvp~a_=NGC* zkC^W+*xn+};~GTE4VrE6MZ*y^Lktc^5B0Rc)B=rO@mAXYTB?W@Oa)Bz1*m|UeR?-* z?0-mB3kIej#gQ9<8(yqKy zzORl;`M`#?xv7{!zlD7G~P(<%9WG0+! zx$A8ThD>tWfP9lpfugT~Q8X|&K#RTAKqOJ~5PVb00zF-Yu7L@)+VCJsP@0t!5Li-2 zO?<6h#p$DCSOaZAG#sv@Ra2@=dtjt!V#SIynx)4UR zn@9dQ>cJ!uD7Tra=v-A8XVE{o-d|fHF$)c|L)tL3n=EUK$pM+n`X+6p3B+tU)&OkX zLp6bAZ|w$nU_v9fKgi^?U3`C{s|U?j{5b!nDrnGe{>apEg z%j(L6zqt7;P24@LeT8jAh7S#Mubcph$X5_FQZQ35a1aY0+xhbfo0U}h0>^Kja zV2jYG1JVSd6hSbR&}`;(+cd_91!>6uwuB{)D+Sy?{g5U``C`6sc6xLuPxvBxm00M1 ziOH9lyvihIKQW6S+5Q9kv`M4@7O|yVEEP({I&Rv(9L`SQ7m$~w7{xZrC}+ywPw&>q3$pEVZ?7RtC|31B*c%*A2_XN*@a}v zky-Rk7Va1FimcLBIR7l3g2-@Kd>P0u@W#eOQ!@P!c{IIr#YWh6_azC1Zm%v zE<219nlJm#uFS1mpEhNrOWA(*PVQ>?v`RGaBV1eM-^$YVH3Gqkl4uGM4{e~Eu+>F_kh4{AdGEE8w%V} z&J9fOzeoZ%X|_?5p*E0$+NA^zGp4RUh9gYT)k1t;P zL%58nx)T=mv~V54t_0yfRB(OK0)3IvurPc5>L-z{g;wma5T+&T2*OQBF-f^5!nILQ z$OMd=3)cqngz-@|V;MdDR&3*h z%u5~C*q!OBsX-ILMAr8^i?!I+d;@-}NQ;NoqCo}eU?y#nrLlJnV?gnmc4+uUVXKUx z7z%3wm{z-WsO7;S(tv%JUbkzWZ@Z3OM2s+&5h){XvnXeyZpu1UcW40K-5QG zTY#ZWkT6AIKwD9mnDf%TGvh)+l{_h>%$CFXP+OpTOAugc`d~tB(5*41;Hmk&dk?yY z6S~B7_Q$}C%!jE=BJJ<7=r=ZWat~$4c5cTQ*!!0j^h=v*OY3n@_i$QmGNfRgy5!RT zNCP{)&h6M78*%HYs59ULH5PWbe&FANO&zng9d%}mEh)Xr-$-gWV0)=Jw3nj#?^5A< zoTGCWf&%&VPw|TtuCgdx6T>Bh)5!WMDqN>^6i)BEGSZtVTqftoQn;cyW)!aIG8)bS zhY3`*HVx(-?b#tgfpab8?OQJf5Nl`It(&V?^!`J=;vn3;di5MJg%xBrQm;(sSho2o zs#m)6j#=a#u3lMyG=-|_w_^b;WU#^EX~}35a%4sQHb181(=`m;?JO=D)MLC&p>D781YIA4g;QXKB^G(jND}g zKI6DW-G?FE=|6y?HSr65t7wtob+WnlZ)?)n?Z#c2YWjr z(=5lUi9hjBvjL~Hk+~RfDi$t=uR&Z%h<+@9Of^-}hiNaC*Gu&u5X?ov|$X9ym}Afh@_k-mIxpu17K<&5=xZnH21)#5>Z3=hD6oG z@(we&A1jI`4Zf7KE*W6G_W6O2A8a!ORY654kw?)p7I!v@qe%gu4zi8=2L30Btifc` zJW7W?_-|mQ%8fy$M5F6fk{n_9JK=x2KRJzJ7SBn~Kj!0a7QbLG64)n&2rM~wvan8O zX|Y_&et=k4ZSE7}#LKS4sA!9|p3w&asyt)^Vx2qq=OO|$E7yA~ z*(|iC4$nplKV^M|XbFgwxKyc4>4v3-vKvrQn-Kt#?i4Wz(w|7s!~7D$+Kgd5%+nJ& zFp^Ho)NfpSi+sctORGeaenb16V%`T<5b6y&NX+DOhZGn+S13AQn_+(T~|lG*UAZ5a+3$ihL7@ zClP--l%bkiZ+h^FNR0<|5i+R&GU8HNi~>!UvEU+z+C_+au&66yxFt%aW-joFhDARM zLAkNmZl;0IBd8UzdK;Siy4D(fY-1z#Z96>W0W6d*7P%?q=(Y3hNkPRWdIS(-PIpQl z5%5??^h6)bSB{wvvUgy)N=ZODJ!KHD?JbMaX8gLCHVX?NMPZS#@O5thrTnX??$-&d zj#!>>CJ}|5!Y7uP0u`)ZV-jPIDHYI-ahtQn>AeDb!J-HDO}gi{(ZBFQnK<7Czr7+o z-bLJ?-(1sZM4=$20+1z1$0DaR1JT0~h=sLI#~%Pa+)`!C6Q5M8zh(Qo(A%8?KapwU z`Ow$yA*lf%97VN*wIN0v+BrfTtG{jQa(X)l>M~hU+LD!}M1Vzaec;&PgG(xFh+Vze z4!nriGj z{3?^LGpR9IU=k}lvB#AnWQA~0SS)4BdrBktA1fEfiltl~_v{~0=LCMi-$4=yv|bJ( z?4w4gEnwvx#aen>A2WW}5v;^xXpV!>oPAuqC*mwt@QFD4I9KuE&K9oZ!<{j%=EHH^ zn}G0(RegB2l`H#jZ<4F~aNMTKK-c~L9)Pil@H>OYY2lZSO)!ew9eU-k++Yd6YC%yn zE^3BRdk^EiPBb=wWS?9##&jXU8=$#NSzOa&)uOnE~nkPV9VL%j6c`bDR&#Jdl^?3Kt3eb8@OBepm-;9E8iN^=ae&VG51J6k05|TzYsvSUE2xr zQo{1F%+ja`+r?WWSmOHie5O;zqUXPGGPg=t^n9wH^Z!)m1T>|kEjmyjey3kt8e<^K zd(N#dhAtdEeS+h=cgwMDmf9Say~MjoK_L8C{1P_kjNoaJU?1uaDcB~H34?z+aNq0yc$ zKh*=`cfbN+O8L@5WHUmTbbrO}ClV}5&xoaLEUZDKV^EXV5pNVCmINNXye4{I)=y}~ zHwDO{r;}}=SPlT_RMJ&4{%NI)RSq~t5t(pFu@6$kpnkf@WH}0&0q59tdQxI>-xRml zy@rKr62^|`r*-$+@w*=UjP!cBX8qG?@i)jK1XM_cB)y73 zyT_<#NJ-EdQ559J6+~KMF$e$`nOKK!%BrGt-c&;c{SZK`F$hQ|?_x5Dsev!*a-w|8 z-fG9~!cW*_##B*Uc_y*ITF)VN4>bNVic4#8TtrrLulb&**7R6m+5+vaVZHkbbTm<} zl73QR3eestfqHb!kjnJOxT04h6A4+i?v50svP?%DyOD=eYzeH4Bf(Z*gO?N&*adF|AT%v{$ubSVzk7RjoL}=V`P%OdWqYvh3N}mo7vPl_piv_2>`NHW?HyuWz?w zZARP2FJsM0iFz}t41PqmHa+eye}W#%%+Ggw{DkbJf) z+nUtx^64(>CWs{bwi6s3Y%2s3UB`$%rh1};b?l{OwBG*~%E^CFMjrGVSvm!uWXb4* zkz2V|zF)ePLzxA<^FBnK-0~>S{#Bo4d`}?w-Vg}#Y8-;oJbHKHMF>Q1&qJ`_8vd=l z-^XH2Od?QbO((5*pvjsM5;*G(4;`dx28qS&GeFKXbpX2+Vgbero}$-bfC}-UT`fS0 zI9M zTV4fQd(;#gs7dF}(a0T=OSwqW8yke|qn zVH)RUdSeAYCiR4q&+l+{INM1A@N6Q-mHiXh?MO>GkO}0?;>{hH{M%6mlmfh!%}ye> zeu6dg#*#r~FvNhhTXFy~Qd9(y)3@V-wp+;7m|!rQ!6;2zRP7S_UE>pNQ7izgCK9WR z@zL;0jaVsSpGLA3iXeJ<$N*ZMN4f4ix_B8GD8|Jr6Ja&g9MLS2hB;j0XIhjpJXWL% z7SO6UyIfdnBm-HJ0&&J~aAj}`Mh+@CCPJT5Xsta+3P=rvAtp!CWxVJ!Rm=@6zz51> z?T1}aPeF$)@=$vLF1l7y3I!q)DFsI(b5$vVL?(d7voyyDM~Q_p2wx)-aR@VG&;*SI zZD6Q_l&y}FM8=v?4o3UZng@t1h#j^E!HDO2e~#gXAo{Tl*jQL?!L=xQQ80(ib06x!=G_@uYYPQ6Y*C@xgPUOQc3aXrADSh$*tM zOJdxOHlNqhfzSvc8KfY?O_yTPTVbb*jdv9D(7Hx!x1-xOF-p_I2L_NdN=HU$9WS}+ zUNZ4iNlH!sk6AYpbz-6=?68kKUVMpvb1*)L-9apsUt;5pLEx)6_erA$sF;|#dlvT! z2zNJzZqo^3=q9b^A5kuac80{jD(_GB(dZ6#8`Ex--m_?ijb#+MI$}e_cQ_)9-8|AEQ4UL(bI8P>)brW62eg$sO>D$yO*^ax+qwkI zK;I*mfLO(U%hobT%B;V@nwQw|>__RH&71-LJaQS@>eq4ZD<&S3ftJ!J|Bn+e3=WX? z0e~=^LdNKj69Gh$vxwrkEI&uP2e$hsSj}-J+>XZoWhRSEDA#CxL>Rz3ynL4lr=LtO z|L^ncA27LF=fNIi{ujW_fHbC*&BJ|A&Xq5ezg*s08pm=2EI8QMjqpvp6S)yov`y4w z#(_|P+kjg{(Uq`ImTn;;1{?ZCt^_&~Wbu}9Bw#y0TyNo)fH;nETRqiVB20K& z7aVaUI0;9>qq6zkcEzonp70+8Ks5)=F_9`7oSFadAQNEwoMU1T);HFq@;n%P=av>oS$-SK%0s9S}94>R71@jf`E&ydth|H z&L!Peof>g$tB6brT>8hH;{Tn|J9|O!jb5Oj053QMrY?e8kZnbZ; zw10)#8~=E;6k-Y&*1zKP^S8;&xe_Wm&tmT^F}R|0v$c!t*TJBpp*=jnWsKfnqchFm zB!iCz-q58U)V}|CBaC(3NArQK%=6-&BzsD)O1>oH8~${@#Ph9?)-FqrZ@$R9J?^58)t2?9f6zx#q8+ zU=cwhUMULC09_=7`o5)$*(gRrx4=Na_Rf9eno0IHtC`P#kf?cB+gUSZgO6M}$!%2m zZJZCX13v$wMCA_+>G-Jf4P@*xis(?mpb;n?y^zz>@k_|&6Q~V_ zn$Q0uLCNEUfzd;|0VHr!HRO4`JE(>LAb8_#l*|zmC36J%^7=_CPNtC18ibIjZR)R>G1n-v(RUt|w}8HnK9+G!T@u|b_|MF__$ ze7NqE5>FBJ0v#af?$xjF)iU{XKI`X7xIn`4ZqAOZe5t%m8 z)^pnRr33m@19mHF4+r%iK`y0C5gR%-0KisKgTaKNW(*EB8+5YS8xq45n_qE(PLqL! z9oG)K{|(@h)-6VG#y=h{$9@(UR=3bv1-&A9+$)Nn0iTRL&xy>(0@F|2=RtR7NVbUZW6uoHTz2+wxZvwWn-GF4KtKE^M>#4FXAfn<~|hEnz(C-BkVo9%8= zjf66(gRx<0#p+j#4reVQ++n6pRVVi~g~U{#9ZbBlnBR>SeE)d4+gUhtR2o8X5*Wv- zH87hj85zhgL?YF{qVm<0n7|Dd&2sxhV4l&tUP|;>3U)ISBBgON)i15?rAkRMS!t%e zVG6fUa0dOn)W4z@iS}W_XzPy1MHJ?=3OEw0fQjANewELEEy^?~^imBR!CcglU-#?C zFM5Atd%sMl4YWW?iTustXI3C+<1<30U?V^<7Sg4hU5y~Y$5dpkZWym6i0o*hB~m~S z$HZr*k!8@=C5q)fLS97HOm@tP*AZOQOG~wL+DhvwSVcm`uI0-me}|S-;g-ru$d?$; z?+X5RQ1K@4`@hcT16l^(nI_m}oMg27ouFIyitcXG>6GG`f_@6G#!wII=cPOX$FlEH zG0eeks2!d#5)A40q=U%6jgqxnXc+MC;^~pN&&vedENV#hd0I_D{uoDGTtrIiE%>T| zA@o>l3?a^Z5>+Zso0NV} z5kewc243Gd7E@#84GJ9=z;!5zRXG6AOda@lF|b$|VHYChKFAxNZ?wryK?l`5PIw1^ zHakCwx-3KYZDtynOjMk|V22LcDnK@?3L< zROVku|I0;!EjU@|?TOf6MD*>#jg-}aJt)0L6!>r#l{jGDwAHMm8K0eoc{KsVy7{+> zayeY99H+czKSdFaGh)$Rel$(-*GK#rM z{*itG9#wGl+lY+nP%TmtzKvRB~=%*!da_$7LdqlpLDq}BzT6~fSc|0BSD*Cxhrk%$E`o!V+-Mws$-|w z*JL|%9Zwn1NkcJL>yiwHr9vQ}bpw3U0wD?Wv5pbd1xLaSuh~pA^YwVCR#Ah9>+yoM)S=M>Ux-DSfDc=@DC)yM%z-3be0SziW8+$7iL>4 zP>9cL)vGra5ECP>*xPz;<)K-6ofJxF{)A_7W2E+HLO$HtBr8C!^LhQQ>u>j|#d zU?RfQU&AL=5T=A!_ZYQiY?E}SNUU$*B1qns1%QNA1}VzNknzMu@U}!Eww_fsgbP7W z5eZWJo>P@v;NKV&Dp*O4d}0SqG7p!Wl7z}KfTM(HxuRp^1Zce(V6Z;AmKiQWDD5a&wT*sklDzQ<| zK#OvQ62~*>l&rH5GG>E-1T0ueZ2O0RXq#!_F_EgYk&v=+)^Hzhn9yV-Kz?;GsoqM= z<#T#yZ6|OxakWVl3!D1Lg&2cu)&XmoU}PD4{>`^$&UW8%VGk@SpJ9-Z11$nkys>O9n7$-F#Tz^h=u9-Zz&B0m;phq zflyD4|Go`SNucXRe#D7(SzU{crhr@_T$fYGmW__*Y(U>Hv_VQt8St$NQ`iT%Vd@a7 zKcFc-j7PuEeh@{c^cl8Wlh04J-H&hFZrTmLKcwC42L5L86I~)2Zy03|E(uZp0f_m) zfOl|Bmel*-_W%dZ#am&Yk?rtJP!6MW2JN=@0zd4;G{Tl9{4j)jLF+)rXcH9dz-H>v zmnb7lH2^SxRj}(BbXB+|fucY=qFOj&Poa{@@{op(jEynk=3kY}o z7R33RZa;H6^VQujiR7_{r2uOumWcT~`^7iFMBmxrr<%}9ad$ICbH%|&etFcNBK z(UhyZFMNC_f6eX(tp@tSg6>D5!QP=7JGv+&u1UuY_a2+lN3VG|^%UifAy zza0k^PJa;t@4L~aa9qSCT|u-oUp~{wyn@XMuG^?z7a-mjJ^@bsPE z%)Xt!l;{kEMP_FXhfZUle|}OvPAD0=^71}*6H6^-dQYrx?ac9J8@gZc@=W}Sls1h3 zc(i1o}u~|Fykl+qp@=ipi^}$Kuznw=ANN0>~?6Y2&MpO!I~ltfy^AO zZ7WI_Q7PI!hWG&e%`H1@od!M=D+{#w5@KphSx|c85uIaL(G(2_{Jbqbe5Wg#jyGdL2Q#e}lXO7a@xn)Iji3}VVw z3T77ps_6CAqc1#%k0%=~QyQO$G>;md*h~?qdbNA_@Y6NZod{sVM-e;TN-&)_YrN5< zDj*G=mC#uZo$G@LvrQ02gin)oKkd|@Rl-5hiL-^F!U)Qb(n5wi(SxNY5z zk>MoG7Rir`hg%XmEpl1Y3btCWR(m7tA_Ru?3KA9qzvFMBj=9*~z%6G_;TE`W@^D;# zI_@74pj@yPR7R>=BoDXXLy>L2BdT8|cVlra+;V9R8$GPZ9e!#VRup_{nY6|qWkPP@ zQ?mBAF}aTkEq383qXy)|nm(C^zm*BqUw;b|D!2YP6Lyq;n92Q2b~5=2lU+>am@ukV zwtLmvukPU`PZlzdV01ffN(P*3l|AgERItu)>f^R!vnk7&}==m{Z2}{Re1jQG!UuG`_ z}MZ_=ST=L}$laEfE znw*;4JNfkF=O)ih{_RX};>tv;{ABrwQW^gf_{R~kk2`SO#WlpyKkB8!%KVq}thJOc I=O%Oi4=v)(NdN!< literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/copy.cpython-37.pyc b/Lib/__pycache__/copy.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf4d18db528490bfd9835b470a24e5569c3e123d GIT binary patch literal 7115 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/copyreg.cpython-37.pyc b/Lib/__pycache__/copyreg.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e198c699ffb53374ab0cd92887ac7376e6f9d27 GIT binary patch literal 4258 zcmZu!O>f-B877AxOHnIXmSy>)Ny`>?<4tYB4T7c!?ADIsGzD74u$|aeRkIXlR-%?7 z*E6%0R-h2T3VIBBPK&|{f&#tt5cJqX4?XoK@D#MC0R08MxX(M>UCC-z8ggd%&e!|# zywAKdGZR|)`Tu(3S8u&yS^uWS_!ppZ14aD>4{ohk+~$ls+~wZ7w_<133ghQ^i`$>r zD-I7h`@~vthk@{H>w#4)xR&sHp?uf2=M0(g4D&nG>6@o`u5#G8S6=frp6-p;XitlBY=9E{)a%r9@ zCDc+_`^^sO>9mBj9HhFG^$eDcCu`JmQf!q^#gU%VX)Y3Z*b%2mx*?WR2Zo{_y{X(n zQJ3-1R%P$oYEIi6?`L*pYgSp;tcr1~HzhA=r(*jyY+*rnYfK?a%T|^%I?L#G1q;!v;FeN~>IpNnI-^nls1a znOA0y96m1B{%px94EgW%TW_y^2(_uz+shw4ihlUkDi^A!%l_&;ous`Fo(kE`%k3+_ z$h5e5=jW?=wzis<{h<`=OL*Ftqm81BhuZ=Dxq+QhKmF)UTQf>pKm|&&jw)%aj8~6r z?;Ethq>sU}g-6G({c>$nq}rUIdC>Ak2aBjE7Y_?td1)IHTg~AkZDZ3$VO{*e9`sZcCkF8YCj# z1#LaY>Ie3oQ(UNQs#olQ?Kzdb$uxG=bL5ZF&no!L0kf^j8SPO{W0txV$A#FA<2s1r ztjKg6!%v(vSGBvAC{cR|3N2~}diuYu$5I^8bqCWavLNZJ&Du8o$unqYWVqCv3N6w+ zEp1NnA5%Si?Z>*sF>W(hgnJ-%(7zAu7%M>wU1!f7hGFLS>Vp{u-{2cRm`!=_pF(cpJ^C5qBB>#^_9&7u+O7@TtGk9oK-adLNUw)-$D!1~x z&^Fb`GmL}!%U_cs>Zv&H=E=H>x% ziYDKq?M!c!gVC3)SjVSzp^fe07!Xhp$^i@-Z{wZWdiEwTO%i4_Fo4C(3UCGZ#Fi|n zvXQ7nYbnn)TYmrc%{%uW-MMXC$Al2MO_6K~2)BGfh?jV z$}{9<*o?wEqWDpUs3g&P_EZ#&*+6s1VutDzLU3ax5EpJn9kLiWhTcG$Cz28+_?*F@ zgx%_Lq{?Vpm}we}Q5mw*Fp|waXxJfyP;{DrU5cUyqM;AlN#2Wixm}n!NdA`sK*OWE zLY4WzFpdu-2XCW=kqlBKivq=L>2PiwRe9bi<*PIx%+#1p)((hb z9RiA_RuqSIAPR13G9p<&hd|b^{iNT=7rBJaj&EYE_RMzV33RP^CKuE$b=83x(--`B z1cryF_zgxih}doe0bPf%jyY}MUs&e5fv^-tmtpf(ZtqyF|bba6K{f4%C3j+vu%5 zbLl&>idoOxE-04%jxyo|#3vSrbn!AJ(iO+Jv4J1ah2C6?%ymT4TJ_X2qTdiUb3HH| zN`8j~iNi=@7bex30B+P{G(%f5K4Q)(X$Rl5wK}-gxZ6)iLJ<_Xpiv=nSr`UBGaltT Zfzx(_Dc23Y8#sXw#HsKpl~kq5 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
fTs&M%@_2B{B$G`!jgT7 zEd6r8ZDguVNNWM50FJ>&7xy)I99dpvgGr`@pXR{I=SZN!2P*?)nX;9O>oSh$-{UmE z%!rDq#{&tv(JJJgbq~`jUUH{>6q*deaX$P61XS4hc*1Z0oWmRxDR0$F48p#IaBN6c z$Yc;uQ3rY_rAgyuIDxlb0udGPMH^}*jC1*pQRBN0gRv=#*JUKwd4kE3C zTSdK2TE%55+M8}wbW(3Eg!^t^>nx!kI?H~1tCPha{96=v-{x)&H#ct% zIUNrfB+4i94$bDx%rZSd_gBBitSk|~M)$G}{jCPOD)}Kbguz~P84!%b*SHx%BaK*1xFy@cHGv;yVQljUL3>qi?G7jNcbR+_& zuF#i(w9R#O+nj|ailM|FW_I{_z4h1>4t^hI|L>6RZMI8m6pX-Ayf=SRT#U5>!!aYh z(+k-U5{IG49LACUM9VnLcz7OV(`0RY=rN@xzb@dZPAVY>HS9>!rlI|q-9G@;j wtQnmKGY-SG;PvBQ$t}TwP@4LTV^4k6;Qxu4uNw9Ye1cP3GtVN|g!{<<0n;*DF8}}l literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/fnmatch.cpython-37.pyc b/Lib/__pycache__/fnmatch.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc38c9d3b7f78548aef8c8677f4cce0673fb664a GIT binary patch literal 3351 zcma)8&u<&Y72erjT+*_v+KwEjMX(NPmozNGZc#KfT)TGcpf*y)h!v-$s0yo{p|s*^ zmzo*IBC+yC?yW_A4tkK#Q|~zi=s(a?4?PrnY=NS_=BQJ@H%rp0;X^6y?CiX6-n@D9 zz4zwc>C+7hKmVUUT>aI8W&Mjjrau>*pW{*6Xt>p}IOBH8I?TN7j&0sf$1!iW<8p_) z+~fYH+wpjfyDzMcFWl`K4|tt7esA+reC~yHz&Zgx%^gVVe4cxFH~1Ou<9&+TPpsBL z^e1LnA1A5Eq8$WqPIe|CDJq;L|O}(sdl5$%M76T@xxCZEZ_a*gKOdA zyDKXXK3i^8GldGHIL;*}6*>>~mI%{4j?ysBvoA%alRRrrwZxGUZ_^Z|&!UkEb<~GC z0)vpo7;v&R&UXfI1)qY$*I*U)av7?D5c~}zW($kv%o|eZAzb!)*%O)?a1bmQ z%Ppt_P-EK8rffv?t>GzTpr%~1>M^T=dbjVRaXlt7t+J$w*_NRS@KGRNN73_dW!J@x_6e~jM@Y$AtV`Mlz@!2^~ZEiF| z{2os@5=K&lpJ&P5ggZ))QgO4wTqPiWhC=qBI!`ZssLD!?TLDL{v3WTI_&tyTb&eptCl> zhrMu=55a}(2RMW%)0mg2YvB;#aN@+@5cGF~| zJF%lZ7)fH-IXucoW1X2}bL^Ex9KvF?ooG+N1Er@&1Hoeqn;+RSW9BV z{N(5vR0%9u09PJ)@g>%HVeQ?%Z9ycC7`E=>S4}bjAr5mkU*+{@1 zrK2py${QmsROu)!rH7SDTZ*zaiT2Vn1ZlaF(sQQ_An-(@!h2t~?X|oQEX}2H9`+L7A ztozp5;=Wrrg?qqcv#_yg_lPlTxA}#YHTSL<#QTJp=zR<80jhwiPr6wFX>oijhcWO+E!T~nVv5>lz|FPKPD|Q(z#aQ~Fs!jD`4*LhzkR1UY9y^JWXlFp0NJ zex|7W-}tV=TVt-=9PXghp5%uk95iB(BxgTcpcd1g=e%)WnWEX4amNl%J#y^%x`8=M}9Mv?*0)x zB+Z`u8&*C=E5BsB|0a72@3%H=_W4}l_iOUo!aroVxy&Eg`+oL2L`scNl`XJx4tqOu z!OHx}9)rDmg>`82g(4`tBWFJ-0#Jgyas9DX)DBH?D*{@BVh7U7GXeh&tO#JmB5a%D zj4g!Y3x_U0%g?=l>^?k>Lg{Po(C6p*JB5#R{K?)};q%wlea#o~?eGh<9`ySeeUtp% zz7L!J%1;+Qjq{6$YrkhNR;S`Xca5T(JVO@o_X=mx0OqT78%QF+XkUO9NrI7@@XSw+tWXbNlXJus0S;&#i~k&U;_og@1x z%EYeCUF^}5-v^L%O3J3_EFpSIT7^emc`IcHPioJRtEpV>e+ z(4M6ccGdyjrupa_J@fWi)|xA8>+3v^*Vn7e{w`Lk_E0xh>pV{tL83GTgbuc>r*gP% wZptS6o7`=#6Q-b^*n~-IrbY(0c5*&U#cdi=l(StJV*YGY$8(E~U?FJy7e$a_JOBUy literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/functools.cpython-37.pyc b/Lib/__pycache__/functools.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28b2e0982d5736db229b41af7596108a5957100d GIT binary patch literal 23828 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/heapq.cpython-37.pyc b/Lib/__pycache__/heapq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7dc5bd7aea37957a416af435a3de269a8a57ceee GIT binary patch literal 14376 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/io.cpython-37.pyc b/Lib/__pycache__/io.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81aaaa05af9707d079477b3f3f7b6f4212a8c5e5 GIT binary patch literal 3423 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 xZcyWH39otnM=U|3BXiSp8I;{tahw1dIRx literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/linecache.cpython-37.pyc b/Lib/__pycache__/linecache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79c769a10458e376d9a3fcd815e8e698e9cad8a2 GIT binary patch literal 3803 zcmZWsO>f-B8J^+CE|*%#@<$viaGXhi#$Lb{lmKlCLw4)hap59W+(?ccRl%0p;Y!qU z$<@qklohxI3i)6ZMeCwH^e9~l^wMMhK>tDy1&?hn2HZd3OZ&XTT}g4cn&C@w=AD`M z<9Q$bXm&PaxN86U@aMa4F!pbHm|iY~AEN0Don-4wa_OXeo!h&!?%2D#?%KPz?nzgA z(%*8|eR)RKr2CYw*Af=hWnFqt*?J)7Wgr`P+mL5vD1AtwJSS&l6Vi;Fm2()?l+G$^ zo!|fa-Keu2i!{k%ExIc2i-#k#oo7PlL)D2zH%Vi?7=~-xi5B#inK+ZN6ebrcj^yc? z{ag+)S|t5Jt_;T9xFNRV3|f+|h^(qC>c=6}WVsRDe3;4WA~9kwNmG&Lc~8iEFB1kE zs&ok*N2;?e29epucs0=?Hbko9PfWsNqL<>g#;uJ%@%Z$_yueQWr?Ff|J$uYPd%=Efr( zE4}gY%I9B*4?fzEvF@3Cu(4{QPVdvNV%1Iay&In-Ccg9V!A6>FqGho?-r``S9B4U% zrUP`0hx{^cIvtXy7j4#_n?@jN5N$Yxv%hecY-UYwwTU=0iHg(F;!2B`zI|smd8(U( z3Ppyzf~IM0=5_2161}H2>|&omC}8GZO0;a7{;z%<8@p+1$4Q8MJA$jorns^PSqufPM*|s|_|%aR zr3glu$2z-eL?_Qolw=~x$QEj3l^aR}@~VhZ3jfif@^Q8obn2CsugLg{j$O_St$Mp& zIrG!FpR3WwO6AI0tmUc(4V|H(zSaM_Ve9zx9W;Fo9rFSn@Fu+Jz^ik-#ua_;Hi`}Ksobe9*qISf`^~Wr`3{TbIsb5b#1x>fu-qIH= zbDl6HPJO4|bM;~2K?>mUC0gqi+g*BG1)#hC=w6~bk&=~%tjQB#iB0oJ#UdXXk#_~T zta9JADI^h=*enO)3Y5Hz!#k!}}D7`e%#=58UdhtkCPI7WxdfG&$tbe*{ zy;Ih;Y3pP^E&~XCll0?OV0~3KrrE63c~}?|X_#-vs3yG$y2CW3d{=Mc@pXq1?0gqZ zzmJX_I_JQtj^~8rS~#|eyMy1Hb#TBh@Z)TvI3b9z{{1JsKFOvlhFAGC$)qdvbPG*= zuV9CcbdI>X3CWc%Nt8PUa&I(my@#)3_c43Uvs&f9=UlB-9>gfm)T=yH{}`RCR*~KU zJ78lU9>0VcfvI&Jc>Pb+9C&*f-u9)B82K};1uy&9nU6A6e~K@MjU#psu~;}=k2Ee@ z=v`nkpv*VkPIx#|Fzoa{H2dov)7%LWn;YXAc0gZe3&h}&Gj=91H)qb!4zTYl)gJa< zRxx+_gb&$cw)^tPnlv#sl5 zpir_!B>J(|(N=t2$Vr|ZqhSSa*DWTVT7_`0KQJS^R0VUd`0^`$TM_82977L5ABFZR zn!bQ;3y%G=IYuRw>`nH2XV=5Ac*#SX5U7*R;u7U!7QdDuufkEI=b9anU$>z{Zo&%Hj z;*3DT%Lg%rQpK;*sjD{u~|i13r&xafy452WXkc&+|e^=kTjJf$IT;-g25=6C;}T{RObkS;|ehy918pqgF!vh6?#irjtm|&Cm1~xhBvL#KZ+d!x9TXgb}>B|4YoiSvnGXV7y{V1i_fCA}U5PxGt5dq~DKaf-(kfRV{4#qtsxEoT#{2LBmb4riK%`O)(8p4T_E#D&9i2&;&5}6U9~1(@}HU!CsC5drH!SleZ`4ASlYE=nsKZFxiCe)1i({KmArg zU9_3T$BL$7u3O~$_AD|bIijLr6;#3+v3$z1^01r`=Y!@J-#I z&Z61}kmw^K4j&0YtAn{D5oc7Ct2TqJ+EeghH%JFsO`Z&Pk-!bpM%`*Q#ZP0tPL K;e7aZc<2AHN4*&U literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/locale.cpython-37.pyc b/Lib/__pycache__/locale.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9f75f03ecb713d29d2c9942b6804d626ca539ed GIT binary patch literal 34569 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/ntpath.cpython-37.pyc b/Lib/__pycache__/ntpath.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..afc6a5f8d2da3e11a248ecf6d5cb627ae0814773 GIT binary patch literal 12933 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 L?1E+3=x_WFwK;zm literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/operator.cpython-37.pyc b/Lib/__pycache__/operator.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f08388532422b91cece8b7a2024128d25f932d57 GIT binary patch literal 13914 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/os.cpython-37.pyc b/Lib/__pycache__/os.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7b779b98f5c798cd0010ce18348ffa7c5e96172 GIT binary patch literal 29707 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%0ANE`ED^@o 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 T-q-Bs?c??y^goM~MEQRKl6;v& literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/random.cpython-37.pyc b/Lib/__pycache__/random.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..195fa8cc90485ef9ef41f67455f8a263d2aaf2f4 GIT binary patch literal 19370 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/re.cpython-37.pyc b/Lib/__pycache__/re.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae68c9cfa79456f2bef084128d86bbb302c88765 GIT binary patch literal 13818 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/reprlib.cpython-37.pyc b/Lib/__pycache__/reprlib.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..474c4538c94cbc41578731a79bc67c772d5b19cd GIT binary patch literal 5364 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
7KF}V3GS@q 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 TnatCfeVI>VMf&i(YZU)Cn34&8 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/sre_constants.cpython-37.pyc b/Lib/__pycache__/sre_constants.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a792c7cc1e7e237a2d5d707b00abb51f1e497531 GIT binary patch literal 6305 zcma)AOLH5?5#AR-5PXQFB{yjm9vyv{z-1RZ{?JnlxuFTN}R7}A6S5NDp>ArchA>7-7~Y@GhCgS z$x8U8|Nh=DX3t5|KZuEbb0Ai5yK9OhG0BjaY{*PuYFp{3hT72#O_oX$(^%>oiKTdI zUp3O;(`*9#1fKw(;Tf*7%)Vl%Y?5Wak&H<`$)@&YBg?aFn$7%5xg$X`3&|ATNARBJ zGklgG;d7Q^%!6J4eH8RD(8ob9fBdYKLh$KKgZAW3tR{N2Ix0IzXkejzJ%)? zTo-X&!j4C&Q zVaxl7mCe+p+_l{cW!vM9-E8Y_zt`(Jp5E!Qew*vtT}O8vZvFc&@5`@g1?Cig@_zn7 zt+-jtHw0O#Rkt?lEozK@T1dF>fZ!6Ar(`HtrYciFr@xc7WwAUb4edKglZ+IcnDA5F zak@^^k|nA5yv2K-)wOl-E@#3I%l^9AwwUhloqoIN==^!l;jRmmyPVDH_~kv%u^#t5 z?%oOnB<#35xAevnuJ>(3(`kAh?1`@Q4%C}FT<8+CM~#jhzz=p4wGZ)KH^5ppPHH$^bpO{}dU$1L3 z%ihtwuHNgqKcd^}wj))L{f_(IJ*s=n*3;_O z+}Un-pIzOsJf7byKWbZ#AK|k!TUh(>(Q}u3FPsJRu!P$^i-#nq#Wg2S%UL! z8TptpE$_~X<-Z(zt5hnvG-G{HotN85wDy&kSk72L${v>CKsD8Y3R7|= zr#bULIjFaoD2xSvhVV5CJg50;tL^$JB%nTbE)eV}9#Nbka1rczNN?g6!AkN1=3w{K z0Ut5)!g`AqCjID5cLBFh#qy`c4Xm&YO79%MFSlNPT~F?`==Z?`SiqYQnwM0UyZw6uHP z>@=V9Ru|vk^6hrF)oiG-8rEt9 zi?U*_hJ4gstgKNJUa={nLn9H21}V}cIPoLaA|S<<1QI_2Z2lUlU!bG)Z?2U~<%S-! zG=4%fimGqs3&l~C5RIZfuh!N^K_nT)(2%Xxiuq4Rfw4IFzGHtV)={%T^bH{$15>YC6-0*PP;gmaptFcX;hpj6*XO?%s1aLSt_HEtrmP2<7U2K@G zohP1tsg=`j+`Re0)%UJnzd;Tp!q)Sv=sw?W>jLW{N^H`<<}5N(=Ug25OnANA3Id`d zvlSjS=>&_vKAkcHFW?}RYaCM1MrN*Mv%ANm>8{s`=KXxBT%aj8(!^Fb4HfU*b4kp- zjeN;$6z^|tpePY`_rihZppX>u^#E|@007@?ej{i+f1vUH)&>eAWm2+!Pu_h4JTUMQCjI#jOQtD2kG6O?*F%!RMf^ol*ML*KYR8UK4i9Atdevb|s*Oq(QsqPj`Z z*ZqlnBP0szArU&_&qkFpm?eKIQ6l|?1QXUJJ0YKkb~u+2bUImTjrk-eva6pCN~bXuyaOR=#Vg9Erl=wsN5GK7k-#TGvOXF| zLqt;OPX!+9D)tx zL&wR+nB$RIAs#wO;-T}WW9K7y+~#Ky0HpL$`16$IMiQETG!_k$n13V|1`FC>hy}x? zH3S6-%AbotQGY{8n27w@7$cHTf)@!V=sA&O0;9>ql8}VSBsgiWP(IMQJ#IU9KsvXH zPxTy17{e+Z|NFqt+z$Tla(5a)_m6mJnx@R9=H8f_$|{+R@@`trs!ArUD%0tdCTFz6 mZ%rOvgh^iGJla&zu4G|vTGnRM$}Ij%giD!~$1Wi`sr(nj{An)$ literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/sre_parse.cpython-37.pyc b/Lib/__pycache__/sre_parse.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4948b17b726029b5c8e1e3b2abb253021c62558 GIT binary patch literal 21371 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 F{|Af(FL3|> literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/stat.cpython-37.pyc b/Lib/__pycache__/stat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ea760560cdfdcfe42e6796dc2c0f908e5068e4b GIT binary patch literal 3887 zcmb7G&3DsC5?3pV<2au{2pl9f zulYaxI3`K|Cgu1ygu)Wu-c4DOK;jZG&Oqie^za@~xB|Vr7h*gHeY_9iJP!T59}+wP z12Fg(i4VXK3}ZV8BYX%(`7oU0BXFLN!UcW~#`t--$S=S+Ttc5QxC~dYy$Dxf0^4zz zglpJdg6nVt+smNBSJ+;Gn{W%;t8kl7z!aZ!Ciyk^nqP-$egkH>3Q7JI+~GG-zlHj3 z)TiJs{~GS`X_)0R$T5jr?;!WP7{@(~XBO`{l<#BT1GGOxzj^fk2DyFoPzJMzsH$w`^~idlFnq?Z!+{tw*Bt5{qD8>W}WNk_Z(-s4nH8yMt-#fUxXz{ zVV0g^6wfeI-(wb@V^lxjN-SZdDU56xvy;YE$zXIEu1FTMu!0#~#cb-BiQi!cUtsjP zgF#@hT+iFmy3`m~B&V>O_?s*ynMBv7)Q~qMNLx}e^QM_@Hax%5@V)!B{YKSyQB`YA zp}Gy<5iQ~PZevFkj<;X;J+)a=o8BDy`!h+k(g4!xkvf-1So=FWj^{g|?t7ITXHl(* z=AKGs)!l0~g|FU89MM)iVg$HFrK27Kg`k%pM$ktPC+J70k~96Nr7>x|Ju)BS_Fj@O z4Easobo_nMQ2m#VN>9Qth%Bi!x9&`P>RuBZ)R9ZI(onY@)pLAx`yip>52L8QM2DH= zT&TPM9g(DeNJ$nbG)xTO!$SCNF}=7|@*Lr9X@#{-_2H8(aJ*f=+1j%FN_E%x*%7sR z^VMw5^_^5v->SRYTaT0cT8PFs#fKks06`GX}T?uQy zOJ)6t>if|zXgFFT>#w9Pkg5`3kwHK7L68X)f>8oh3RwL&HXE?*fI+~j0c!wR(?HyD5Ioq$!~k!Du>cx&l29d zvKTvL@7SU8cgCcm^wZe7L^?3ie@d)NAit9jQN#My^X4fYtauvuSj$eFKuzrMd_kw` z@d4Eod+PM8c=bB^PtS=d5IT_J-A)D=kOt z@!rsb_iVd9SEyWdSM~VuTz|#sJ<6ygD=fi=*&t#}9%kYZ_TjO|?i7+n&{r-)vsy0m zKFcoC$;D$R=mjHeGuj%Dqh84Ag%@E@Nza7s3br)F(zzD8q-;GON%{9unxydj3(LD8 zI^sM5e$+~0oZvFSRf0(ZD(8aArJ#}|s0Ijn-2`oKL3;`xi?1Z{2!)79Su5aK7WJ&z z8=+uosSHvp>+7a&YhjnRp`|0+`bH@dN|qT4>&L>zv0$!mtVBL5W-;IMLvk4p3j%;)N)P>4XI*LD`Y~^D5id2()d8=UW(E^gi6}T z7fsEww8(8$&t$X$AF#6Jl$l=D*RX#Om5zDI6wOOs1*1I~DOMp>v{nsU(9slb13sSB zb6PoN+orx;vQdg=g|HaCklQtzIs9o~(u zsq})at>7ANmMt3>HGgVc!7%fw9KYE$u3*@hKpb449i73&&+y4pK4mLymX^zzl$|=2 z4kMezov-mrU887g8HL>Dsp(9um@+M`Tr`k0zuGm-ij35IDh6xQvbFrFWMN;?FjJVu z?xkAOO}m6q_m=77GZ@gr&u>kLW@k|dKWoG9z4$XMG5dArIem$H|3pv}g`K*Tcr4z3 tqF0G`Ua=Fl)8nI_56w&#CB}}gxEyD3s!8la(qK<~^pj6gWUOkV?0@Kyf7Sp1 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/struct.cpython-37.pyc b/Lib/__pycache__/struct.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c73be5e0db982801226e3031812684022967815e GIT binary patch literal 348 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/tempfile.cpython-37.pyc b/Lib/__pycache__/tempfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e08fe81ca16ed1a05dbc4a700c32d97086c6e0c0 GIT binary patch literal 22159 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/token.cpython-37.pyc b/Lib/__pycache__/token.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9fde3a9eab72d500633eb74212bb2c00d21b305 GIT binary patch literal 3613 zcmchZOH&(35`e2)t(IuLFmG&Z%V2DT4fy@U4}n^sv1nmQ7*82ii^&Gd5|Z5A*qCVT zg_+w%tYh~Nh={%Hf7oAA;nVDizc8oGYzgp8?8MAz)uFFmSy`D`)!8){iD(Re!Jlru zDa0824>gW|3Ra%u-+m=A28=V1Kn5Qu+X|P!&t*`#4+30)AooKTS3%u z22mb@7!N}?kH8rog&rP*UfvCT{0#K-9vI-gFv$C0i1))VAAqxb5YF)-7~#Wko}Yya z{2W~5BM|53;S#?9qx>R_@i<)OmtdTa!WBLSSNUa_;Ny_sS74G~g=>5QuJZ&;@kyBG z*I3VJSmM4NYn`^AoAf{#EOdE_Ukga9E( z=pxVoI0_NMga{!@!1KV4x(R0pJ%nCDAEBQxKo}$p5rzq83FinSg!6<8go}hY;Syn# zFh;mc7$;mITqR5p5`;;@HNthm6k(b$L%2b>Nw`J0O}In2OSnh4Pk2ChNO(lR__Iw4 z6a6Si6rOqf+q7JnxomxOO>Rm}*3)K|1^~?J7#h@vsNv?U27kV#^;~4StxHhoAsT>Q-dt0 zZB`{!vcAL0iF4#69R<%h+I5#Xtis521Fi2eiltmSUC@i<%ARLd8yS?fXl4QbHdUDP zJ6io6t=0<^PDoZ3i(hM`V86ouAJZtG*r^+-rDXnvp8pNK+ce4suJ5DMV)FZ0DdRvst3}5mml!>bb(BnVimI~pyXfF z*JyH0e$8C}-})qEOFLw(5U7VzGeA-=S)So2YlR`;viFfgxf%3YNUzmZW=#!sh4w5r zkYelan_)NDin?Lc5OE`zZO*!pRt){?I+XE1N1HLH+l`^!G0@y-S#mWuHp|>tGxXuB z+tr!b?RHyV-4L)!7na>LAN8Ga&!BW@m_cZkefYY{9Bj9G4lx%td%Sokop{W(fxWETgRx6B2i!nw0J_o30rXNEX70e2+}=G1wRK*drC>kV( z5oybOkv|NrGB@D%x_xf{kMb=09K}E|@c&FUo#6TYlSVG(PV~Gc&okX<2paQGDFigrx01 z9RqW#Tr=Oq*PL|^lM`=}Q~bu%!}U&CTAxh(V%QraOeXe+|FmXL&a6!$C#J7GOJKQ% zZF};vMc*Fb_bd?sOkF!>&Drl8o0{^{<>^;&YHGg+d(9gBqVEbO)os&>L*2CFwYo!t z&PKTw->O?X8%}&@!>V95wJ6W+2gdFAllVC7D`V)HkUm-Ty-N%U*}^1kf3}5!+CBZ~K`u1PRr)Y57`ePY zpDgIYkCtq{6aH-)cS>`sbqK6_#mM&&ezq z^^r!>M03t!YXn==e=KF~lF`AEXHBVOBo;-WRD$|usYI2HYPD3dmPkf1l1sW!jg_T2 zJulQkF`qFOM8MEjvl#;iGDb=_ib754Ua4f4lX;=!J!T6p=de!n&*!o^gNmi4q)-a_ zQbs7t*_DFu75{pAYY@qDRV zQ3P;&-djF9mru^4Ir(-O&|kL2f<~^`u62=`b~W75)o%HVnQTfI+I%KIzp|9h>aPXL zri+EeOu8tvd}d+sxSq1^+=WYP7;qPxh+;iGFGo-?}deFM5(iQw!`9d@hcQ_^Su6`{ysjb4KP%R{f5 V_sV&tPnDu_R1W&^QG#=t^k3UReX{@n literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/tokenize.cpython-37.pyc b/Lib/__pycache__/tokenize.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32bd177127e6a7bca59f9553aca83a3fd1160b61 GIT binary patch literal 17744 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 CYb2}y literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/types.cpython-37.pyc b/Lib/__pycache__/types.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..10ca70af5e9b168007cd9df5e04339e6df400a9c GIT binary patch literal 8988 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 NV^7sD*59!&{vUJ*bDsbJ literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/warnings.cpython-37.pyc b/Lib/__pycache__/warnings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87b6633366ea57d9c2a3c16415b8198c63650757 GIT binary patch literal 13780 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 literal 0 HcmV?d00001 diff --git a/Lib/__pycache__/weakref.cpython-37.pyc b/Lib/__pycache__/weakref.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a9bae99d6662902064a31bf0f38aebb4e008244 GIT binary patch literal 19124 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 xTeDVghEqhLfb`EkyiCaqj-s)1CreY len(other): + return False + for elem in self: + if elem not in other: + return False + return True + + def __lt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) < len(other) and self.__le__(other) + + def __gt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) > len(other) and self.__ge__(other) + + def __ge__(self, other): + if not isinstance(other, Set): + return NotImplemented + if len(self) < len(other): + return False + for elem in other: + if elem not in self: + return False + return True + + def __eq__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) == len(other) and self.__le__(other) + + @classmethod + def _from_iterable(cls, it): + '''Construct an instance of the class from any iterable input. + + Must override this method if the class constructor signature + does not accept an iterable for an input. + ''' + return cls(it) + + def __and__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + return self._from_iterable(value for value in other if value in self) + + __rand__ = __and__ + + def isdisjoint(self, other): + 'Return True if two sets have a null intersection.' + for value in other: + if value in self: + return False + return True + + def __or__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + chain = (e for s in (self, other) for e in s) + return self._from_iterable(chain) + + __ror__ = __or__ + + def __sub__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return self._from_iterable(value for value in self + if value not in other) + + def __rsub__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return self._from_iterable(value for value in other + if value not in self) + + def __xor__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return (self - other) | (other - self) + + __rxor__ = __xor__ + + def _hash(self): + """Compute the hash value of a set. + + Note that we don't define __hash__: not all sets are hashable. + But if you define a hashable set type, its __hash__ should + call this function. + + This must be compatible __eq__. + + All sets ought to compare equal if they contain the same + elements, regardless of how they are implemented, and + regardless of the order of the elements; so there's not much + freedom for __eq__ or __hash__. We match the algorithm used + by the built-in frozenset type. + """ + MAX = sys.maxsize + MASK = 2 * MAX + 1 + n = len(self) + h = 1927868237 * (n + 1) + h &= MASK + for x in self: + hx = hash(x) + h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 + h &= MASK + h = h * 69069 + 907133923 + h &= MASK + if h > MAX: + h -= MASK + 1 + if h == -1: + h = 590923713 + return h + +Set.register(frozenset) + + +class MutableSet(Set): + """A mutable set is a finite, iterable container. + + This class provides concrete generic implementations of all + methods except for __contains__, __iter__, __len__, + add(), and discard(). + + To override the comparisons (presumably for speed, as the + semantics are fixed), all you have to do is redefine __le__ and + then the other operations will automatically follow suit. + """ + + __slots__ = () + + @abstractmethod + def add(self, value): + """Add an element.""" + raise NotImplementedError + + @abstractmethod + def discard(self, value): + """Remove an element. Do not raise an exception if absent.""" + raise NotImplementedError + + def remove(self, value): + """Remove an element. If not a member, raise a KeyError.""" + if value not in self: + raise KeyError(value) + self.discard(value) + + def pop(self): + """Return the popped value. Raise KeyError if empty.""" + it = iter(self) + try: + value = next(it) + except StopIteration: + raise KeyError from None + self.discard(value) + return value + + def clear(self): + """This is slow (creates N new iterators!) but effective.""" + try: + while True: + self.pop() + except KeyError: + pass + + def __ior__(self, it): + for value in it: + self.add(value) + return self + + def __iand__(self, it): + for value in (self - it): + self.discard(value) + return self + + def __ixor__(self, it): + if it is self: + self.clear() + else: + if not isinstance(it, Set): + it = self._from_iterable(it) + for value in it: + if value in self: + self.discard(value) + else: + self.add(value) + return self + + def __isub__(self, it): + if it is self: + self.clear() + else: + for value in it: + self.discard(value) + return self + +MutableSet.register(set) + + +### MAPPINGS ### + + +class Mapping(Collection): + + __slots__ = () + + """A Mapping is a generic container for associating key/value + pairs. + + This class provides concrete generic implementations of all + methods except for __getitem__, __iter__, and __len__. + + """ + + @abstractmethod + def __getitem__(self, key): + raise KeyError + + def get(self, key, default=None): + 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.' + try: + return self[key] + except KeyError: + return default + + def __contains__(self, key): + try: + self[key] + except KeyError: + return False + else: + return True + + def keys(self): + "D.keys() -> a set-like object providing a view on D's keys" + return KeysView(self) + + def items(self): + "D.items() -> a set-like object providing a view on D's items" + return ItemsView(self) + + def values(self): + "D.values() -> an object providing a view on D's values" + return ValuesView(self) + + def __eq__(self, other): + if not isinstance(other, Mapping): + return NotImplemented + return dict(self.items()) == dict(other.items()) + + __reversed__ = None + +Mapping.register(mappingproxy) + + +class MappingView(Sized): + + __slots__ = '_mapping', + + def __init__(self, mapping): + self._mapping = mapping + + def __len__(self): + return len(self._mapping) + + def __repr__(self): + return '{0.__class__.__name__}({0._mapping!r})'.format(self) + + +class KeysView(MappingView, Set): + + __slots__ = () + + @classmethod + def _from_iterable(self, it): + return set(it) + + def __contains__(self, key): + return key in self._mapping + + def __iter__(self): + yield from self._mapping + +KeysView.register(dict_keys) + + +class ItemsView(MappingView, Set): + + __slots__ = () + + @classmethod + def _from_iterable(self, it): + return set(it) + + def __contains__(self, item): + key, value = item + try: + v = self._mapping[key] + except KeyError: + return False + else: + return v is value or v == value + + def __iter__(self): + for key in self._mapping: + yield (key, self._mapping[key]) + +ItemsView.register(dict_items) + + +class ValuesView(MappingView, Collection): + + __slots__ = () + + def __contains__(self, value): + for key in self._mapping: + v = self._mapping[key] + if v is value or v == value: + return True + return False + + def __iter__(self): + for key in self._mapping: + yield self._mapping[key] + +ValuesView.register(dict_values) + + +class MutableMapping(Mapping): + + __slots__ = () + + """A MutableMapping is a generic container for associating + key/value pairs. + + This class provides concrete generic implementations of all + methods except for __getitem__, __setitem__, __delitem__, + __iter__, and __len__. + + """ + + @abstractmethod + def __setitem__(self, key, value): + raise KeyError + + @abstractmethod + def __delitem__(self, key): + raise KeyError + + __marker = object() + + def pop(self, key, default=__marker): + '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + ''' + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def popitem(self): + '''D.popitem() -> (k, v), remove and return some (key, value) pair + as a 2-tuple; but raise KeyError if D is empty. + ''' + try: + key = next(iter(self)) + except StopIteration: + raise KeyError from None + value = self[key] + del self[key] + return key, value + + def clear(self): + 'D.clear() -> None. Remove all items from D.' + try: + while True: + self.popitem() + except KeyError: + pass + + def update(*args, **kwds): + ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. + If E present and has a .keys() method, does: for k in E: D[k] = E[k] + If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v + In either case, this is followed by: for k, v in F.items(): D[k] = v + ''' + if not args: + raise TypeError("descriptor 'update' of 'MutableMapping' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('update expected at most 1 arguments, got %d' % + len(args)) + if args: + other = args[0] + if isinstance(other, Mapping): + for key in other: + self[key] = other[key] + elif hasattr(other, "keys"): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + def setdefault(self, key, default=None): + 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D' + try: + return self[key] + except KeyError: + self[key] = default + return default + +MutableMapping.register(dict) + + +### SEQUENCES ### + + +class Sequence(Reversible, Collection): + + """All the operations on a read-only sequence. + + Concrete subclasses must override __new__ or __init__, + __getitem__, and __len__. + """ + + __slots__ = () + + @abstractmethod + def __getitem__(self, index): + raise IndexError + + def __iter__(self): + i = 0 + try: + while True: + v = self[i] + yield v + i += 1 + except IndexError: + return + + def __contains__(self, value): + for v in self: + if v is value or v == value: + return True + return False + + def __reversed__(self): + for i in reversed(range(len(self))): + yield self[i] + + def index(self, value, start=0, stop=None): + '''S.index(value, [start, [stop]]) -> integer -- return first index of value. + Raises ValueError if the value is not present. + + Supporting start and stop arguments is optional, but + recommended. + ''' + if start is not None and start < 0: + start = max(len(self) + start, 0) + if stop is not None and stop < 0: + stop += len(self) + + i = start + while stop is None or i < stop: + try: + v = self[i] + if v is value or v == value: + return i + except IndexError: + break + i += 1 + raise ValueError + + def count(self, value): + 'S.count(value) -> integer -- return number of occurrences of value' + return sum(1 for v in self if v is value or v == value) + +Sequence.register(tuple) +Sequence.register(str) +Sequence.register(range) +Sequence.register(memoryview) + + +class ByteString(Sequence): + + """This unifies bytes and bytearray. + + XXX Should add all their methods. + """ + + __slots__ = () + +ByteString.register(bytes) +ByteString.register(bytearray) + + +class MutableSequence(Sequence): + + __slots__ = () + + """All the operations on a read-write sequence. + + Concrete subclasses must provide __new__ or __init__, + __getitem__, __setitem__, __delitem__, __len__, and insert(). + + """ + + @abstractmethod + def __setitem__(self, index, value): + raise IndexError + + @abstractmethod + def __delitem__(self, index): + raise IndexError + + @abstractmethod + def insert(self, index, value): + 'S.insert(index, value) -- insert value before index' + raise IndexError + + def append(self, value): + 'S.append(value) -- append value to the end of the sequence' + self.insert(len(self), value) + + def clear(self): + 'S.clear() -> None -- remove all items from S' + try: + while True: + self.pop() + except IndexError: + pass + + def reverse(self): + 'S.reverse() -- reverse *IN PLACE*' + n = len(self) + for i in range(n//2): + self[i], self[n-i-1] = self[n-i-1], self[i] + + def extend(self, values): + 'S.extend(iterable) -- extend sequence by appending elements from the iterable' + for v in values: + self.append(v) + + def pop(self, index=-1): + '''S.pop([index]) -> item -- remove and return item at index (default last). + Raise IndexError if list is empty or index is out of range. + ''' + v = self[index] + del self[index] + return v + + def remove(self, value): + '''S.remove(value) -- remove first occurrence of value. + Raise ValueError if the value is not present. + ''' + del self[self.index(value)] + + def __iadd__(self, values): + self.extend(values) + return self + +MutableSequence.register(list) +MutableSequence.register(bytearray) # Multiply inheriting, see ByteString diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py new file mode 100644 index 0000000..a2cae54 --- /dev/null +++ b/Lib/_dummy_thread.py @@ -0,0 +1,163 @@ +"""Drop-in replacement for the thread module. + +Meant to be used as a brain-dead substitute so that threaded code does +not need to be rewritten for when the thread module is not present. + +Suggested usage is:: + + try: + import _thread + except ImportError: + import _dummy_thread as _thread + +""" +# Exports only things specified by thread documentation; +# skipping obsolete synonyms allocate(), start_new(), exit_thread(). +__all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock', + 'interrupt_main', 'LockType'] + +# A dummy value +TIMEOUT_MAX = 2**31 + +# NOTE: this module can be imported early in the extension building process, +# and so top level imports of other modules should be avoided. Instead, all +# imports are done when needed on a function-by-function basis. Since threads +# are disabled, the import lock should not be an issue anyway (??). + +error = RuntimeError + +def start_new_thread(function, args, kwargs={}): + """Dummy implementation of _thread.start_new_thread(). + + Compatibility is maintained by making sure that ``args`` is a + tuple and ``kwargs`` is a dictionary. If an exception is raised + and it is SystemExit (which can be done by _thread.exit()) it is + caught and nothing is done; all other exceptions are printed out + by using traceback.print_exc(). + + If the executed function calls interrupt_main the KeyboardInterrupt will be + raised when the function returns. + + """ + if type(args) != type(tuple()): + raise TypeError("2nd arg must be a tuple") + if type(kwargs) != type(dict()): + raise TypeError("3rd arg must be a dict") + global _main + _main = False + try: + function(*args, **kwargs) + except SystemExit: + pass + except: + import traceback + traceback.print_exc() + _main = True + global _interrupt + if _interrupt: + _interrupt = False + raise KeyboardInterrupt + +def exit(): + """Dummy implementation of _thread.exit().""" + raise SystemExit + +def get_ident(): + """Dummy implementation of _thread.get_ident(). + + Since this module should only be used when _threadmodule is not + available, it is safe to assume that the current process is the + only thread. Thus a constant can be safely returned. + """ + return 1 + +def allocate_lock(): + """Dummy implementation of _thread.allocate_lock().""" + return LockType() + +def stack_size(size=None): + """Dummy implementation of _thread.stack_size().""" + if size is not None: + raise error("setting thread stack size not supported") + return 0 + +def _set_sentinel(): + """Dummy implementation of _thread._set_sentinel().""" + return LockType() + +class LockType(object): + """Class implementing dummy implementation of _thread.LockType. + + Compatibility is maintained by maintaining self.locked_status + which is a boolean that stores the state of the lock. Pickling of + the lock, though, should not be done since if the _thread module is + then used with an unpickled ``lock()`` from here problems could + occur from this class not having atomic methods. + + """ + + def __init__(self): + self.locked_status = False + + def acquire(self, waitflag=None, timeout=-1): + """Dummy implementation of acquire(). + + For blocking calls, self.locked_status is automatically set to + True and returned appropriately based on value of + ``waitflag``. If it is non-blocking, then the value is + actually checked and not set if it is already acquired. This + is all done so that threading.Condition's assert statements + aren't triggered and throw a little fit. + + """ + if waitflag is None or waitflag: + self.locked_status = True + return True + else: + if not self.locked_status: + self.locked_status = True + return True + else: + if timeout > 0: + import time + time.sleep(timeout) + return False + + __enter__ = acquire + + def __exit__(self, typ, val, tb): + self.release() + + def release(self): + """Release the dummy lock.""" + # XXX Perhaps shouldn't actually bother to test? Could lead + # to problems for complex, threaded code. + if not self.locked_status: + raise error + self.locked_status = False + return True + + def locked(self): + return self.locked_status + + def __repr__(self): + return "<%s %s.%s object at %s>" % ( + "locked" if self.locked_status else "unlocked", + self.__class__.__module__, + self.__class__.__qualname__, + hex(id(self)) + ) + +# Used to signal that interrupt_main was called in a "thread" +_interrupt = False +# True when not executing in a "thread" +_main = True + +def interrupt_main(): + """Set _interrupt flag to True to have start_new_thread raise + KeyboardInterrupt upon exiting.""" + if _main: + raise KeyboardInterrupt + else: + global _interrupt + _interrupt = True diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py new file mode 100644 index 0000000..304c66f --- /dev/null +++ b/Lib/_weakrefset.py @@ -0,0 +1,196 @@ +# Access WeakSet through the weakref module. +# This code is separated-out because it is needed +# by abc.py to load everything else at startup. + +from _weakref import ref + +__all__ = ['WeakSet'] + + +class _IterationGuard: + # This context manager registers itself in the current iterators of the + # weak container, such as to delay all removals until the context manager + # exits. + # This technique should be relatively thread-safe (since sets are). + + def __init__(self, weakcontainer): + # Don't create cycles + self.weakcontainer = ref(weakcontainer) + + def __enter__(self): + w = self.weakcontainer() + if w is not None: + w._iterating.add(self) + return self + + def __exit__(self, e, t, b): + w = self.weakcontainer() + if w is not None: + s = w._iterating + s.remove(self) + if not s: + w._commit_removals() + + +class WeakSet: + def __init__(self, data=None): + self.data = set() + def _remove(item, selfref=ref(self)): + self = selfref() + if self is not None: + if self._iterating: + self._pending_removals.append(item) + else: + self.data.discard(item) + self._remove = _remove + # A list of keys to be removed + self._pending_removals = [] + self._iterating = set() + if data is not None: + self.update(data) + + def _commit_removals(self): + l = self._pending_removals + discard = self.data.discard + while l: + discard(l.pop()) + + def __iter__(self): + with _IterationGuard(self): + for itemref in self.data: + item = itemref() + if item is not None: + # Caveat: the iterator will keep a strong reference to + # `item` until it is resumed or closed. + yield item + + def __len__(self): + return len(self.data) - len(self._pending_removals) + + def __contains__(self, item): + try: + wr = ref(item) + except TypeError: + return False + return wr in self.data + + def __reduce__(self): + return (self.__class__, (list(self),), + getattr(self, '__dict__', None)) + + def add(self, item): + if self._pending_removals: + self._commit_removals() + self.data.add(ref(item, self._remove)) + + def clear(self): + if self._pending_removals: + self._commit_removals() + self.data.clear() + + def copy(self): + return self.__class__(self) + + def pop(self): + if self._pending_removals: + self._commit_removals() + while True: + try: + itemref = self.data.pop() + except KeyError: + raise KeyError('pop from empty WeakSet') from None + item = itemref() + if item is not None: + return item + + def remove(self, item): + if self._pending_removals: + self._commit_removals() + self.data.remove(ref(item)) + + def discard(self, item): + if self._pending_removals: + self._commit_removals() + self.data.discard(ref(item)) + + def update(self, other): + if self._pending_removals: + self._commit_removals() + for element in other: + self.add(element) + + def __ior__(self, other): + self.update(other) + return self + + def difference(self, other): + newset = self.copy() + newset.difference_update(other) + return newset + __sub__ = difference + + def difference_update(self, other): + self.__isub__(other) + def __isub__(self, other): + if self._pending_removals: + self._commit_removals() + if self is other: + self.data.clear() + else: + self.data.difference_update(ref(item) for item in other) + return self + + def intersection(self, other): + return self.__class__(item for item in other if item in self) + __and__ = intersection + + def intersection_update(self, other): + self.__iand__(other) + def __iand__(self, other): + if self._pending_removals: + self._commit_removals() + self.data.intersection_update(ref(item) for item in other) + return self + + def issubset(self, other): + return self.data.issubset(ref(item) for item in other) + __le__ = issubset + + def __lt__(self, other): + return self.data < set(map(ref, other)) + + def issuperset(self, other): + return self.data.issuperset(ref(item) for item in other) + __ge__ = issuperset + + def __gt__(self, other): + return self.data > set(map(ref, other)) + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.data == set(map(ref, other)) + + def symmetric_difference(self, other): + newset = self.copy() + newset.symmetric_difference_update(other) + return newset + __xor__ = symmetric_difference + + def symmetric_difference_update(self, other): + self.__ixor__(other) + def __ixor__(self, other): + if self._pending_removals: + self._commit_removals() + if self is other: + self.data.clear() + else: + self.data.symmetric_difference_update(ref(item, self._remove) for item in other) + return self + + def union(self, other): + return self.__class__(e for s in (self, other) for e in s) + __or__ = union + + def isdisjoint(self, other): + return len(self.intersection(other)) == 0 diff --git a/Lib/abc.py b/Lib/abc.py new file mode 100644 index 0000000..7094141 --- /dev/null +++ b/Lib/abc.py @@ -0,0 +1,170 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Abstract Base Classes (ABCs) according to PEP 3119.""" + + +def abstractmethod(funcobj): + """A decorator indicating abstract methods. + + Requires that the metaclass is ABCMeta or derived from it. A + class that has a metaclass derived from ABCMeta cannot be + instantiated unless all of its abstract methods are overridden. + The abstract methods can be called using any of the normal + 'super' call mechanisms. + + Usage: + + class C(metaclass=ABCMeta): + @abstractmethod + def my_abstract_method(self, ...): + ... + """ + funcobj.__isabstractmethod__ = True + return funcobj + + +class abstractclassmethod(classmethod): + """A decorator indicating abstract classmethods. + + Similar to abstractmethod. + + Usage: + + class C(metaclass=ABCMeta): + @abstractclassmethod + def my_abstract_classmethod(cls, ...): + ... + + 'abstractclassmethod' is deprecated. Use 'classmethod' with + 'abstractmethod' instead. + """ + + __isabstractmethod__ = True + + def __init__(self, callable): + callable.__isabstractmethod__ = True + super().__init__(callable) + + +class abstractstaticmethod(staticmethod): + """A decorator indicating abstract staticmethods. + + Similar to abstractmethod. + + Usage: + + class C(metaclass=ABCMeta): + @abstractstaticmethod + def my_abstract_staticmethod(...): + ... + + 'abstractstaticmethod' is deprecated. Use 'staticmethod' with + 'abstractmethod' instead. + """ + + __isabstractmethod__ = True + + def __init__(self, callable): + callable.__isabstractmethod__ = True + super().__init__(callable) + + +class abstractproperty(property): + """A decorator indicating abstract properties. + + Requires that the metaclass is ABCMeta or derived from it. A + class that has a metaclass derived from ABCMeta cannot be + instantiated unless all of its abstract properties are overridden. + The abstract properties can be called using any of the normal + 'super' call mechanisms. + + Usage: + + class C(metaclass=ABCMeta): + @abstractproperty + def my_abstract_property(self): + ... + + This defines a read-only property; you can also define a read-write + abstract property using the 'long' form of property declaration: + + class C(metaclass=ABCMeta): + def getx(self): ... + def setx(self, value): ... + x = abstractproperty(getx, setx) + + 'abstractproperty' is deprecated. Use 'property' with 'abstractmethod' + instead. + """ + + __isabstractmethod__ = True + + +try: + from _abc import (get_cache_token, _abc_init, _abc_register, + _abc_instancecheck, _abc_subclasscheck, _get_dump, + _reset_registry, _reset_caches) +except ImportError: + from _py_abc import ABCMeta, get_cache_token + ABCMeta.__module__ = 'abc' +else: + class ABCMeta(type): + """Metaclass for defining Abstract Base Classes (ABCs). + + Use this metaclass to create an ABC. An ABC can be subclassed + directly, and then acts as a mix-in class. You can also register + unrelated concrete classes (even built-in classes) and unrelated + ABCs as 'virtual subclasses' -- these and their descendants will + be considered subclasses of the registering ABC by the built-in + issubclass() function, but the registering ABC won't show up in + their MRO (Method Resolution Order) nor will method + implementations defined by the registering ABC be callable (not + even via super()). + """ + def __new__(mcls, name, bases, namespace, **kwargs): + cls = super().__new__(mcls, name, bases, namespace, **kwargs) + _abc_init(cls) + return cls + + def register(cls, subclass): + """Register a virtual subclass of an ABC. + + Returns the subclass, to allow usage as a class decorator. + """ + return _abc_register(cls, subclass) + + def __instancecheck__(cls, instance): + """Override for isinstance(instance, cls).""" + return _abc_instancecheck(cls, instance) + + def __subclasscheck__(cls, subclass): + """Override for issubclass(subclass, cls).""" + return _abc_subclasscheck(cls, subclass) + + def _dump_registry(cls, file=None): + """Debug helper to print the ABC registry.""" + print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file) + print(f"Inv. counter: {get_cache_token()}", file=file) + (_abc_registry, _abc_cache, _abc_negative_cache, + _abc_negative_cache_version) = _get_dump(cls) + print(f"_abc_registry: {_abc_registry!r}", file=file) + print(f"_abc_cache: {_abc_cache!r}", file=file) + print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file) + print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}", + file=file) + + def _abc_registry_clear(cls): + """Clear the registry (for debugging or testing).""" + _reset_registry(cls) + + def _abc_caches_clear(cls): + """Clear the caches (for debugging or testing).""" + _reset_caches(cls) + + +class ABC(metaclass=ABCMeta): + """Helper class that provides a standard way to create an ABC using + inheritance. + """ + __slots__ = () diff --git a/Lib/base64.py b/Lib/base64.py new file mode 100644 index 0000000..eb8f258 --- /dev/null +++ b/Lib/base64.py @@ -0,0 +1,602 @@ +#! /usr/bin/env python3 + +"""Base16, Base32, Base64 (RFC 3548), Base85 and Ascii85 data encodings""" + +# Modified 04-Oct-1995 by Jack Jansen to use binascii module +# Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support +# Modified 22-May-2007 by Guido van Rossum to use bytes everywhere + +import re +import struct +import binascii + + +__all__ = [ + # Legacy interface exports traditional RFC 2045 Base64 encodings + 'encode', 'decode', 'encodebytes', 'decodebytes', + # Generalized interface for other encodings + 'b64encode', 'b64decode', 'b32encode', 'b32decode', + 'b16encode', 'b16decode', + # Base85 and Ascii85 encodings + 'b85encode', 'b85decode', 'a85encode', 'a85decode', + # Standard Base64 encoding + 'standard_b64encode', 'standard_b64decode', + # Some common Base64 alternatives. As referenced by RFC 3458, see thread + # starting at: + # + # http://zgp.org/pipermail/p2p-hackers/2001-September/000316.html + 'urlsafe_b64encode', 'urlsafe_b64decode', + ] + + +bytes_types = (bytes, bytearray) # Types acceptable as binary data + +def _bytes_from_decode_data(s): + if isinstance(s, str): + try: + return s.encode('ascii') + except UnicodeEncodeError: + raise ValueError('string argument should contain only ASCII characters') + if isinstance(s, bytes_types): + return s + try: + return memoryview(s).tobytes() + except TypeError: + raise TypeError("argument should be a bytes-like object or ASCII " + "string, not %r" % s.__class__.__name__) from None + + +# Base64 encoding/decoding uses binascii + +def b64encode(s, altchars=None): + """Encode the bytes-like object s using Base64 and return a bytes object. + + Optional altchars should be a byte string of length 2 which specifies an + alternative alphabet for the '+' and '/' characters. This allows an + application to e.g. generate url or filesystem safe Base64 strings. + """ + encoded = binascii.b2a_base64(s, newline=False) + if altchars is not None: + assert len(altchars) == 2, repr(altchars) + return encoded.translate(bytes.maketrans(b'+/', altchars)) + return encoded + + +def b64decode(s, altchars=None, validate=False): + """Decode the Base64 encoded bytes-like object or ASCII string s. + + Optional altchars must be a bytes-like object or ASCII string of length 2 + which specifies the alternative alphabet used instead of the '+' and '/' + characters. + + The result is returned as a bytes object. A binascii.Error is raised if + s is incorrectly padded. + + If validate is False (the default), characters that are neither in the + normal base-64 alphabet nor the alternative alphabet are discarded prior + to the padding check. If validate is True, these non-alphabet characters + in the input result in a binascii.Error. + """ + s = _bytes_from_decode_data(s) + if altchars is not None: + altchars = _bytes_from_decode_data(altchars) + assert len(altchars) == 2, repr(altchars) + s = s.translate(bytes.maketrans(altchars, b'+/')) + if validate and not re.match(b'^[A-Za-z0-9+/]*={0,2}$', s): + raise binascii.Error('Non-base64 digit found') + return binascii.a2b_base64(s) + + +def standard_b64encode(s): + """Encode bytes-like object s using the standard Base64 alphabet. + + The result is returned as a bytes object. + """ + return b64encode(s) + +def standard_b64decode(s): + """Decode bytes encoded with the standard Base64 alphabet. + + Argument s is a bytes-like object or ASCII string to decode. The result + is returned as a bytes object. A binascii.Error is raised if the input + is incorrectly padded. Characters that are not in the standard alphabet + are discarded prior to the padding check. + """ + return b64decode(s) + + +_urlsafe_encode_translation = bytes.maketrans(b'+/', b'-_') +_urlsafe_decode_translation = bytes.maketrans(b'-_', b'+/') + +def urlsafe_b64encode(s): + """Encode bytes using the URL- and filesystem-safe Base64 alphabet. + + Argument s is a bytes-like object to encode. The result is returned as a + bytes object. The alphabet uses '-' instead of '+' and '_' instead of + '/'. + """ + return b64encode(s).translate(_urlsafe_encode_translation) + +def urlsafe_b64decode(s): + """Decode bytes using the URL- and filesystem-safe Base64 alphabet. + + Argument s is a bytes-like object or ASCII string to decode. The result + is returned as a bytes object. A binascii.Error is raised if the input + is incorrectly padded. Characters that are not in the URL-safe base-64 + alphabet, and are not a plus '+' or slash '/', are discarded prior to the + padding check. + + The alphabet uses '-' instead of '+' and '_' instead of '/'. + """ + s = _bytes_from_decode_data(s) + s = s.translate(_urlsafe_decode_translation) + return b64decode(s) + + + +# Base32 encoding/decoding must be done in Python +_b32alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' +_b32tab2 = None +_b32rev = None + +def b32encode(s): + """Encode the bytes-like object s using Base32 and return a bytes object. + """ + global _b32tab2 + # Delay the initialization of the table to not waste memory + # if the function is never called + if _b32tab2 is None: + b32tab = [bytes((i,)) for i in _b32alphabet] + _b32tab2 = [a + b for a in b32tab for b in b32tab] + b32tab = None + + if not isinstance(s, bytes_types): + s = memoryview(s).tobytes() + leftover = len(s) % 5 + # Pad the last quantum with zero bits if necessary + if leftover: + s = s + b'\0' * (5 - leftover) # Don't use += ! + encoded = bytearray() + from_bytes = int.from_bytes + b32tab2 = _b32tab2 + for i in range(0, len(s), 5): + c = from_bytes(s[i: i + 5], 'big') + encoded += (b32tab2[c >> 30] + # bits 1 - 10 + b32tab2[(c >> 20) & 0x3ff] + # bits 11 - 20 + b32tab2[(c >> 10) & 0x3ff] + # bits 21 - 30 + b32tab2[c & 0x3ff] # bits 31 - 40 + ) + # Adjust for any leftover partial quanta + if leftover == 1: + encoded[-6:] = b'======' + elif leftover == 2: + encoded[-4:] = b'====' + elif leftover == 3: + encoded[-3:] = b'===' + elif leftover == 4: + encoded[-1:] = b'=' + return bytes(encoded) + +def b32decode(s, casefold=False, map01=None): + """Decode the Base32 encoded bytes-like object or ASCII string s. + + Optional casefold is a flag specifying whether a lowercase alphabet is + acceptable as input. For security purposes, the default is False. + + RFC 3548 allows for optional mapping of the digit 0 (zero) to the + letter O (oh), and for optional mapping of the digit 1 (one) to + either the letter I (eye) or letter L (el). The optional argument + map01 when not None, specifies which letter the digit 1 should be + mapped to (when map01 is not None, the digit 0 is always mapped to + the letter O). For security purposes the default is None, so that + 0 and 1 are not allowed in the input. + + The result is returned as a bytes object. A binascii.Error is raised if + the input is incorrectly padded or if there are non-alphabet + characters present in the input. + """ + global _b32rev + # Delay the initialization of the table to not waste memory + # if the function is never called + if _b32rev is None: + _b32rev = {v: k for k, v in enumerate(_b32alphabet)} + s = _bytes_from_decode_data(s) + if len(s) % 8: + raise binascii.Error('Incorrect padding') + # Handle section 2.4 zero and one mapping. The flag map01 will be either + # False, or the character to map the digit 1 (one) to. It should be + # either L (el) or I (eye). + if map01 is not None: + map01 = _bytes_from_decode_data(map01) + assert len(map01) == 1, repr(map01) + s = s.translate(bytes.maketrans(b'01', b'O' + map01)) + if casefold: + s = s.upper() + # Strip off pad characters from the right. We need to count the pad + # characters because this will tell us how many null bytes to remove from + # the end of the decoded string. + l = len(s) + s = s.rstrip(b'=') + padchars = l - len(s) + # Now decode the full quanta + decoded = bytearray() + b32rev = _b32rev + for i in range(0, len(s), 8): + quanta = s[i: i + 8] + acc = 0 + try: + for c in quanta: + acc = (acc << 5) + b32rev[c] + except KeyError: + raise binascii.Error('Non-base32 digit found') from None + decoded += acc.to_bytes(5, 'big') + # Process the last, partial quanta + if padchars: + acc <<= 5 * padchars + last = acc.to_bytes(5, 'big') + if padchars == 1: + decoded[-5:] = last[:-1] + elif padchars == 3: + decoded[-5:] = last[:-2] + elif padchars == 4: + decoded[-5:] = last[:-3] + elif padchars == 6: + decoded[-5:] = last[:-4] + else: + raise binascii.Error('Incorrect padding') + return bytes(decoded) + + + +# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns +# lowercase. The RFC also recommends against accepting input case +# insensitively. +def b16encode(s): + """Encode the bytes-like object s using Base16 and return a bytes object. + """ + return binascii.hexlify(s).upper() + + +def b16decode(s, casefold=False): + """Decode the Base16 encoded bytes-like object or ASCII string s. + + Optional casefold is a flag specifying whether a lowercase alphabet is + acceptable as input. For security purposes, the default is False. + + The result is returned as a bytes object. A binascii.Error is raised if + s is incorrectly padded or if there are non-alphabet characters present + in the input. + """ + s = _bytes_from_decode_data(s) + if casefold: + s = s.upper() + if re.search(b'[^0-9A-F]', s): + raise binascii.Error('Non-base16 digit found') + return binascii.unhexlify(s) + +# +# Ascii85 encoding/decoding +# + +_a85chars = None +_a85chars2 = None +_A85START = b"<~" +_A85END = b"~>" + +def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): + # Helper function for a85encode and b85encode + if not isinstance(b, bytes_types): + b = memoryview(b).tobytes() + + padding = (-len(b)) % 4 + if padding: + b = b + b'\0' * padding + words = struct.Struct('!%dI' % (len(b) // 4)).unpack(b) + + chunks = [b'z' if foldnuls and not word else + b'y' if foldspaces and word == 0x20202020 else + (chars2[word // 614125] + + chars2[word // 85 % 7225] + + chars[word % 85]) + for word in words] + + if padding and not pad: + if chunks[-1] == b'z': + chunks[-1] = chars[0] * 5 + chunks[-1] = chunks[-1][:-padding] + + return b''.join(chunks) + +def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): + """Encode bytes-like object b using Ascii85 and return a bytes object. + + foldspaces is an optional flag that uses the special short sequence 'y' + instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This + feature is not supported by the "standard" Adobe encoding. + + wrapcol controls whether the output should have newline (b'\\n') characters + added to it. If this is non-zero, each output line will be at most this + many characters long. + + pad controls whether the input is padded to a multiple of 4 before + encoding. Note that the btoa implementation always pads. + + adobe controls whether the encoded byte sequence is framed with <~ and ~>, + which is used by the Adobe implementation. + """ + global _a85chars, _a85chars2 + # Delay the initialization of tables to not waste memory + # if the function is never called + if _a85chars is None: + _a85chars = [bytes((i,)) for i in range(33, 118)] + _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] + + result = _85encode(b, _a85chars, _a85chars2, pad, True, foldspaces) + + if adobe: + result = _A85START + result + if wrapcol: + wrapcol = max(2 if adobe else 1, wrapcol) + chunks = [result[i: i + wrapcol] + for i in range(0, len(result), wrapcol)] + if adobe: + if len(chunks[-1]) + 2 > wrapcol: + chunks.append(b'') + result = b'\n'.join(chunks) + if adobe: + result += _A85END + + return result + +def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): + """Decode the Ascii85 encoded bytes-like object or ASCII string b. + + foldspaces is a flag that specifies whether the 'y' short sequence should be + accepted as shorthand for 4 consecutive spaces (ASCII 0x20). This feature is + not supported by the "standard" Adobe encoding. + + adobe controls whether the input sequence is in Adobe Ascii85 format (i.e. + is framed with <~ and ~>). + + ignorechars should be a byte string containing characters to ignore from the + input. This should only contain whitespace characters, and by default + contains all whitespace characters in ASCII. + + The result is returned as a bytes object. + """ + b = _bytes_from_decode_data(b) + if adobe: + if not b.endswith(_A85END): + raise ValueError( + "Ascii85 encoded byte sequences must end " + "with {!r}".format(_A85END) + ) + if b.startswith(_A85START): + b = b[2:-2] # Strip off start/end markers + else: + b = b[:-2] + # + # We have to go through this stepwise, so as to ignore spaces and handle + # special short sequences + # + packI = struct.Struct('!I').pack + decoded = [] + decoded_append = decoded.append + curr = [] + curr_append = curr.append + curr_clear = curr.clear + for x in b + b'u' * 4: + if b'!'[0] <= x <= b'u'[0]: + curr_append(x) + if len(curr) == 5: + acc = 0 + for x in curr: + acc = 85 * acc + (x - 33) + try: + decoded_append(packI(acc)) + except struct.error: + raise ValueError('Ascii85 overflow') from None + curr_clear() + elif x == b'z'[0]: + if curr: + raise ValueError('z inside Ascii85 5-tuple') + decoded_append(b'\0\0\0\0') + elif foldspaces and x == b'y'[0]: + if curr: + raise ValueError('y inside Ascii85 5-tuple') + decoded_append(b'\x20\x20\x20\x20') + elif x in ignorechars: + # Skip whitespace + continue + else: + raise ValueError('Non-Ascii85 digit found: %c' % x) + + result = b''.join(decoded) + padding = 4 - len(curr) + if padding: + # Throw away the extra padding + result = result[:-padding] + return result + +# The following code is originally taken (with permission) from Mercurial + +_b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~") +_b85chars = None +_b85chars2 = None +_b85dec = None + +def b85encode(b, pad=False): + """Encode bytes-like object b in base85 format and return a bytes object. + + If pad is true, the input is padded with b'\\0' so its length is a multiple of + 4 bytes before encoding. + """ + global _b85chars, _b85chars2 + # Delay the initialization of tables to not waste memory + # if the function is never called + if _b85chars is None: + _b85chars = [bytes((i,)) for i in _b85alphabet] + _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] + return _85encode(b, _b85chars, _b85chars2, pad) + +def b85decode(b): + """Decode the base85-encoded bytes-like object or ASCII string b + + The result is returned as a bytes object. + """ + global _b85dec + # Delay the initialization of tables to not waste memory + # if the function is never called + if _b85dec is None: + _b85dec = [None] * 256 + for i, c in enumerate(_b85alphabet): + _b85dec[c] = i + + b = _bytes_from_decode_data(b) + padding = (-len(b)) % 5 + b = b + b'~' * padding + out = [] + packI = struct.Struct('!I').pack + for i in range(0, len(b), 5): + chunk = b[i:i + 5] + acc = 0 + try: + for c in chunk: + acc = acc * 85 + _b85dec[c] + except TypeError: + for j, c in enumerate(chunk): + if _b85dec[c] is None: + raise ValueError('bad base85 character at position %d' + % (i + j)) from None + raise + try: + out.append(packI(acc)) + except struct.error: + raise ValueError('base85 overflow in hunk starting at byte %d' + % i) from None + + result = b''.join(out) + if padding: + result = result[:-padding] + return result + +# Legacy interface. This code could be cleaned up since I don't believe +# binascii has any line length limitations. It just doesn't seem worth it +# though. The files should be opened in binary mode. + +MAXLINESIZE = 76 # Excluding the CRLF +MAXBINSIZE = (MAXLINESIZE//4)*3 + +def encode(input, output): + """Encode a file; input and output are binary files.""" + while True: + s = input.read(MAXBINSIZE) + if not s: + break + while len(s) < MAXBINSIZE: + ns = input.read(MAXBINSIZE-len(s)) + if not ns: + break + s += ns + line = binascii.b2a_base64(s) + output.write(line) + + +def decode(input, output): + """Decode a file; input and output are binary files.""" + while True: + line = input.readline() + if not line: + break + s = binascii.a2b_base64(line) + output.write(s) + +def _input_type_check(s): + try: + m = memoryview(s) + except TypeError as err: + msg = "expected bytes-like object, not %s" % s.__class__.__name__ + raise TypeError(msg) from err + if m.format not in ('c', 'b', 'B'): + msg = ("expected single byte elements, not %r from %s" % + (m.format, s.__class__.__name__)) + raise TypeError(msg) + if m.ndim != 1: + msg = ("expected 1-D data, not %d-D data from %s" % + (m.ndim, s.__class__.__name__)) + raise TypeError(msg) + + +def encodebytes(s): + """Encode a bytestring into a bytes object containing multiple lines + of base-64 data.""" + _input_type_check(s) + pieces = [] + for i in range(0, len(s), MAXBINSIZE): + chunk = s[i : i + MAXBINSIZE] + pieces.append(binascii.b2a_base64(chunk)) + return b"".join(pieces) + +def encodestring(s): + """Legacy alias of encodebytes().""" + import warnings + warnings.warn("encodestring() is a deprecated alias since 3.1, " + "use encodebytes()", + DeprecationWarning, 2) + return encodebytes(s) + + +def decodebytes(s): + """Decode a bytestring of base-64 data into a bytes object.""" + _input_type_check(s) + return binascii.a2b_base64(s) + +def decodestring(s): + """Legacy alias of decodebytes().""" + import warnings + warnings.warn("decodestring() is a deprecated alias since Python 3.1, " + "use decodebytes()", + DeprecationWarning, 2) + return decodebytes(s) + + +# Usable as a script... +def main(): + """Small main program""" + import sys, getopt + try: + opts, args = getopt.getopt(sys.argv[1:], 'deut') + except getopt.error as msg: + sys.stdout = sys.stderr + print(msg) + print("""usage: %s [-d|-e|-u|-t] [file|-] + -d, -u: decode + -e: encode (default) + -t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0]) + sys.exit(2) + func = encode + for o, a in opts: + if o == '-e': func = encode + if o == '-d': func = decode + if o == '-u': func = decode + if o == '-t': test(); return + if args and args[0] != '-': + with open(args[0], 'rb') as f: + func(f, sys.stdout.buffer) + else: + func(sys.stdin.buffer, sys.stdout.buffer) + + +def test(): + s0 = b"Aladdin:open sesame" + print(repr(s0)) + s1 = encodebytes(s0) + print(repr(s1)) + s2 = decodebytes(s1) + print(repr(s2)) + assert s0 == s2 + + +if __name__ == '__main__': + main() diff --git a/Lib/bisect.py b/Lib/bisect.py new file mode 100644 index 0000000..7732c63 --- /dev/null +++ b/Lib/bisect.py @@ -0,0 +1,92 @@ +"""Bisection algorithms.""" + +def insort_right(a, x, lo=0, hi=None): + """Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the right of the rightmost x. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if x < a[mid]: hi = mid + else: lo = mid+1 + a.insert(lo, x) + +def bisect_right(a, x, lo=0, hi=None): + """Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e <= x, and all e in + a[i:] have e > x. So if x already appears in the list, a.insert(x) will + insert just after the rightmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if x < a[mid]: hi = mid + else: lo = mid+1 + return lo + +def insort_left(a, x, lo=0, hi=None): + """Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the left of the leftmost x. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if a[mid] < x: lo = mid+1 + else: hi = mid + a.insert(lo, x) + + +def bisect_left(a, x, lo=0, hi=None): + """Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e < x, and all e in + a[i:] have e >= x. So if x already appears in the list, a.insert(x) will + insert just before the leftmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if a[mid] < x: lo = mid+1 + else: hi = mid + return lo + +# Overwrite above definitions with a fast C implementation +try: + from _bisect import * +except ImportError: + pass + +# Create aliases +bisect = bisect_right +insort = insort_right diff --git a/Lib/codecs.py b/Lib/codecs.py new file mode 100644 index 0000000..a70ed20 --- /dev/null +++ b/Lib/codecs.py @@ -0,0 +1,1114 @@ +""" codecs -- Python Codec Registry, API and helpers. + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" + +import builtins +import sys + +### Registry and builtin stateless codec functions + +try: + from _codecs import * +except ImportError as why: + raise SystemError('Failed to load the builtin codecs: %s' % why) + +__all__ = ["register", "lookup", "open", "EncodedFile", "BOM", "BOM_BE", + "BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", + "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_LE", "BOM_UTF16_BE", + "BOM_UTF32", "BOM_UTF32_LE", "BOM_UTF32_BE", + "CodecInfo", "Codec", "IncrementalEncoder", "IncrementalDecoder", + "StreamReader", "StreamWriter", + "StreamReaderWriter", "StreamRecoder", + "getencoder", "getdecoder", "getincrementalencoder", + "getincrementaldecoder", "getreader", "getwriter", + "encode", "decode", "iterencode", "iterdecode", + "strict_errors", "ignore_errors", "replace_errors", + "xmlcharrefreplace_errors", + "backslashreplace_errors", "namereplace_errors", + "register_error", "lookup_error"] + +### Constants + +# +# Byte Order Mark (BOM = ZERO WIDTH NO-BREAK SPACE = U+FEFF) +# and its possible byte string values +# for UTF8/UTF16/UTF32 output and little/big endian machines +# + +# UTF-8 +BOM_UTF8 = b'\xef\xbb\xbf' + +# UTF-16, little endian +BOM_LE = BOM_UTF16_LE = b'\xff\xfe' + +# UTF-16, big endian +BOM_BE = BOM_UTF16_BE = b'\xfe\xff' + +# UTF-32, little endian +BOM_UTF32_LE = b'\xff\xfe\x00\x00' + +# UTF-32, big endian +BOM_UTF32_BE = b'\x00\x00\xfe\xff' + +if sys.byteorder == 'little': + + # UTF-16, native endianness + BOM = BOM_UTF16 = BOM_UTF16_LE + + # UTF-32, native endianness + BOM_UTF32 = BOM_UTF32_LE + +else: + + # UTF-16, native endianness + BOM = BOM_UTF16 = BOM_UTF16_BE + + # UTF-32, native endianness + BOM_UTF32 = BOM_UTF32_BE + +# Old broken names (don't use in new code) +BOM32_LE = BOM_UTF16_LE +BOM32_BE = BOM_UTF16_BE +BOM64_LE = BOM_UTF32_LE +BOM64_BE = BOM_UTF32_BE + + +### Codec base classes (defining the API) + +class CodecInfo(tuple): + """Codec details when looking up the codec registry""" + + # Private API to allow Python 3.4 to blacklist the known non-Unicode + # codecs in the standard library. A more general mechanism to + # reliably distinguish test encodings from other codecs will hopefully + # be defined for Python 3.5 + # + # See http://bugs.python.org/issue19619 + _is_text_encoding = True # Assume codecs are text encodings by default + + def __new__(cls, encode, decode, streamreader=None, streamwriter=None, + incrementalencoder=None, incrementaldecoder=None, name=None, + *, _is_text_encoding=None): + self = tuple.__new__(cls, (encode, decode, streamreader, streamwriter)) + self.name = name + self.encode = encode + self.decode = decode + self.incrementalencoder = incrementalencoder + self.incrementaldecoder = incrementaldecoder + self.streamwriter = streamwriter + self.streamreader = streamreader + if _is_text_encoding is not None: + self._is_text_encoding = _is_text_encoding + return self + + def __repr__(self): + return "<%s.%s object for encoding %s at %#x>" % \ + (self.__class__.__module__, self.__class__.__qualname__, + self.name, id(self)) + +class Codec: + + """ Defines the interface for stateless encoders/decoders. + + The .encode()/.decode() methods may use different error + handling schemes by providing the errors argument. These + string values are predefined: + + 'strict' - raise a ValueError error (or a subclass) + 'ignore' - ignore the character and continue with the next + 'replace' - replace with a suitable replacement character; + Python will use the official U+FFFD REPLACEMENT + CHARACTER for the builtin Unicode codecs on + decoding and '?' on encoding. + 'surrogateescape' - replace with private code points U+DCnn. + 'xmlcharrefreplace' - Replace with the appropriate XML + character reference (only for encoding). + 'backslashreplace' - Replace with backslashed escape sequences. + 'namereplace' - Replace with \\N{...} escape sequences + (only for encoding). + + The set of allowed values can be extended via register_error. + + """ + def encode(self, input, errors='strict'): + + """ Encodes the object input and returns a tuple (output + object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling. + + The method may not store state in the Codec instance. Use + StreamWriter for codecs which have to keep state in order to + make encoding efficient. + + The encoder must be able to handle zero length input and + return an empty object of the output object type in this + situation. + + """ + raise NotImplementedError + + def decode(self, input, errors='strict'): + + """ Decodes the object input and returns a tuple (output + object, length consumed). + + input must be an object which provides the bf_getreadbuf + buffer slot. Python strings, buffer objects and memory + mapped files are examples of objects providing this slot. + + errors defines the error handling to apply. It defaults to + 'strict' handling. + + The method may not store state in the Codec instance. Use + StreamReader for codecs which have to keep state in order to + make decoding efficient. + + The decoder must be able to handle zero length input and + return an empty object of the output object type in this + situation. + + """ + raise NotImplementedError + +class IncrementalEncoder(object): + """ + An IncrementalEncoder encodes an input in multiple steps. The input can + be passed piece by piece to the encode() method. The IncrementalEncoder + remembers the state of the encoding process between calls to encode(). + """ + def __init__(self, errors='strict'): + """ + Creates an IncrementalEncoder instance. + + The IncrementalEncoder may use different error handling schemes by + providing the errors keyword argument. See the module docstring + for a list of possible values. + """ + self.errors = errors + self.buffer = "" + + def encode(self, input, final=False): + """ + Encodes input and returns the resulting object. + """ + raise NotImplementedError + + def reset(self): + """ + Resets the encoder to the initial state. + """ + + def getstate(self): + """ + Return the current state of the encoder. + """ + return 0 + + def setstate(self, state): + """ + Set the current state of the encoder. state must have been + returned by getstate(). + """ + +class BufferedIncrementalEncoder(IncrementalEncoder): + """ + This subclass of IncrementalEncoder can be used as the baseclass for an + incremental encoder if the encoder must keep some of the output in a + buffer between calls to encode(). + """ + def __init__(self, errors='strict'): + IncrementalEncoder.__init__(self, errors) + # unencoded input that is kept between calls to encode() + self.buffer = "" + + def _buffer_encode(self, input, errors, final): + # Overwrite this method in subclasses: It must encode input + # and return an (output, length consumed) tuple + raise NotImplementedError + + def encode(self, input, final=False): + # encode input (taking the buffer into account) + data = self.buffer + input + (result, consumed) = self._buffer_encode(data, self.errors, final) + # keep unencoded input until the next call + self.buffer = data[consumed:] + return result + + def reset(self): + IncrementalEncoder.reset(self) + self.buffer = "" + + def getstate(self): + return self.buffer or 0 + + def setstate(self, state): + self.buffer = state or "" + +class IncrementalDecoder(object): + """ + An IncrementalDecoder decodes an input in multiple steps. The input can + be passed piece by piece to the decode() method. The IncrementalDecoder + remembers the state of the decoding process between calls to decode(). + """ + def __init__(self, errors='strict'): + """ + Create an IncrementalDecoder instance. + + The IncrementalDecoder may use different error handling schemes by + providing the errors keyword argument. See the module docstring + for a list of possible values. + """ + self.errors = errors + + def decode(self, input, final=False): + """ + Decode input and returns the resulting object. + """ + raise NotImplementedError + + def reset(self): + """ + Reset the decoder to the initial state. + """ + + def getstate(self): + """ + Return the current state of the decoder. + + This must be a (buffered_input, additional_state_info) tuple. + buffered_input must be a bytes object containing bytes that + were passed to decode() that have not yet been converted. + additional_state_info must be a non-negative integer + representing the state of the decoder WITHOUT yet having + processed the contents of buffered_input. In the initial state + and after reset(), getstate() must return (b"", 0). + """ + return (b"", 0) + + def setstate(self, state): + """ + Set the current state of the decoder. + + state must have been returned by getstate(). The effect of + setstate((b"", 0)) must be equivalent to reset(). + """ + +class BufferedIncrementalDecoder(IncrementalDecoder): + """ + This subclass of IncrementalDecoder can be used as the baseclass for an + incremental decoder if the decoder must be able to handle incomplete + byte sequences. + """ + def __init__(self, errors='strict'): + IncrementalDecoder.__init__(self, errors) + # undecoded input that is kept between calls to decode() + self.buffer = b"" + + def _buffer_decode(self, input, errors, final): + # Overwrite this method in subclasses: It must decode input + # and return an (output, length consumed) tuple + raise NotImplementedError + + def decode(self, input, final=False): + # decode input (taking the buffer into account) + data = self.buffer + input + (result, consumed) = self._buffer_decode(data, self.errors, final) + # keep undecoded input until the next call + self.buffer = data[consumed:] + return result + + def reset(self): + IncrementalDecoder.reset(self) + self.buffer = b"" + + def getstate(self): + # additional state info is always 0 + return (self.buffer, 0) + + def setstate(self, state): + # ignore additional state info + self.buffer = state[0] + +# +# The StreamWriter and StreamReader class provide generic working +# interfaces which can be used to implement new encoding submodules +# very easily. See encodings/utf_8.py for an example on how this is +# done. +# + +class StreamWriter(Codec): + + def __init__(self, stream, errors='strict'): + + """ Creates a StreamWriter instance. + + stream must be a file-like object open for writing. + + The StreamWriter may use different error handling + schemes by providing the errors keyword argument. These + parameters are predefined: + + 'strict' - raise a ValueError (or a subclass) + 'ignore' - ignore the character and continue with the next + 'replace'- replace with a suitable replacement character + 'xmlcharrefreplace' - Replace with the appropriate XML + character reference. + 'backslashreplace' - Replace with backslashed escape + sequences. + 'namereplace' - Replace with \\N{...} escape sequences. + + The set of allowed parameter values can be extended via + register_error. + """ + self.stream = stream + self.errors = errors + + def write(self, object): + + """ Writes the object's contents encoded to self.stream. + """ + data, consumed = self.encode(object, self.errors) + self.stream.write(data) + + def writelines(self, list): + + """ Writes the concatenated list of strings to the stream + using .write(). + """ + self.write(''.join(list)) + + def reset(self): + + """ Flushes and resets the codec buffers used for keeping state. + + Calling this method should ensure that the data on the + output is put into a clean state, that allows appending + of new fresh data without having to rescan the whole + stream to recover state. + + """ + pass + + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + if whence == 0 and offset == 0: + self.reset() + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### + +class StreamReader(Codec): + + charbuffertype = str + + def __init__(self, stream, errors='strict'): + + """ Creates a StreamReader instance. + + stream must be a file-like object open for reading. + + The StreamReader may use different error handling + schemes by providing the errors keyword argument. These + parameters are predefined: + + 'strict' - raise a ValueError (or a subclass) + 'ignore' - ignore the character and continue with the next + 'replace'- replace with a suitable replacement character + 'backslashreplace' - Replace with backslashed escape sequences; + + The set of allowed parameter values can be extended via + register_error. + """ + self.stream = stream + self.errors = errors + self.bytebuffer = b"" + self._empty_charbuffer = self.charbuffertype() + self.charbuffer = self._empty_charbuffer + self.linebuffer = None + + def decode(self, input, errors='strict'): + raise NotImplementedError + + def read(self, size=-1, chars=-1, firstline=False): + + """ Decodes data from the stream self.stream and returns the + resulting object. + + chars indicates the number of decoded code points or bytes to + return. read() will never return more data than requested, + but it might return less, if there is not enough available. + + size indicates the approximate maximum number of decoded + bytes or code points to read for decoding. The decoder + can modify this setting as appropriate. The default value + -1 indicates to read and decode as much as possible. size + is intended to prevent having to decode huge files in one + step. + + If firstline is true, and a UnicodeDecodeError happens + after the first line terminator in the input only the first line + will be returned, the rest of the input will be kept until the + next call to read(). + + The method should use a greedy read strategy, meaning that + it should read as much data as is allowed within the + definition of the encoding and the given size, e.g. if + optional encoding endings or state markers are available + on the stream, these should be read too. + """ + # If we have lines cached, first merge them back into characters + if self.linebuffer: + self.charbuffer = self._empty_charbuffer.join(self.linebuffer) + self.linebuffer = None + + if chars < 0: + # For compatibility with other read() methods that take a + # single argument + chars = size + + # read until we get the required number of characters (if available) + while True: + # can the request be satisfied from the character buffer? + if chars >= 0: + if len(self.charbuffer) >= chars: + break + # we need more data + if size < 0: + newdata = self.stream.read() + else: + newdata = self.stream.read(size) + # decode bytes (those remaining from the last call included) + data = self.bytebuffer + newdata + if not data: + break + try: + newchars, decodedbytes = self.decode(data, self.errors) + except UnicodeDecodeError as exc: + if firstline: + newchars, decodedbytes = \ + self.decode(data[:exc.start], self.errors) + lines = newchars.splitlines(keepends=True) + if len(lines)<=1: + raise + else: + raise + # keep undecoded bytes until the next call + self.bytebuffer = data[decodedbytes:] + # put new characters in the character buffer + self.charbuffer += newchars + # there was no data available + if not newdata: + break + if chars < 0: + # Return everything we've got + result = self.charbuffer + self.charbuffer = self._empty_charbuffer + else: + # Return the first chars characters + result = self.charbuffer[:chars] + self.charbuffer = self.charbuffer[chars:] + return result + + def readline(self, size=None, keepends=True): + + """ Read one line from the input stream and return the + decoded data. + + size, if given, is passed as size argument to the + read() method. + + """ + # If we have lines cached from an earlier read, return + # them unconditionally + if self.linebuffer: + line = self.linebuffer[0] + del self.linebuffer[0] + if len(self.linebuffer) == 1: + # revert to charbuffer mode; we might need more data + # next time + self.charbuffer = self.linebuffer[0] + self.linebuffer = None + if not keepends: + line = line.splitlines(keepends=False)[0] + return line + + readsize = size or 72 + line = self._empty_charbuffer + # If size is given, we call read() only once + while True: + data = self.read(readsize, firstline=True) + if data: + # If we're at a "\r" read one extra character (which might + # be a "\n") to get a proper line ending. If the stream is + # temporarily exhausted we return the wrong line ending. + if (isinstance(data, str) and data.endswith("\r")) or \ + (isinstance(data, bytes) and data.endswith(b"\r")): + data += self.read(size=1, chars=1) + + line += data + lines = line.splitlines(keepends=True) + if lines: + if len(lines) > 1: + # More than one line result; the first line is a full line + # to return + line = lines[0] + del lines[0] + if len(lines) > 1: + # cache the remaining lines + lines[-1] += self.charbuffer + self.linebuffer = lines + self.charbuffer = None + else: + # only one remaining line, put it back into charbuffer + self.charbuffer = lines[0] + self.charbuffer + if not keepends: + line = line.splitlines(keepends=False)[0] + break + line0withend = lines[0] + line0withoutend = lines[0].splitlines(keepends=False)[0] + if line0withend != line0withoutend: # We really have a line end + # Put the rest back together and keep it until the next call + self.charbuffer = self._empty_charbuffer.join(lines[1:]) + \ + self.charbuffer + if keepends: + line = line0withend + else: + line = line0withoutend + break + # we didn't get anything or this was our only try + if not data or size is not None: + if line and not keepends: + line = line.splitlines(keepends=False)[0] + break + if readsize < 8000: + readsize *= 2 + return line + + def readlines(self, sizehint=None, keepends=True): + + """ Read all lines available on the input stream + and return them as a list. + + Line breaks are implemented using the codec's decoder + method and are included in the list entries. + + sizehint, if given, is ignored since there is no efficient + way to finding the true end-of-line. + + """ + data = self.read() + return data.splitlines(keepends) + + def reset(self): + + """ Resets the codec buffers used for keeping state. + + Note that no stream repositioning should take place. + This method is primarily intended to be able to recover + from decoding errors. + + """ + self.bytebuffer = b"" + self.charbuffer = self._empty_charbuffer + self.linebuffer = None + + def seek(self, offset, whence=0): + """ Set the input stream's current position. + + Resets the codec buffers used for keeping state. + """ + self.stream.seek(offset, whence) + self.reset() + + def __next__(self): + + """ Return the next decoded line from the input stream.""" + line = self.readline() + if line: + return line + raise StopIteration + + def __iter__(self): + return self + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### + +class StreamReaderWriter: + + """ StreamReaderWriter instances allow wrapping streams which + work in both read and write modes. + + The design is such that one can use the factory functions + returned by the codec.lookup() function to construct the + instance. + + """ + # Optional attributes set by the file wrappers below + encoding = 'unknown' + + def __init__(self, stream, Reader, Writer, errors='strict'): + + """ Creates a StreamReaderWriter instance. + + stream must be a Stream-like object. + + Reader, Writer must be factory functions or classes + providing the StreamReader, StreamWriter interface resp. + + Error handling is done in the same way as defined for the + StreamWriter/Readers. + + """ + self.stream = stream + self.reader = Reader(stream, errors) + self.writer = Writer(stream, errors) + self.errors = errors + + def read(self, size=-1): + + return self.reader.read(size) + + def readline(self, size=None): + + return self.reader.readline(size) + + def readlines(self, sizehint=None): + + return self.reader.readlines(sizehint) + + def __next__(self): + + """ Return the next decoded line from the input stream.""" + return next(self.reader) + + def __iter__(self): + return self + + def write(self, data): + + return self.writer.write(data) + + def writelines(self, list): + + return self.writer.writelines(list) + + def reset(self): + + self.reader.reset() + self.writer.reset() + + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + self.reader.reset() + if whence == 0 and offset == 0: + self.writer.reset() + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + # these are needed to make "with StreamReaderWriter(...)" work properly + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### + +class StreamRecoder: + + """ StreamRecoder instances translate data from one encoding to another. + + They use the complete set of APIs returned by the + codecs.lookup() function to implement their task. + + Data written to the StreamRecoder is first decoded into an + intermediate format (depending on the "decode" codec) and then + written to the underlying stream using an instance of the provided + Writer class. + + In the other direction, data is read from the underlying stream using + a Reader instance and then encoded and returned to the caller. + + """ + # Optional attributes set by the file wrappers below + data_encoding = 'unknown' + file_encoding = 'unknown' + + def __init__(self, stream, encode, decode, Reader, Writer, + errors='strict'): + + """ Creates a StreamRecoder instance which implements a two-way + conversion: encode and decode work on the frontend (the + data visible to .read() and .write()) while Reader and Writer + work on the backend (the data in stream). + + You can use these objects to do transparent + transcodings from e.g. latin-1 to utf-8 and back. + + stream must be a file-like object. + + encode and decode must adhere to the Codec interface; Reader and + Writer must be factory functions or classes providing the + StreamReader and StreamWriter interfaces resp. + + Error handling is done in the same way as defined for the + StreamWriter/Readers. + + """ + self.stream = stream + self.encode = encode + self.decode = decode + self.reader = Reader(stream, errors) + self.writer = Writer(stream, errors) + self.errors = errors + + def read(self, size=-1): + + data = self.reader.read(size) + data, bytesencoded = self.encode(data, self.errors) + return data + + def readline(self, size=None): + + if size is None: + data = self.reader.readline() + else: + data = self.reader.readline(size) + data, bytesencoded = self.encode(data, self.errors) + return data + + def readlines(self, sizehint=None): + + data = self.reader.read() + data, bytesencoded = self.encode(data, self.errors) + return data.splitlines(keepends=True) + + def __next__(self): + + """ Return the next decoded line from the input stream.""" + data = next(self.reader) + data, bytesencoded = self.encode(data, self.errors) + return data + + def __iter__(self): + return self + + def write(self, data): + + data, bytesdecoded = self.decode(data, self.errors) + return self.writer.write(data) + + def writelines(self, list): + + data = ''.join(list) + data, bytesdecoded = self.decode(data, self.errors) + return self.writer.write(data) + + def reset(self): + + self.reader.reset() + self.writer.reset() + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### Shortcuts + +def open(filename, mode='r', encoding=None, errors='strict', buffering=1): + + """ Open an encoded file using the given mode and return + a wrapped version providing transparent encoding/decoding. + + Note: The wrapped version will only accept the object format + defined by the codecs, i.e. Unicode objects for most builtin + codecs. Output is also codec dependent and will usually be + Unicode as well. + + Underlying encoded files are always opened in binary mode. + The default file mode is 'r', meaning to open the file in read mode. + + encoding specifies the encoding which is to be used for the + file. + + errors may be given to define the error handling. It defaults + to 'strict' which causes ValueErrors to be raised in case an + encoding error occurs. + + buffering has the same meaning as for the builtin open() API. + It defaults to line buffered. + + The returned wrapped file object provides an extra attribute + .encoding which allows querying the used encoding. This + attribute is only available if an encoding was specified as + parameter. + + """ + if encoding is not None and \ + 'b' not in mode: + # Force opening of the file in binary mode + mode = mode + 'b' + file = builtins.open(filename, mode, buffering) + if encoding is None: + return file + info = lookup(encoding) + srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors) + # Add attributes to simplify introspection + srw.encoding = encoding + return srw + +def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'): + + """ Return a wrapped version of file which provides transparent + encoding translation. + + Data written to the wrapped file is decoded according + to the given data_encoding and then encoded to the underlying + file using file_encoding. The intermediate data type + will usually be Unicode but depends on the specified codecs. + + Bytes read from the file are decoded using file_encoding and then + passed back to the caller encoded using data_encoding. + + If file_encoding is not given, it defaults to data_encoding. + + errors may be given to define the error handling. It defaults + to 'strict' which causes ValueErrors to be raised in case an + encoding error occurs. + + The returned wrapped file object provides two extra attributes + .data_encoding and .file_encoding which reflect the given + parameters of the same name. The attributes can be used for + introspection by Python programs. + + """ + if file_encoding is None: + file_encoding = data_encoding + data_info = lookup(data_encoding) + file_info = lookup(file_encoding) + sr = StreamRecoder(file, data_info.encode, data_info.decode, + file_info.streamreader, file_info.streamwriter, errors) + # Add attributes to simplify introspection + sr.data_encoding = data_encoding + sr.file_encoding = file_encoding + return sr + +### Helpers for codec lookup + +def getencoder(encoding): + + """ Lookup up the codec for the given encoding and return + its encoder function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).encode + +def getdecoder(encoding): + + """ Lookup up the codec for the given encoding and return + its decoder function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).decode + +def getincrementalencoder(encoding): + + """ Lookup up the codec for the given encoding and return + its IncrementalEncoder class or factory function. + + Raises a LookupError in case the encoding cannot be found + or the codecs doesn't provide an incremental encoder. + + """ + encoder = lookup(encoding).incrementalencoder + if encoder is None: + raise LookupError(encoding) + return encoder + +def getincrementaldecoder(encoding): + + """ Lookup up the codec for the given encoding and return + its IncrementalDecoder class or factory function. + + Raises a LookupError in case the encoding cannot be found + or the codecs doesn't provide an incremental decoder. + + """ + decoder = lookup(encoding).incrementaldecoder + if decoder is None: + raise LookupError(encoding) + return decoder + +def getreader(encoding): + + """ Lookup up the codec for the given encoding and return + its StreamReader class or factory function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).streamreader + +def getwriter(encoding): + + """ Lookup up the codec for the given encoding and return + its StreamWriter class or factory function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).streamwriter + +def iterencode(iterator, encoding, errors='strict', **kwargs): + """ + Encoding iterator. + + Encodes the input strings from the iterator using an IncrementalEncoder. + + errors and kwargs are passed through to the IncrementalEncoder + constructor. + """ + encoder = getincrementalencoder(encoding)(errors, **kwargs) + for input in iterator: + output = encoder.encode(input) + if output: + yield output + output = encoder.encode("", True) + if output: + yield output + +def iterdecode(iterator, encoding, errors='strict', **kwargs): + """ + Decoding iterator. + + Decodes the input strings from the iterator using an IncrementalDecoder. + + errors and kwargs are passed through to the IncrementalDecoder + constructor. + """ + decoder = getincrementaldecoder(encoding)(errors, **kwargs) + for input in iterator: + output = decoder.decode(input) + if output: + yield output + output = decoder.decode(b"", True) + if output: + yield output + +### Helpers for charmap-based codecs + +def make_identity_dict(rng): + + """ make_identity_dict(rng) -> dict + + Return a dictionary where elements of the rng sequence are + mapped to themselves. + + """ + return {i:i for i in rng} + +def make_encoding_map(decoding_map): + + """ Creates an encoding map from a decoding map. + + If a target mapping in the decoding map occurs multiple + times, then that target is mapped to None (undefined mapping), + causing an exception when encountered by the charmap codec + during translation. + + One example where this happens is cp875.py which decodes + multiple character to \\u001a. + + """ + m = {} + for k,v in decoding_map.items(): + if not v in m: + m[v] = k + else: + m[v] = None + return m + +### error handlers + +try: + strict_errors = lookup_error("strict") + ignore_errors = lookup_error("ignore") + replace_errors = lookup_error("replace") + xmlcharrefreplace_errors = lookup_error("xmlcharrefreplace") + backslashreplace_errors = lookup_error("backslashreplace") + namereplace_errors = lookup_error("namereplace") +except LookupError: + # In --disable-unicode builds, these error handler are missing + strict_errors = None + ignore_errors = None + replace_errors = None + xmlcharrefreplace_errors = None + backslashreplace_errors = None + namereplace_errors = None + +# Tell modulefinder that using codecs probably needs the encodings +# package +_false = 0 +if _false: + import encodings + +### Tests + +if __name__ == '__main__': + + # Make stdout translate Latin-1 output into UTF-8 output + sys.stdout = EncodedFile(sys.stdout, 'latin-1', 'utf-8') + + # Have stdin translate Latin-1 input into UTF-8 input + sys.stdin = EncodedFile(sys.stdin, 'utf-8', 'latin-1') diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py new file mode 100644 index 0000000..9a753db --- /dev/null +++ b/Lib/collections/__init__.py @@ -0,0 +1,1279 @@ +'''This module implements specialized container datatypes providing +alternatives to Python's general purpose built-in containers, dict, +list, set, and tuple. + +* namedtuple factory function for creating tuple subclasses with named fields +* deque list-like container with fast appends and pops on either end +* ChainMap dict-like class for creating a single view of multiple mappings +* Counter dict subclass for counting hashable objects +* OrderedDict dict subclass that remembers the order entries were added +* defaultdict dict subclass that calls a factory function to supply missing values +* UserDict wrapper around dictionary objects for easier dict subclassing +* UserList wrapper around list objects for easier list subclassing +* UserString wrapper around string objects for easier string subclassing + +''' + +__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', + 'UserString', 'Counter', 'OrderedDict', 'ChainMap'] + +import _collections_abc +from operator import itemgetter as _itemgetter, eq as _eq +from keyword import iskeyword as _iskeyword +import sys as _sys +import heapq as _heapq +from _weakref import proxy as _proxy +from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from reprlib import recursive_repr as _recursive_repr + +try: + from _collections import deque +except ImportError: + pass +else: + _collections_abc.MutableSequence.register(deque) + +try: + from _collections import defaultdict +except ImportError: + pass + + +def __getattr__(name): + # For backwards compatibility, continue to make the collections ABCs + # through Python 3.6 available through the collections module. + # Note, no new collections ABCs were added in Python 3.7 + if name in _collections_abc.__all__: + obj = getattr(_collections_abc, name) + import warnings + warnings.warn("Using or importing the ABCs from 'collections' instead " + "of from 'collections.abc' is deprecated, " + "and in 3.8 it will stop working", + DeprecationWarning, stacklevel=2) + globals()[name] = obj + return obj + raise AttributeError(f'module {__name__!r} has no attribute {name!r}') + +################################################################################ +### OrderedDict +################################################################################ + +class _OrderedDictKeysView(_collections_abc.KeysView): + + def __reversed__(self): + yield from reversed(self._mapping) + +class _OrderedDictItemsView(_collections_abc.ItemsView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield (key, self._mapping[key]) + +class _OrderedDictValuesView(_collections_abc.ValuesView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield self._mapping[key] + +class _Link(object): + __slots__ = 'prev', 'next', 'key', '__weakref__' + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as regular dictionaries. + + # The internal self.__map dict maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # The sentinel is in self.__hardroot with a weakref proxy in self.__root. + # The prev links are weakref proxies (to prevent circular references). + # Individual links are kept alive by the hard reference in self.__map. + # Those hard references disappear when a key is deleted from an OrderedDict. + + def __init__(*args, **kwds): + '''Initialize an ordered dictionary. The signature is the same as + regular dictionaries. Keyword argument order is preserved. + ''' + if not args: + raise TypeError("descriptor '__init__' of 'OrderedDict' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__hardroot = _Link() + self.__root = root = _proxy(self.__hardroot) + root.prev = root.next = root + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, + dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link at the end of the linked list, + # and the inherited dictionary is updated with the new key/value pair. + if key not in self: + self.__map[key] = link = Link() + root = self.__root + last = root.prev + link.prev, link.next, link.key = last, root, key + last.next = link + root.prev = proxy(link) + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which gets + # removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link = self.__map.pop(key) + link_prev = link.prev + link_next = link.next + link_prev.next = link_next + link_next.prev = link_prev + link.prev = None + link.next = None + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + # Traverse the linked list in order. + root = self.__root + curr = root.next + while curr is not root: + yield curr.key + curr = curr.next + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + # Traverse the linked list in reverse order. + root = self.__root + curr = root.prev + while curr is not root: + yield curr.key + curr = curr.prev + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + root = self.__root + root.prev = root.next = root + self.__map.clear() + dict.clear(self) + + def popitem(self, last=True): + '''Remove and return a (key, value) pair from the dictionary. + + Pairs are returned in LIFO order if last is true or FIFO order if false. + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root.prev + link_prev = link.prev + link_prev.next = root + root.prev = link_prev + else: + link = root.next + link_next = link.next + root.next = link_next + link_next.prev = root + key = link.key + del self.__map[key] + value = dict.pop(self, key) + return key, value + + def move_to_end(self, key, last=True): + '''Move an existing element to the end (or beginning if last is false). + + Raise KeyError if the element does not exist. + ''' + link = self.__map[key] + link_prev = link.prev + link_next = link.next + soft_link = link_next.prev + link_prev.next = link_next + link_next.prev = link_prev + root = self.__root + if last: + last = root.prev + link.prev = last + link.next = root + root.prev = soft_link + last.next = link + else: + first = root.next + link.prev = root + link.next = first + first.prev = soft_link + root.next = link + + def __sizeof__(self): + sizeof = _sys.getsizeof + n = len(self) + 1 # number of links including root + size = sizeof(self.__dict__) # instance dictionary + size += sizeof(self.__map) * 2 # internal dict and inherited dict + size += sizeof(self.__hardroot) * n # link objects + size += sizeof(self.__root) * n # proxy objects + return size + + update = __update = _collections_abc.MutableMapping.update + + def keys(self): + "D.keys() -> a set-like object providing a view on D's keys" + return _OrderedDictKeysView(self) + + def items(self): + "D.items() -> a set-like object providing a view on D's items" + return _OrderedDictItemsView(self) + + def values(self): + "D.values() -> an object providing a view on D's values" + return _OrderedDictValuesView(self) + + __ne__ = _collections_abc.MutableMapping.__ne__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding + value. If key is not found, d is returned if given, otherwise KeyError + is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + '''Insert key with a value of default if key is not in the dictionary. + + Return the value for key if key is in the dictionary, else default. + ''' + if key in self: + return self[key] + self[key] = default + return default + + @_recursive_repr() + def __repr__(self): + 'od.__repr__() <==> repr(od)' + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self.items())) + + def __reduce__(self): + 'Return state information for pickling' + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + return self.__class__, (), inst_dict or None, None, iter(self.items()) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''Create a new ordered dictionary with keys from iterable and values set to value. + ''' + self = cls() + for key in iterable: + self[key] = value + return self + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return dict.__eq__(self, other) and all(map(_eq, self, other)) + return dict.__eq__(self, other) + + +try: + from _collections import OrderedDict +except ImportError: + # Leave the pure Python version in place. + pass + + +################################################################################ +### namedtuple +################################################################################ + +_nt_itemgetters = {} + +def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None): + """Returns a new subclass of tuple with named fields. + + >>> Point = namedtuple('Point', ['x', 'y']) + >>> Point.__doc__ # docstring for the new class + 'Point(x, y)' + >>> p = Point(11, y=22) # instantiate with positional args or keywords + >>> p[0] + p[1] # indexable like a plain tuple + 33 + >>> x, y = p # unpack like a regular tuple + >>> x, y + (11, 22) + >>> p.x + p.y # fields also accessible by name + 33 + >>> d = p._asdict() # convert to a dictionary + >>> d['x'] + 11 + >>> Point(**d) # convert from a dictionary + Point(x=11, y=22) + >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields + Point(x=100, y=22) + + """ + + # Validate the field names. At the user's option, either generate an error + # message or automatically replace the field name with a valid name. + if isinstance(field_names, str): + field_names = field_names.replace(',', ' ').split() + field_names = list(map(str, field_names)) + typename = _sys.intern(str(typename)) + + if rename: + seen = set() + for index, name in enumerate(field_names): + if (not name.isidentifier() + or _iskeyword(name) + or name.startswith('_') + or name in seen): + field_names[index] = f'_{index}' + seen.add(name) + + for name in [typename] + field_names: + if type(name) is not str: + raise TypeError('Type names and field names must be strings') + if not name.isidentifier(): + raise ValueError('Type names and field names must be valid ' + f'identifiers: {name!r}') + if _iskeyword(name): + raise ValueError('Type names and field names cannot be a ' + f'keyword: {name!r}') + + seen = set() + for name in field_names: + if name.startswith('_') and not rename: + raise ValueError('Field names cannot start with an underscore: ' + f'{name!r}') + if name in seen: + raise ValueError(f'Encountered duplicate field name: {name!r}') + seen.add(name) + + field_defaults = {} + if defaults is not None: + defaults = tuple(defaults) + if len(defaults) > len(field_names): + raise TypeError('Got more default values than field names') + field_defaults = dict(reversed(list(zip(reversed(field_names), + reversed(defaults))))) + + # Variables used in the methods and docstrings + field_names = tuple(map(_sys.intern, field_names)) + num_fields = len(field_names) + arg_list = repr(field_names).replace("'", "")[1:-1] + repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')' + tuple_new = tuple.__new__ + _len = len + + # Create all the named tuple methods to be added to the class namespace + + s = f'def __new__(_cls, {arg_list}): return _tuple_new(_cls, ({arg_list}))' + namespace = {'_tuple_new': tuple_new, '__name__': f'namedtuple_{typename}'} + # Note: exec() has the side-effect of interning the field names + exec(s, namespace) + __new__ = namespace['__new__'] + __new__.__doc__ = f'Create new instance of {typename}({arg_list})' + if defaults is not None: + __new__.__defaults__ = defaults + + @classmethod + def _make(cls, iterable): + result = tuple_new(cls, iterable) + if _len(result) != num_fields: + raise TypeError(f'Expected {num_fields} arguments, got {len(result)}') + return result + + _make.__func__.__doc__ = (f'Make a new {typename} object from a sequence ' + 'or iterable') + + def _replace(_self, **kwds): + result = _self._make(map(kwds.pop, field_names, _self)) + if kwds: + raise ValueError(f'Got unexpected field names: {list(kwds)!r}') + return result + + _replace.__doc__ = (f'Return a new {typename} object replacing specified ' + 'fields with new values') + + def __repr__(self): + 'Return a nicely formatted representation string' + return self.__class__.__name__ + repr_fmt % self + + def _asdict(self): + 'Return a new OrderedDict which maps field names to their values.' + return OrderedDict(zip(self._fields, self)) + + def __getnewargs__(self): + 'Return self as a plain tuple. Used by copy and pickle.' + return tuple(self) + + # Modify function metadata to help with introspection and debugging + + for method in (__new__, _make.__func__, _replace, + __repr__, _asdict, __getnewargs__): + method.__qualname__ = f'{typename}.{method.__name__}' + + # Build-up the class namespace dictionary + # and use type() to build the result class + class_namespace = { + '__doc__': f'{typename}({arg_list})', + '__slots__': (), + '_fields': field_names, + '_fields_defaults': field_defaults, + '__new__': __new__, + '_make': _make, + '_replace': _replace, + '__repr__': __repr__, + '_asdict': _asdict, + '__getnewargs__': __getnewargs__, + } + cache = _nt_itemgetters + for index, name in enumerate(field_names): + try: + itemgetter_object, doc = cache[index] + except KeyError: + itemgetter_object = _itemgetter(index) + doc = f'Alias for field number {index}' + cache[index] = itemgetter_object, doc + class_namespace[name] = property(itemgetter_object, doc=doc) + + result = type(typename, (tuple,), class_namespace) + + # For pickling to work, the __module__ variable needs to be set to the frame + # where the named tuple is created. Bypass this step in environments where + # sys._getframe is not defined (Jython for example) or sys._getframe is not + # defined for arguments greater than 0 (IronPython), or where the user has + # specified a particular module. + if module is None: + try: + module = _sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass + if module is not None: + result.__module__ = module + + return result + + +######################################################################## +### Counter +######################################################################## + +def _count_elements(mapping, iterable): + 'Tally elements from the iterable.' + mapping_get = mapping.get + for elem in iterable: + mapping[elem] = mapping_get(elem, 0) + 1 + +try: # Load C helper function if available + from _collections import _count_elements +except ImportError: + pass + +class Counter(dict): + '''Dict subclass for counting hashable items. Sometimes called a bag + or multiset. Elements are stored as dictionary keys and their counts + are stored as dictionary values. + + >>> c = Counter('abcdeabcdabcaba') # count elements from a string + + >>> c.most_common(3) # three most common elements + [('a', 5), ('b', 4), ('c', 3)] + >>> sorted(c) # list all unique elements + ['a', 'b', 'c', 'd', 'e'] + >>> ''.join(sorted(c.elements())) # list elements with repetitions + 'aaaaabbbbcccdde' + >>> sum(c.values()) # total of all counts + 15 + + >>> c['a'] # count of letter 'a' + 5 + >>> for elem in 'shazam': # update counts from an iterable + ... c[elem] += 1 # by adding 1 to each element's count + >>> c['a'] # now there are seven 'a' + 7 + >>> del c['b'] # remove all 'b' + >>> c['b'] # now there are zero 'b' + 0 + + >>> d = Counter('simsalabim') # make another counter + >>> c.update(d) # add in the second counter + >>> c['a'] # now there are nine 'a' + 9 + + >>> c.clear() # empty the counter + >>> c + Counter() + + Note: If a count is set to zero or reduced to zero, it will remain + in the counter until the entry is deleted or the counter is cleared: + + >>> c = Counter('aaabbc') + >>> c['b'] -= 2 # reduce the count of 'b' by two + >>> c.most_common() # 'b' is still in, but its count is zero + [('a', 3), ('c', 1), ('b', 0)] + + ''' + # References: + # http://en.wikipedia.org/wiki/Multiset + # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html + # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm + # http://code.activestate.com/recipes/259174/ + # Knuth, TAOCP Vol. II section 4.6.3 + + def __init__(*args, **kwds): + '''Create a new, empty Counter object. And if given, count elements + from an input iterable. Or, initialize the count from another mapping + of elements to their counts. + + >>> c = Counter() # a new, empty counter + >>> c = Counter('gallahad') # a new counter from an iterable + >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping + >>> c = Counter(a=4, b=2) # a new counter from keyword args + + ''' + if not args: + raise TypeError("descriptor '__init__' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + super(Counter, self).__init__() + self.update(*args, **kwds) + + def __missing__(self, key): + 'The count of elements not in the Counter is zero.' + # Needed so that self[missing_item] does not raise KeyError + return 0 + + def most_common(self, n=None): + '''List the n most common elements and their counts from the most + common to the least. If n is None, then list all element counts. + + >>> Counter('abcdeabcdabcaba').most_common(3) + [('a', 5), ('b', 4), ('c', 3)] + + ''' + # Emulate Bag.sortedByCount from Smalltalk + if n is None: + return sorted(self.items(), key=_itemgetter(1), reverse=True) + return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) + + def elements(self): + '''Iterator over elements repeating each as many times as its count. + + >>> c = Counter('ABCABC') + >>> sorted(c.elements()) + ['A', 'A', 'B', 'B', 'C', 'C'] + + # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 + >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) + >>> product = 1 + >>> for factor in prime_factors.elements(): # loop over factors + ... product *= factor # and multiply them + >>> product + 1836 + + Note, if an element's count has been set to zero or is a negative + number, elements() will ignore it. + + ''' + # Emulate Bag.do from Smalltalk and Multiset.begin from C++. + return _chain.from_iterable(_starmap(_repeat, self.items())) + + # Override dict methods where necessary + + @classmethod + def fromkeys(cls, iterable, v=None): + # There is no equivalent method for counters because setting v=1 + # means that no element can have a count greater than one. + raise NotImplementedError( + 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') + + def update(*args, **kwds): + '''Like dict.update() but add counts instead of replacing them. + + Source can be an iterable, a dictionary, or another Counter instance. + + >>> c = Counter('which') + >>> c.update('witch') # add elements from another iterable + >>> d = Counter('watch') + >>> c.update(d) # add elements from another counter + >>> c['h'] # four 'h' in which, witch, and watch + 4 + + ''' + # The regular dict.update() operation makes no sense here because the + # replace behavior results in the some of original untouched counts + # being mixed-in with all of the other counts for a mismash that + # doesn't have a straight-forward interpretation in most counting + # contexts. Instead, we implement straight-addition. Both the inputs + # and outputs are allowed to contain zero and negative counts. + + if not args: + raise TypeError("descriptor 'update' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + iterable = args[0] if args else None + if iterable is not None: + if isinstance(iterable, _collections_abc.Mapping): + if self: + self_get = self.get + for elem, count in iterable.items(): + self[elem] = count + self_get(elem, 0) + else: + super(Counter, self).update(iterable) # fast path when counter is empty + else: + _count_elements(self, iterable) + if kwds: + self.update(kwds) + + def subtract(*args, **kwds): + '''Like dict.update() but subtracts counts instead of replacing them. + Counts can be reduced below zero. Both the inputs and outputs are + allowed to contain zero and negative counts. + + Source can be an iterable, a dictionary, or another Counter instance. + + >>> c = Counter('which') + >>> c.subtract('witch') # subtract elements from another iterable + >>> c.subtract(Counter('watch')) # subtract elements from another counter + >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch + 0 + >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch + -1 + + ''' + if not args: + raise TypeError("descriptor 'subtract' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + iterable = args[0] if args else None + if iterable is not None: + self_get = self.get + if isinstance(iterable, _collections_abc.Mapping): + for elem, count in iterable.items(): + self[elem] = self_get(elem, 0) - count + else: + for elem in iterable: + self[elem] = self_get(elem, 0) - 1 + if kwds: + self.subtract(kwds) + + def copy(self): + 'Return a shallow copy.' + return self.__class__(self) + + def __reduce__(self): + return self.__class__, (dict(self),) + + def __delitem__(self, elem): + 'Like dict.__delitem__() but does not raise KeyError for missing values.' + if elem in self: + super().__delitem__(elem) + + def __repr__(self): + if not self: + return '%s()' % self.__class__.__name__ + try: + items = ', '.join(map('%r: %r'.__mod__, self.most_common())) + return '%s({%s})' % (self.__class__.__name__, items) + except TypeError: + # handle case where values are not orderable + return '{0}({1!r})'.format(self.__class__.__name__, dict(self)) + + # Multiset-style mathematical operations discussed in: + # Knuth TAOCP Volume II section 4.6.3 exercise 19 + # and at http://en.wikipedia.org/wiki/Multiset + # + # Outputs guaranteed to only include positive counts. + # + # To strip negative and zero counts, add-in an empty counter: + # c += Counter() + + def __add__(self, other): + '''Add counts from two counters. + + >>> Counter('abbb') + Counter('bcc') + Counter({'b': 4, 'c': 2, 'a': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + newcount = count + other[elem] + if newcount > 0: + result[elem] = newcount + for elem, count in other.items(): + if elem not in self and count > 0: + result[elem] = count + return result + + def __sub__(self, other): + ''' Subtract count, but keep only results with positive counts. + + >>> Counter('abbbc') - Counter('bccd') + Counter({'b': 2, 'a': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + newcount = count - other[elem] + if newcount > 0: + result[elem] = newcount + for elem, count in other.items(): + if elem not in self and count < 0: + result[elem] = 0 - count + return result + + def __or__(self, other): + '''Union is the maximum of value in either of the input counters. + + >>> Counter('abbb') | Counter('bcc') + Counter({'b': 3, 'c': 2, 'a': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + other_count = other[elem] + newcount = other_count if count < other_count else count + if newcount > 0: + result[elem] = newcount + for elem, count in other.items(): + if elem not in self and count > 0: + result[elem] = count + return result + + def __and__(self, other): + ''' Intersection is the minimum of corresponding counts. + + >>> Counter('abbb') & Counter('bcc') + Counter({'b': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + other_count = other[elem] + newcount = count if count < other_count else other_count + if newcount > 0: + result[elem] = newcount + return result + + def __pos__(self): + 'Adds an empty counter, effectively stripping negative and zero counts' + result = Counter() + for elem, count in self.items(): + if count > 0: + result[elem] = count + return result + + def __neg__(self): + '''Subtracts from an empty counter. Strips positive and zero counts, + and flips the sign on negative counts. + + ''' + result = Counter() + for elem, count in self.items(): + if count < 0: + result[elem] = 0 - count + return result + + def _keep_positive(self): + '''Internal method to strip elements with a negative or zero count''' + nonpositive = [elem for elem, count in self.items() if not count > 0] + for elem in nonpositive: + del self[elem] + return self + + def __iadd__(self, other): + '''Inplace add from another counter, keeping only positive counts. + + >>> c = Counter('abbb') + >>> c += Counter('bcc') + >>> c + Counter({'b': 4, 'c': 2, 'a': 1}) + + ''' + for elem, count in other.items(): + self[elem] += count + return self._keep_positive() + + def __isub__(self, other): + '''Inplace subtract counter, but keep only results with positive counts. + + >>> c = Counter('abbbc') + >>> c -= Counter('bccd') + >>> c + Counter({'b': 2, 'a': 1}) + + ''' + for elem, count in other.items(): + self[elem] -= count + return self._keep_positive() + + def __ior__(self, other): + '''Inplace union is the maximum of value from either counter. + + >>> c = Counter('abbb') + >>> c |= Counter('bcc') + >>> c + Counter({'b': 3, 'c': 2, 'a': 1}) + + ''' + for elem, other_count in other.items(): + count = self[elem] + if other_count > count: + self[elem] = other_count + return self._keep_positive() + + def __iand__(self, other): + '''Inplace intersection is the minimum of corresponding counts. + + >>> c = Counter('abbb') + >>> c &= Counter('bcc') + >>> c + Counter({'b': 1}) + + ''' + for elem, count in self.items(): + other_count = other[elem] + if other_count < count: + self[elem] = other_count + return self._keep_positive() + + +######################################################################## +### ChainMap +######################################################################## + +class ChainMap(_collections_abc.MutableMapping): + ''' A ChainMap groups multiple dicts (or other mappings) together + to create a single, updateable view. + + The underlying mappings are stored in a list. That list is public and can + be accessed or updated using the *maps* attribute. There is no other + state. + + Lookups search the underlying mappings successively until a key is found. + In contrast, writes, updates, and deletions only operate on the first + mapping. + + ''' + + def __init__(self, *maps): + '''Initialize a ChainMap by setting *maps* to the given mappings. + If no mappings are provided, a single empty dictionary is used. + + ''' + self.maps = list(maps) or [{}] # always at least one map + + def __missing__(self, key): + raise KeyError(key) + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] # can't use 'key in mapping' with defaultdict + except KeyError: + pass + return self.__missing__(key) # support subclasses that define __missing__ + + def get(self, key, default=None): + return self[key] if key in self else default + + def __len__(self): + return len(set().union(*self.maps)) # reuses stored hash values if possible + + def __iter__(self): + d = {} + for mapping in reversed(self.maps): + d.update(mapping) # reuses stored hash values if possible + return iter(d) + + def __contains__(self, key): + return any(key in m for m in self.maps) + + def __bool__(self): + return any(self.maps) + + @_recursive_repr() + def __repr__(self): + return '{0.__class__.__name__}({1})'.format( + self, ', '.join(map(repr, self.maps))) + + @classmethod + def fromkeys(cls, iterable, *args): + 'Create a ChainMap with a single dict created from the iterable.' + return cls(dict.fromkeys(iterable, *args)) + + def copy(self): + 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' + return self.__class__(self.maps[0].copy(), *self.maps[1:]) + + __copy__ = copy + + def new_child(self, m=None): # like Django's Context.push() + '''New ChainMap with a new map followed by all previous maps. + If no map is provided, an empty dict is used. + ''' + if m is None: + m = {} + return self.__class__(m, *self.maps) + + @property + def parents(self): # like Django's Context.pop() + 'New ChainMap from maps[1:].' + return self.__class__(*self.maps[1:]) + + def __setitem__(self, key, value): + self.maps[0][key] = value + + def __delitem__(self, key): + try: + del self.maps[0][key] + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def popitem(self): + 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' + try: + return self.maps[0].popitem() + except KeyError: + raise KeyError('No keys found in the first mapping.') + + def pop(self, key, *args): + 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' + try: + return self.maps[0].pop(key, *args) + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def clear(self): + 'Clear maps[0], leaving maps[1:] intact.' + self.maps[0].clear() + + +################################################################################ +### UserDict +################################################################################ + +class UserDict(_collections_abc.MutableMapping): + + # Start by filling-out the abstract methods + def __init__(*args, **kwargs): + if not args: + raise TypeError("descriptor '__init__' of 'UserDict' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + if args: + dict = args[0] + elif 'dict' in kwargs: + dict = kwargs.pop('dict') + import warnings + warnings.warn("Passing 'dict' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + dict = None + self.data = {} + if dict is not None: + self.update(dict) + if len(kwargs): + self.update(kwargs) + def __len__(self): return len(self.data) + def __getitem__(self, key): + if key in self.data: + return self.data[key] + if hasattr(self.__class__, "__missing__"): + return self.__class__.__missing__(self, key) + raise KeyError(key) + def __setitem__(self, key, item): self.data[key] = item + def __delitem__(self, key): del self.data[key] + def __iter__(self): + return iter(self.data) + + # Modify __contains__ to work correctly when __missing__ is present + def __contains__(self, key): + return key in self.data + + # Now, add the methods in dicts but not in MutableMapping + def __repr__(self): return repr(self.data) + def copy(self): + if self.__class__ is UserDict: + return UserDict(self.data.copy()) + import copy + data = self.data + try: + self.data = {} + c = copy.copy(self) + finally: + self.data = data + c.update(self) + return c + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + + + +################################################################################ +### UserList +################################################################################ + +class UserList(_collections_abc.MutableSequence): + """A more or less complete user-defined wrapper around list objects.""" + def __init__(self, initlist=None): + self.data = [] + if initlist is not None: + # XXX should this accept an arbitrary sequence? + if type(initlist) == type(self.data): + self.data[:] = initlist + elif isinstance(initlist, UserList): + self.data[:] = initlist.data[:] + else: + self.data = list(initlist) + def __repr__(self): return repr(self.data) + def __lt__(self, other): return self.data < self.__cast(other) + def __le__(self, other): return self.data <= self.__cast(other) + def __eq__(self, other): return self.data == self.__cast(other) + def __gt__(self, other): return self.data > self.__cast(other) + def __ge__(self, other): return self.data >= self.__cast(other) + def __cast(self, other): + return other.data if isinstance(other, UserList) else other + def __contains__(self, item): return item in self.data + def __len__(self): return len(self.data) + def __getitem__(self, i): return self.data[i] + def __setitem__(self, i, item): self.data[i] = item + def __delitem__(self, i): del self.data[i] + def __add__(self, other): + if isinstance(other, UserList): + return self.__class__(self.data + other.data) + elif isinstance(other, type(self.data)): + return self.__class__(self.data + other) + return self.__class__(self.data + list(other)) + def __radd__(self, other): + if isinstance(other, UserList): + return self.__class__(other.data + self.data) + elif isinstance(other, type(self.data)): + return self.__class__(other + self.data) + return self.__class__(list(other) + self.data) + def __iadd__(self, other): + if isinstance(other, UserList): + self.data += other.data + elif isinstance(other, type(self.data)): + self.data += other + else: + self.data += list(other) + return self + def __mul__(self, n): + return self.__class__(self.data*n) + __rmul__ = __mul__ + def __imul__(self, n): + self.data *= n + return self + def append(self, item): self.data.append(item) + def insert(self, i, item): self.data.insert(i, item) + def pop(self, i=-1): return self.data.pop(i) + def remove(self, item): self.data.remove(item) + def clear(self): self.data.clear() + def copy(self): return self.__class__(self) + def count(self, item): return self.data.count(item) + def index(self, item, *args): return self.data.index(item, *args) + def reverse(self): self.data.reverse() + def sort(self, *args, **kwds): self.data.sort(*args, **kwds) + def extend(self, other): + if isinstance(other, UserList): + self.data.extend(other.data) + else: + self.data.extend(other) + + + +################################################################################ +### UserString +################################################################################ + +class UserString(_collections_abc.Sequence): + def __init__(self, seq): + if isinstance(seq, str): + self.data = seq + elif isinstance(seq, UserString): + self.data = seq.data[:] + else: + self.data = str(seq) + def __str__(self): return str(self.data) + def __repr__(self): return repr(self.data) + def __int__(self): return int(self.data) + def __float__(self): return float(self.data) + def __complex__(self): return complex(self.data) + def __hash__(self): return hash(self.data) + def __getnewargs__(self): + return (self.data[:],) + + def __eq__(self, string): + if isinstance(string, UserString): + return self.data == string.data + return self.data == string + def __lt__(self, string): + if isinstance(string, UserString): + return self.data < string.data + return self.data < string + def __le__(self, string): + if isinstance(string, UserString): + return self.data <= string.data + return self.data <= string + def __gt__(self, string): + if isinstance(string, UserString): + return self.data > string.data + return self.data > string + def __ge__(self, string): + if isinstance(string, UserString): + return self.data >= string.data + return self.data >= string + + def __contains__(self, char): + if isinstance(char, UserString): + char = char.data + return char in self.data + + def __len__(self): return len(self.data) + def __getitem__(self, index): return self.__class__(self.data[index]) + def __add__(self, other): + if isinstance(other, UserString): + return self.__class__(self.data + other.data) + elif isinstance(other, str): + return self.__class__(self.data + other) + return self.__class__(self.data + str(other)) + def __radd__(self, other): + if isinstance(other, str): + return self.__class__(other + self.data) + return self.__class__(str(other) + self.data) + def __mul__(self, n): + return self.__class__(self.data*n) + __rmul__ = __mul__ + def __mod__(self, args): + return self.__class__(self.data % args) + def __rmod__(self, format): + return self.__class__(format % args) + + # the following methods are defined in alphabetical order: + def capitalize(self): return self.__class__(self.data.capitalize()) + def casefold(self): + return self.__class__(self.data.casefold()) + def center(self, width, *args): + return self.__class__(self.data.center(width, *args)) + def count(self, sub, start=0, end=_sys.maxsize): + if isinstance(sub, UserString): + sub = sub.data + return self.data.count(sub, start, end) + def encode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.encode(encoding, errors)) + return self.__class__(self.data.encode(encoding)) + return self.__class__(self.data.encode()) + def endswith(self, suffix, start=0, end=_sys.maxsize): + return self.data.endswith(suffix, start, end) + def expandtabs(self, tabsize=8): + return self.__class__(self.data.expandtabs(tabsize)) + def find(self, sub, start=0, end=_sys.maxsize): + if isinstance(sub, UserString): + sub = sub.data + return self.data.find(sub, start, end) + def format(self, *args, **kwds): + return self.data.format(*args, **kwds) + def format_map(self, mapping): + return self.data.format_map(mapping) + def index(self, sub, start=0, end=_sys.maxsize): + return self.data.index(sub, start, end) + def isalpha(self): return self.data.isalpha() + def isalnum(self): return self.data.isalnum() + def isascii(self): return self.data.isascii() + def isdecimal(self): return self.data.isdecimal() + def isdigit(self): return self.data.isdigit() + def isidentifier(self): return self.data.isidentifier() + def islower(self): return self.data.islower() + def isnumeric(self): return self.data.isnumeric() + def isprintable(self): return self.data.isprintable() + def isspace(self): return self.data.isspace() + def istitle(self): return self.data.istitle() + def isupper(self): return self.data.isupper() + def join(self, seq): return self.data.join(seq) + def ljust(self, width, *args): + return self.__class__(self.data.ljust(width, *args)) + def lower(self): return self.__class__(self.data.lower()) + def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) + maketrans = str.maketrans + def partition(self, sep): + return self.data.partition(sep) + def replace(self, old, new, maxsplit=-1): + if isinstance(old, UserString): + old = old.data + if isinstance(new, UserString): + new = new.data + return self.__class__(self.data.replace(old, new, maxsplit)) + def rfind(self, sub, start=0, end=_sys.maxsize): + if isinstance(sub, UserString): + sub = sub.data + return self.data.rfind(sub, start, end) + def rindex(self, sub, start=0, end=_sys.maxsize): + return self.data.rindex(sub, start, end) + def rjust(self, width, *args): + return self.__class__(self.data.rjust(width, *args)) + def rpartition(self, sep): + return self.data.rpartition(sep) + def rstrip(self, chars=None): + return self.__class__(self.data.rstrip(chars)) + def split(self, sep=None, maxsplit=-1): + return self.data.split(sep, maxsplit) + def rsplit(self, sep=None, maxsplit=-1): + return self.data.rsplit(sep, maxsplit) + def splitlines(self, keepends=False): return self.data.splitlines(keepends) + def startswith(self, prefix, start=0, end=_sys.maxsize): + return self.data.startswith(prefix, start, end) + def strip(self, chars=None): return self.__class__(self.data.strip(chars)) + def swapcase(self): return self.__class__(self.data.swapcase()) + def title(self): return self.__class__(self.data.title()) + def translate(self, *args): + return self.__class__(self.data.translate(*args)) + def upper(self): return self.__class__(self.data.upper()) + def zfill(self, width): return self.__class__(self.data.zfill(width)) diff --git a/Lib/collections/__pycache__/__init__.cpython-37.pyc b/Lib/collections/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f907d766b307dc12470e1df5c9ad281397460554 GIT binary patch literal 46633 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 b%6j9UcOEL_<=V}Ac*cME@#grs@#p?OTPRuA literal 0 HcmV?d00001 diff --git a/Lib/collections/__pycache__/abc.cpython-37.pyc b/Lib/collections/__pycache__/abc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..828f9152c209e9c288827022364df5c902be020b GIT binary patch literal 228 zcmZ?b<>g`k0=7p+(QZKcF^B^LOhASM5En}Ti4=wu#vFza5Y3dskjogw$jFew9L%7} z@)9V^pvicPQ42`0$Hyn;SX$w^Hv$;{6yj!#TVE@B3%T**+x3Z%fq zFF$9in9$, is about +# to be pickled, the (, ) tuple is looked up here to see +# if it is a registered extension code for it. Extension codes are +# universal, so that the meaning of a pickle does not depend on +# context. (There are also some codes reserved for local use that +# don't have this restriction.) Codes are positive ints; 0 is +# reserved. + +_extension_registry = {} # key -> code +_inverted_registry = {} # code -> key +_extension_cache = {} # code -> object +# Don't ever rebind those names: pickling grabs a reference to them when +# it's initialized, and won't see a rebinding. + +def add_extension(module, name, code): + """Register an extension code.""" + code = int(code) + if not 1 <= code <= 0x7fffffff: + raise ValueError("code out of range") + key = (module, name) + if (_extension_registry.get(key) == code and + _inverted_registry.get(code) == key): + return # Redundant registrations are benign + if key in _extension_registry: + raise ValueError("key %s is already registered with code %s" % + (key, _extension_registry[key])) + if code in _inverted_registry: + raise ValueError("code %s is already in use for key %s" % + (code, _inverted_registry[code])) + _extension_registry[key] = code + _inverted_registry[code] = key + +def remove_extension(module, name, code): + """Unregister an extension code. For testing only.""" + key = (module, name) + if (_extension_registry.get(key) != code or + _inverted_registry.get(code) != key): + raise ValueError("key %s is not registered with code %s" % + (key, code)) + del _extension_registry[key] + del _inverted_registry[code] + if code in _extension_cache: + del _extension_cache[code] + +def clear_extension_cache(): + _extension_cache.clear() + +# Standard extension code assignments + +# Reserved ranges + +# First Last Count Purpose +# 1 127 127 Reserved for Python standard library +# 128 191 64 Reserved for Zope +# 192 239 48 Reserved for 3rd parties +# 240 255 16 Reserved for private use (will never be assigned) +# 256 Inf Inf Reserved for future assignment + +# Extension codes are assigned by the Python Software Foundation. diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py new file mode 100644 index 0000000..29fc1da --- /dev/null +++ b/Lib/distutils/__init__.py @@ -0,0 +1,101 @@ +import os +import sys +import warnings +import imp +import opcode # opcode is not a virtualenv module, so we can use it to find the stdlib + # Important! To work on pypy, this must be a module that resides in the + # lib-python/modified-x.y.z directory + +dirname = os.path.dirname + +distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils') +if os.path.normpath(distutils_path) == os.path.dirname(os.path.normpath(__file__)): + warnings.warn( + "The virtualenv distutils package at %s appears to be in the same location as the system distutils?") +else: + __path__.insert(0, distutils_path) + real_distutils = imp.load_module("_virtualenv_distutils", None, distutils_path, ('', '', imp.PKG_DIRECTORY)) + # Copy the relevant attributes + try: + __revision__ = real_distutils.__revision__ + except AttributeError: + pass + __version__ = real_distutils.__version__ + +from distutils import dist, sysconfig + +try: + basestring +except NameError: + basestring = str + +## patch build_ext (distutils doesn't know how to get the libs directory +## path on windows - it hardcodes the paths around the patched sys.prefix) + +if sys.platform == 'win32': + from distutils.command.build_ext import build_ext as old_build_ext + class build_ext(old_build_ext): + def finalize_options (self): + if self.library_dirs is None: + self.library_dirs = [] + elif isinstance(self.library_dirs, basestring): + self.library_dirs = self.library_dirs.split(os.pathsep) + + self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs")) + old_build_ext.finalize_options(self) + + from distutils.command import build_ext as build_ext_module + build_ext_module.build_ext = build_ext + +## distutils.dist patches: + +old_find_config_files = dist.Distribution.find_config_files +def find_config_files(self): + found = old_find_config_files(self) + system_distutils = os.path.join(distutils_path, 'distutils.cfg') + #if os.path.exists(system_distutils): + # found.insert(0, system_distutils) + # What to call the per-user config file + if os.name == 'posix': + user_filename = ".pydistutils.cfg" + else: + user_filename = "pydistutils.cfg" + user_filename = os.path.join(sys.prefix, user_filename) + if os.path.isfile(user_filename): + for item in list(found): + if item.endswith('pydistutils.cfg'): + found.remove(item) + found.append(user_filename) + return found +dist.Distribution.find_config_files = find_config_files + +## distutils.sysconfig patches: + +old_get_python_inc = sysconfig.get_python_inc +def sysconfig_get_python_inc(plat_specific=0, prefix=None): + if prefix is None: + prefix = sys.real_prefix + return old_get_python_inc(plat_specific, prefix) +sysconfig_get_python_inc.__doc__ = old_get_python_inc.__doc__ +sysconfig.get_python_inc = sysconfig_get_python_inc + +old_get_python_lib = sysconfig.get_python_lib +def sysconfig_get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + if standard_lib and prefix is None: + prefix = sys.real_prefix + return old_get_python_lib(plat_specific, standard_lib, prefix) +sysconfig_get_python_lib.__doc__ = old_get_python_lib.__doc__ +sysconfig.get_python_lib = sysconfig_get_python_lib + +old_get_config_vars = sysconfig.get_config_vars +def sysconfig_get_config_vars(*args): + real_vars = old_get_config_vars(*args) + if sys.platform == 'win32': + lib_dir = os.path.join(sys.real_prefix, "libs") + if isinstance(real_vars, dict) and 'LIBDIR' not in real_vars: + real_vars['LIBDIR'] = lib_dir # asked for all + elif isinstance(real_vars, list) and 'LIBDIR' in args: + real_vars = real_vars + [lib_dir] # asked for list + return real_vars +sysconfig_get_config_vars.__doc__ = old_get_config_vars.__doc__ +sysconfig.get_config_vars = sysconfig_get_config_vars diff --git a/Lib/distutils/__pycache__/__init__.cpython-37.pyc b/Lib/distutils/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7b446a080ac773373261f32f4a13c7f306d1dc6 GIT binary patch literal 2845 zcma)8-E!N;72X9v5QIpIk}O%Vm4r_GNB?M&b~2giWZWdS$93aTJa(GY8?_jSyOaTe z0JB)hmWH~LuiHLBhq~+w^kMe4SH0;2^s3(hC0bT48gTaaoIQJX&-b0>*R58_@NF%a zAOAYf*uQ9S`UU8GiBkTZGbWkj857f%3to*K;Z&_F+^Y42r&wA`ec@9(saLhHyfirG z(m8fSqnZg-|k@?80zaEDu-23TOL)y2u&U ztYXb7*8FF>M!hF4o~+~PC0XBb{>Jq!tPZlv!!_|fXOEa{$nXu5p?d$w6>F931IRvv zk8A3~XiY7r-Smq1NY2UT8z!!(D>M^bQ7h@k;;LMdE!lp<#Wi&`y{@iBC~7787}6W! zro15MWe3upx(R6y(jKHYAiX7S%LTazi+9v*$nHRP2eMm|KWDw=e^b;pY(plc*)>U4 z9&CO0Qg!zdZFb{K<$K+kq&tfHJMp&a#-@9%?8c*!ignpFMR!Yele}xNu8fDOn-%@o zBt_nhA*IRv(x~BEL%$Wv(c2B8*#?&N9P820Hn65&yC$J_$@C4GE!yH8VG9ju~N4GHmN^Xxd76Pm-;& z*AmSv+0wDz$ANWe!=y~|(!_aR*>Ec^RcUmRu^vrW zFD;VXy0{@br&XLqBdrF>YuhStJF`2ook5bvS#qGFVnop>afM!~vcW%?UWQ-){oVcF zZ2kdu%gu)y-@oX7`uV0*<&G&vo6ij*{q3I8gRFRU_eo;ZS5F^r!u`!ztTv-4$rBSr z>!W?W1asF>$|fqtLmu!Z?>LwE!KIl$>*w9s=y^7Xq8x~cA{$20u#meM^_x-j6Tml> zRK_cZ&r~berV8pc+LaIx@OOh;!<>gw1^ECSgTNi}LvDELP&g$&b`BkkYSKXhxh~y9 zH}|A>=$>f!X?^TMXF3kh=X&q;Rnr*rBmRK>Y4y+>dy`Oln14FvlesZ^oc;9l2Zm9T z^f`I}LT%%qHM_X={s2K96=m}Jpo7bMM{qEIZlc$+%M?~zo{Xl1KtEHZp2L}Rn=0gA zX4^A6(G(j56abFr}tKXdpq*eq93F`%REh1_>M-T_Y9zzY>k27&*~ zsp3b=#^5z5+BPhuC^}=z967jMzR`25gX#sS*+sgpZDpd-zIj>XKxrRYr8UZ86O|*? zPX@_wJ@oqI8-3Kya7JdwTrZCCyiq!-e08S2j-4aQ zMgPZJa15up2|J=m$w9_iMwB;xxyR6cj`b%VH_7AM823@C@6_W*7?poUMa=jMn=(Vv zV=9cBdXpM>;8SV?OX_280wlwG(jD`iy1qAd5D)hYN|hvQKqeq#JH8fUK6bYGMOduR z?`>$hJOS8kmBN4W`0EFcpY=k!bQ-7=SnuI6nF2PTU=0dAJO}bBz?%ME&@0h5x{Gel zwO*{ZOVOxuAz2Z1Y(-i2e2CwBH^gT){t=c+VhhDM1TGg*Q_-K$9!{0X322njPX>3V z?o}KMUd1{``Yx@T3`fE*M*Tvnil4R)PbxN6L`BLY7Dka?gDD&2IOmkHWP&mxjUaB3 zcrGhqd6F4z>*+U-B3$0X``>;0?1gAo2cGd>AZ=>3hi3(-k8JxZg9l}6*QkeD7uwE6 z5fb`TsEJ*gV5=!l>IQAq*Z`ZSx-Q-#eHWAB^342tzZeby$n{x9uM)0aB(;T~sfo@^ z@6`R~1LU2`C3sk|U0 codecs.CodecInfo object + The getregentry() API must return a CodecInfo object with encoder, decoder, + incrementalencoder, incrementaldecoder, streamwriter and streamreader + atttributes which adhere to the Python Codec Interface Standard. + + In addition, a module may optionally also define the following + APIs which are then used by the package's codec search function: + + * getaliases() -> sequence of encoding name strings to use as aliases + + Alias names returned by getaliases() must be normalized encoding + names as defined by normalize_encoding(). + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +"""#" + +import codecs +import sys +from . import aliases + +_cache = {} +_unknown = '--unknown--' +_import_tail = ['*'] +_aliases = aliases.aliases + +class CodecRegistryError(LookupError, SystemError): + pass + +def normalize_encoding(encoding): + + """ Normalize an encoding name. + + Normalization works as follows: all non-alphanumeric + characters except the dot used for Python package names are + collapsed and replaced with a single underscore, e.g. ' -;#' + becomes '_'. Leading and trailing underscores are removed. + + Note that encoding names should be ASCII only; if they do use + non-ASCII characters, these must be Latin-1 compatible. + + """ + if isinstance(encoding, bytes): + encoding = str(encoding, "ascii") + + chars = [] + punct = False + for c in encoding: + if c.isalnum() or c == '.': + if punct and chars: + chars.append('_') + chars.append(c) + punct = False + else: + punct = True + return ''.join(chars) + +def search_function(encoding): + + # Cache lookup + entry = _cache.get(encoding, _unknown) + if entry is not _unknown: + return entry + + # Import the module: + # + # First try to find an alias for the normalized encoding + # name and lookup the module using the aliased name, then try to + # lookup the module using the standard import scheme, i.e. first + # try in the encodings package, then at top-level. + # + norm_encoding = normalize_encoding(encoding) + aliased_encoding = _aliases.get(norm_encoding) or \ + _aliases.get(norm_encoding.replace('.', '_')) + if aliased_encoding is not None: + modnames = [aliased_encoding, + norm_encoding] + else: + modnames = [norm_encoding] + for modname in modnames: + if not modname or '.' in modname: + continue + try: + # Import is absolute to prevent the possibly malicious import of a + # module with side-effects that is not in the 'encodings' package. + mod = __import__('encodings.' + modname, fromlist=_import_tail, + level=0) + except ImportError: + # ImportError may occur because 'encodings.(modname)' does not exist, + # or because it imports a name that does not exist (see mbcs and oem) + pass + else: + break + else: + mod = None + + try: + getregentry = mod.getregentry + except AttributeError: + # Not a codec module + mod = None + + if mod is None: + # Cache misses + _cache[encoding] = None + return None + + # Now ask the module for the registry entry + entry = getregentry() + if not isinstance(entry, codecs.CodecInfo): + if not 4 <= len(entry) <= 7: + raise CodecRegistryError('module "%s" (%s) failed to register' + % (mod.__name__, mod.__file__)) + if not callable(entry[0]) or not callable(entry[1]) or \ + (entry[2] is not None and not callable(entry[2])) or \ + (entry[3] is not None and not callable(entry[3])) or \ + (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \ + (len(entry) > 5 and entry[5] is not None and not callable(entry[5])): + raise CodecRegistryError('incompatible codecs in module "%s" (%s)' + % (mod.__name__, mod.__file__)) + if len(entry)<7 or entry[6] is None: + entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) + entry = codecs.CodecInfo(*entry) + + # Cache the codec registry entry + _cache[encoding] = entry + + # Register its aliases (without overwriting previously registered + # aliases) + try: + codecaliases = mod.getaliases() + except AttributeError: + pass + else: + for alias in codecaliases: + if alias not in _aliases: + _aliases[alias] = modname + + # Return the registry entry + return entry + +# Register the search_function in the Python codec registry +codecs.register(search_function) + +if sys.platform == 'win32': + def _alias_mbcs(encoding): + try: + import _winapi + ansi_code_page = "cp%s" % _winapi.GetACP() + if encoding == ansi_code_page: + import encodings.mbcs + return encodings.mbcs.getregentry() + except ImportError: + # Imports may fail while we are shutting down + pass + + codecs.register(_alias_mbcs) diff --git a/Lib/encodings/__pycache__/__init__.cpython-37.pyc b/Lib/encodings/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22047625074cf517632dc709ef9660398359343e GIT binary patch literal 3970 zcmai1L2uj06`mm}ijr;Fn`V$*<1Nmv&I%^69w zC{i9$aTHKMQSY@yPCahzWAFV5J@nKcK;+b(@(+qV^_w9jC)q<~a5%$x^XAQ)?|tw2 zi-mB}hQJ3ns;TqiJR%8w=*P-oX8ddsFe1HtUSyAPZsqp@@=` zH6}K?8(PcqDC?|$y3Dj0hk}KJVI&43&Y`%=F4m5@9!Wjt~lE#}CB4(g&-oD>5m%*hr3H-}>jJrgTGlXFKjBEIB-a-?WvF zVaB@)Hutv6?WD*?GG;z|e<3>wvtH>kA=ls~WvX1$`ocJn`jmd8oumZb`ZkrttxDk! zPGkt{8E{g4z(=Ukn*1!wWOz8raCIlW5FYV)PXG|OIpw?xGuk+|J@vv2QXaRAOk zbwg`7N(n4B@W(6}s*ipYjhP>%Np;!pdRH3)hs-Qc+xJAwM(M>ZR)}0y2vb*<3SYw7 zDKOr?7og2gMOt1ZI6+0g2VZ@`^W=mI~D6C6&hD9xpbS z!fpoI{|9nlawhv0z~RRyxTOq-hQzOMwDrxH!w)-Ra5$1(wt^UX0A#DdMvx5JSg{hc zftul1hTUGqws!Zo*Vtwhv3)g8*}h1Hd@lF~+x<0rvbn#%x%>DTmc0Rck=-{GZJQSL z>M$?o*4IaIKTb~K_4V)RYM`X1KPCGBPdblA5HKDA+flHPQC!m4*caUp4jn&~GLgG& zvv535MY!h`P0uRCZPC<@#2e|d`W(PZ(`==nR!mqU*sk?LC#Ne zL;fN&HxrN~+Ja9Z+g<(DS7qAox=zUIb!T(i%^)GPF90 zoCbImUKQSv5iWFq1pT3kL`5J{3?tAWFWJdwDMBa`Y!rh~QgFX0xtT39w*J}8<(Za4 z(3eUN%ii(^K<(@7pcH1(48LTZJ=)t6Nhh zq;74f(py1;i+GT#3@I-CkSl(!@OljmS!mLxVNr`V=@NC&HmPj@=2tN{gSk?pf=t6a zM<8V6i~{J!xiO(R&5V9SUdsW>%*@Ftofw&gdE=Z8@0Go?nyPNj@kN236Ugu8W^Qzi zi51&;(~0$BC$|tD4<@y|CS6YRTHlt@u{*w!+1$))S4mdq7O(xuoY+rDeAyzI({IYZ zP@?{xkz@BM*+YvUArpJt%d#Qu)U9Uk4RoW zMYv{jIMw{o!m07fNLRU?wQ_n&En<>BeMM!H*VP-uZcvgfatC`Y;rXCrT*3MONV7{h z<<>{&L;9b3)R>Mi)BFf~^&6Obs^>5+B{4TQo6GbZ#+4Rr1GoDY)_n&_dnWmvmc;lS z$$2gL8j|xf$=6yEVF@*93Ud3Zxmu!BcxPB|3){a>Zt_qav6ouER3rv zP1U*Y>w9BEx=nZ69~QP3pf(hRiCm9FR;5K9SQu6bv#3{Gs1h8?P85wg!ByQ1))jNx z`nyhw#oSvJVA0x~)?Ip1E@Jb-)}>AAHgrl=MPy;3z|)CKD)UrU?cmhd$U#z!d@xf{ zONUXIxy_5hq}`MsD(RXoPu&H@BC}${T`CX2FTObNg)Yb4dew7Hbfik2?z}dtI<#BU zo%eZav8=|tX*KpW7N#9E#GD5;Sq()`m(Vk)W7z1=qi2}v-7;;%HY~%y*Ot*V98j2L z+O$P~0%}{L*Y)2jU9Cndv}rn)ft5?3J4JdeQ+}cht)WuCb9=^o3OWuR&3rrPjBf+& zB+@AzNt&LMD`bLHpBqTzpXfP5aomx4W}SmiDyFJ|f4-Vw9o(b1rfu$O%)YdOA+Tr{ zbq~Ay!_c+A7TM<3p4+-W_uw!{T}!pvqjDL>v@Lx_@)r7T%a7C0Q-1b___xh%%+|i| z=(!Soo>KN#EKQft5am`l#KB(+PL#Ltt^EOP@^}(>o?OKkIcc2A7J5>}hGeR_p_-qm z<|dkAZYN3lqhSTtM`Og)poFK2B#r;l)y_2H3J2vthB{)PH+{=oUD@d*=G-qs?eiZ) cNqQZPg*%49I(gZ+#Y?7h-T9`8+jQps2Z8ofM*si- literal 0 HcmV?d00001 diff --git a/Lib/encodings/__pycache__/aliases.cpython-37.pyc b/Lib/encodings/__pycache__/aliases.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32442d30cc81dec84d19421a53b821d1087c427b GIT binary patch literal 6319 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 Cp&bGM literal 0 HcmV?d00001 diff --git a/Lib/encodings/__pycache__/idna.cpython-37.pyc b/Lib/encodings/__pycache__/idna.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb696c9efffa963f53891c1f41c1619fdc418525 GIT binary patch literal 5747 zcmbtYO>i8=74Dw@9j#<}5y&=97y{R4S+SExG2D1G(f(ap07i

rthmb06RORP;J^LfCg!4CB)7$;} z|Glrj_j)djkNXUd^QYOj+!Ks_LWTZgBQuXT`3(}m1aGiP{?991myL>nf1_b;SQV4A zh<9ya-sTlYSQS^;6;C+Ay~Qd8;fVtNec_8S{ExlFL{W_2Vq!cpt`~RBN)eI?aR`z_ zkc>kz0m-B|49Q_g4nZ;rNlDxT$vsgKvctPp$f0u8*jFniz zzQt(XUEVRb7E=>DnClp+AwN`yb2H_&yIlSiy*=ugnxb%&z0V~>&OgeM4^cCw$NcaL zMuU2b%NeU!%P)R=VP|S7ekW|yMNqpI%CM#)8Jv&}aVZ%HzYPQLig!t*PyCy`86 zE-t_EW^nrK%K27nF;wBoE6rNiSb0@8*JZeoth~Cdt~KM{-Z0}Gv(6gYFAHZPS|Qiv8WU` z!dA~ltFxJPy;+a5v36XCZX*FpWQDjXHvo;Ds8Sr5vvzuRZ)tXRk1A?s_7 zJx`GGpF+Y6i~HO+3_ituvuGl}?>A{qKxVlm?l~o1G~^We4bVc`C(~+j`5Q9Z6DjM0 zG>9;+uz1R1ir?_%*En#)*_$kW{3_U1fkt+@#Y}dC$vI&nU5qWxVv7!>;=-Z>s!VFt z`LZ$JxyzXE>oI@6e@v{-Qa0%2*OO#=~Lh?XLgv> z>h&Cn^U%T0v^GT$ZM4*O(3F8{HiJepUf((X3Rx>iR47#v+^nl>!TE)Y0S@I_eJk@? z?Rc92S9UW;AL~d?V!X_3M6uR8u?lsip4nIu)}m^!uRqL}xh$dAsQKN?&GVNQmX^+; zE_o6OXG4I-p-o7Dgd;$L2_!t9TTPf94m227S;`ZoVE2Kgd;QSoc&`ssOFw1ixajp` zU0cC!$$QF8VY6N160O2h&MrLr4~(OXTtl}YVC{~n{M5t@R=;g`>^4K*qJB3_`4Ps3 z^;2utB$okpbC)m6d$F|_cfPvcC)DF$X>mEwW|q@vwQ~gJ^MPnaNf0+xAe-%2oP-Bx zm5Z5QPwFuY7uTZ9UfotvB8gbFZM9kDF)AKMl9_ND@+jpT5fK)&=5frMHzQfLwPh=Q zt1Y9dMqS0xivW?yC}}rTuRJ?y{levDk3Q-cJb4@mGkosg?8DBmI?lM^p+pFnK#gxs zlJ%`4ylBdY(Yi)m`j3gsJl-Tg5;2OU5J$Pf5aumjF%c_~v*r~`IM8Jwvlp69pX+T)o2328%w5nNe@cU!cy{ zt1wZ+cljD%rtDn?NI8g?fx29|HY@dst&b5f=z zAdT72iI!*N*g#0J%9pd!L{3+ImXeR6b=lA1NkGj?ea}OoMwI&>J83oQDu-%;KpjdM zZfBNgss!w{rQlUHcI5*!oSRum)L6^xdfaL&G@vac@*x^Nhj5~?ofVY~>$I&ZMjAn} zJ~lr^m!9|Xj3PXk)kCcV|5f70c#%&6(M7`nri;XE+RItMbcyd2H4tZVc0Cw}zrzG~ z!=VBq6=)-wfg1xN5F7yqH(dE$&>o^?La4I)SOJAOKy(_Li^l9SFKVwRIO%ywYt$1Z3O4ltXQpXw!=nVlasXG<1miZIif6i0?AMC>U)>R z{S#VJgJkef;60Bwp_pmFl3WhHF(WRSxB;W>erQ1!yAgq%P#3HIl=_0;s7=q**TX0eM#{ z)9jN2l6WY`qDCc=+NYG1y&R1c#N;S@f^sJ*p*TfDGN+xw2;MS#tsaMs5!iv75Z50B zzHFkp+Fo0WWHo1uKVbNT;L1QNIr+eG67upFq(g*6DLK^KwN4Ud`Obs;Ej@GR=*wkG zK1~~VhLW?C%u#X>{GLTchF9OBJT9sHe}OMQx?cjmk1_h)!IyKQoK0uthW^PV$jVdti%Vw6NWMhF(U%8FUNLj&^HjYNgVtS{%C%kg$Tcw9ek4~9W G_P+o>d-WRt literal 0 HcmV?d00001 diff --git a/Lib/encodings/__pycache__/latin_1.cpython-37.pyc b/Lib/encodings/__pycache__/latin_1.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b868d88f3f2669ae29a39f820b8471cbcd5d7f28 GIT binary patch literal 1919 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 literal 0 HcmV?d00001 diff --git a/Lib/encodings/__pycache__/utf_8.cpython-37.pyc b/Lib/encodings/__pycache__/utf_8.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9d142ea5f9f263cd734c795e8fff44c7d0eef78 GIT binary patch literal 1637 zcmbVMUysv95a0E`I8N?>w9sDF2lojql}LpL5JJ_30M$v39Rm zi5JAZ_B)ivex-eEpZXR0)R}d{<)?d${$hxhx97oRzd{XxoR zpw9Mj)(aGZjhW!WD)^X7eq@bpaZxzJJ>g^LJ0?8QI$@%PJMKGs?4rdNZM3w};-RI5 zmOymS(m{)l79TBLv4fT!w6xLE7Q5oY2^$B(dcvYh$8W>OEA_G}!>da*xqka|pSix-iQia2K zbntaJD2i}IdL52rE#Z|E{V@I^d^Q-32JzG9_}QNrIE%GcE12afw@Af7Zx`nfXT6I; zv0wQc_J#}o-bUzF{4}z(mlNDtcM*MhJH<8XXm@AjVyUzz0V=3}W6;7I{)&fpk{=O8 zojiztdLDjrD;X>n_cN6xkE%Q?lE+X@A)D7p!^!$}^Hx&K4ij18-LrC9C&pKQvC>}S z?*c(IxH+_Oo#Xs4Y+UW*tgoPuY|JsqmT-k7Y)q>y9E`=&y@N6bIhUo%iU;IK!o!?C zr9p41lOfK!hr&>SWE@%VEy4Ggp#wPXL^jar4Ic)x1kdbfrO@P)z$cP1qauq4!M-fN}yCNn9d9qyTZKchke= zWFlc*E9b%@NR+M(EYklYtnL#9GMiHu$&Ui+;JqIw=TqF>+d@J5|3fj785Y#P(PHZM zTrMu7*DtqFkbVXQRs4_+e2zk~BWzG*DO)+pRi0`I>z5WL%8rj+^M{FA+M%*&;--&v zZ+2Sz>xw;NYq|_{7k?4RDNc-LqrEl^M}AZH?IHaS4$4V&dcUbEpd12$2jcO(P<3Z2 z(ZLj(5LRE|p_=N4afe%54-gp<2kQ5zqg!bzsyt1b3Oh|G1!f%UFYcLolVYor)`i-D hGI$I!y82vX{@tdtzNM})upI6?o)y?Vr)T5i{teQiSyTW3 literal 0 HcmV?d00001 diff --git a/Lib/encodings/aliases.py b/Lib/encodings/aliases.py new file mode 100644 index 0000000..2e63c2f --- /dev/null +++ b/Lib/encodings/aliases.py @@ -0,0 +1,550 @@ +""" Encoding Aliases Support + + This module is used by the encodings package search function to + map encodings names to module names. + + Note that the search function normalizes the encoding names before + doing the lookup, so the mapping will have to map normalized + encoding names to module names. + + Contents: + + The following aliases dictionary contains mappings of all IANA + character set names for which the Python core library provides + codecs. In addition to these, a few Python specific codec + aliases have also been added. + +""" +aliases = { + + # Please keep this list sorted alphabetically by value ! + + # ascii codec + '646' : 'ascii', + 'ansi_x3.4_1968' : 'ascii', + 'ansi_x3_4_1968' : 'ascii', # some email headers use this non-standard name + 'ansi_x3.4_1986' : 'ascii', + 'cp367' : 'ascii', + 'csascii' : 'ascii', + 'ibm367' : 'ascii', + 'iso646_us' : 'ascii', + 'iso_646.irv_1991' : 'ascii', + 'iso_ir_6' : 'ascii', + 'us' : 'ascii', + 'us_ascii' : 'ascii', + + # base64_codec codec + 'base64' : 'base64_codec', + 'base_64' : 'base64_codec', + + # big5 codec + 'big5_tw' : 'big5', + 'csbig5' : 'big5', + + # big5hkscs codec + 'big5_hkscs' : 'big5hkscs', + 'hkscs' : 'big5hkscs', + + # bz2_codec codec + 'bz2' : 'bz2_codec', + + # cp037 codec + '037' : 'cp037', + 'csibm037' : 'cp037', + 'ebcdic_cp_ca' : 'cp037', + 'ebcdic_cp_nl' : 'cp037', + 'ebcdic_cp_us' : 'cp037', + 'ebcdic_cp_wt' : 'cp037', + 'ibm037' : 'cp037', + 'ibm039' : 'cp037', + + # cp1026 codec + '1026' : 'cp1026', + 'csibm1026' : 'cp1026', + 'ibm1026' : 'cp1026', + + # cp1125 codec + '1125' : 'cp1125', + 'ibm1125' : 'cp1125', + 'cp866u' : 'cp1125', + 'ruscii' : 'cp1125', + + # cp1140 codec + '1140' : 'cp1140', + 'ibm1140' : 'cp1140', + + # cp1250 codec + '1250' : 'cp1250', + 'windows_1250' : 'cp1250', + + # cp1251 codec + '1251' : 'cp1251', + 'windows_1251' : 'cp1251', + + # cp1252 codec + '1252' : 'cp1252', + 'windows_1252' : 'cp1252', + + # cp1253 codec + '1253' : 'cp1253', + 'windows_1253' : 'cp1253', + + # cp1254 codec + '1254' : 'cp1254', + 'windows_1254' : 'cp1254', + + # cp1255 codec + '1255' : 'cp1255', + 'windows_1255' : 'cp1255', + + # cp1256 codec + '1256' : 'cp1256', + 'windows_1256' : 'cp1256', + + # cp1257 codec + '1257' : 'cp1257', + 'windows_1257' : 'cp1257', + + # cp1258 codec + '1258' : 'cp1258', + 'windows_1258' : 'cp1258', + + # cp273 codec + '273' : 'cp273', + 'ibm273' : 'cp273', + 'csibm273' : 'cp273', + + # cp424 codec + '424' : 'cp424', + 'csibm424' : 'cp424', + 'ebcdic_cp_he' : 'cp424', + 'ibm424' : 'cp424', + + # cp437 codec + '437' : 'cp437', + 'cspc8codepage437' : 'cp437', + 'ibm437' : 'cp437', + + # cp500 codec + '500' : 'cp500', + 'csibm500' : 'cp500', + 'ebcdic_cp_be' : 'cp500', + 'ebcdic_cp_ch' : 'cp500', + 'ibm500' : 'cp500', + + # cp775 codec + '775' : 'cp775', + 'cspc775baltic' : 'cp775', + 'ibm775' : 'cp775', + + # cp850 codec + '850' : 'cp850', + 'cspc850multilingual' : 'cp850', + 'ibm850' : 'cp850', + + # cp852 codec + '852' : 'cp852', + 'cspcp852' : 'cp852', + 'ibm852' : 'cp852', + + # cp855 codec + '855' : 'cp855', + 'csibm855' : 'cp855', + 'ibm855' : 'cp855', + + # cp857 codec + '857' : 'cp857', + 'csibm857' : 'cp857', + 'ibm857' : 'cp857', + + # cp858 codec + '858' : 'cp858', + 'csibm858' : 'cp858', + 'ibm858' : 'cp858', + + # cp860 codec + '860' : 'cp860', + 'csibm860' : 'cp860', + 'ibm860' : 'cp860', + + # cp861 codec + '861' : 'cp861', + 'cp_is' : 'cp861', + 'csibm861' : 'cp861', + 'ibm861' : 'cp861', + + # cp862 codec + '862' : 'cp862', + 'cspc862latinhebrew' : 'cp862', + 'ibm862' : 'cp862', + + # cp863 codec + '863' : 'cp863', + 'csibm863' : 'cp863', + 'ibm863' : 'cp863', + + # cp864 codec + '864' : 'cp864', + 'csibm864' : 'cp864', + 'ibm864' : 'cp864', + + # cp865 codec + '865' : 'cp865', + 'csibm865' : 'cp865', + 'ibm865' : 'cp865', + + # cp866 codec + '866' : 'cp866', + 'csibm866' : 'cp866', + 'ibm866' : 'cp866', + + # cp869 codec + '869' : 'cp869', + 'cp_gr' : 'cp869', + 'csibm869' : 'cp869', + 'ibm869' : 'cp869', + + # cp932 codec + '932' : 'cp932', + 'ms932' : 'cp932', + 'mskanji' : 'cp932', + 'ms_kanji' : 'cp932', + + # cp949 codec + '949' : 'cp949', + 'ms949' : 'cp949', + 'uhc' : 'cp949', + + # cp950 codec + '950' : 'cp950', + 'ms950' : 'cp950', + + # euc_jis_2004 codec + 'jisx0213' : 'euc_jis_2004', + 'eucjis2004' : 'euc_jis_2004', + 'euc_jis2004' : 'euc_jis_2004', + + # euc_jisx0213 codec + 'eucjisx0213' : 'euc_jisx0213', + + # euc_jp codec + 'eucjp' : 'euc_jp', + 'ujis' : 'euc_jp', + 'u_jis' : 'euc_jp', + + # euc_kr codec + 'euckr' : 'euc_kr', + 'korean' : 'euc_kr', + 'ksc5601' : 'euc_kr', + 'ks_c_5601' : 'euc_kr', + 'ks_c_5601_1987' : 'euc_kr', + 'ksx1001' : 'euc_kr', + 'ks_x_1001' : 'euc_kr', + + # gb18030 codec + 'gb18030_2000' : 'gb18030', + + # gb2312 codec + 'chinese' : 'gb2312', + 'csiso58gb231280' : 'gb2312', + 'euc_cn' : 'gb2312', + 'euccn' : 'gb2312', + 'eucgb2312_cn' : 'gb2312', + 'gb2312_1980' : 'gb2312', + 'gb2312_80' : 'gb2312', + 'iso_ir_58' : 'gb2312', + + # gbk codec + '936' : 'gbk', + 'cp936' : 'gbk', + 'ms936' : 'gbk', + + # hex_codec codec + 'hex' : 'hex_codec', + + # hp_roman8 codec + 'roman8' : 'hp_roman8', + 'r8' : 'hp_roman8', + 'csHPRoman8' : 'hp_roman8', + + # hz codec + 'hzgb' : 'hz', + 'hz_gb' : 'hz', + 'hz_gb_2312' : 'hz', + + # iso2022_jp codec + 'csiso2022jp' : 'iso2022_jp', + 'iso2022jp' : 'iso2022_jp', + 'iso_2022_jp' : 'iso2022_jp', + + # iso2022_jp_1 codec + 'iso2022jp_1' : 'iso2022_jp_1', + 'iso_2022_jp_1' : 'iso2022_jp_1', + + # iso2022_jp_2 codec + 'iso2022jp_2' : 'iso2022_jp_2', + 'iso_2022_jp_2' : 'iso2022_jp_2', + + # iso2022_jp_2004 codec + 'iso_2022_jp_2004' : 'iso2022_jp_2004', + 'iso2022jp_2004' : 'iso2022_jp_2004', + + # iso2022_jp_3 codec + 'iso2022jp_3' : 'iso2022_jp_3', + 'iso_2022_jp_3' : 'iso2022_jp_3', + + # iso2022_jp_ext codec + 'iso2022jp_ext' : 'iso2022_jp_ext', + 'iso_2022_jp_ext' : 'iso2022_jp_ext', + + # iso2022_kr codec + 'csiso2022kr' : 'iso2022_kr', + 'iso2022kr' : 'iso2022_kr', + 'iso_2022_kr' : 'iso2022_kr', + + # iso8859_10 codec + 'csisolatin6' : 'iso8859_10', + 'iso_8859_10' : 'iso8859_10', + 'iso_8859_10_1992' : 'iso8859_10', + 'iso_ir_157' : 'iso8859_10', + 'l6' : 'iso8859_10', + 'latin6' : 'iso8859_10', + + # iso8859_11 codec + 'thai' : 'iso8859_11', + 'iso_8859_11' : 'iso8859_11', + 'iso_8859_11_2001' : 'iso8859_11', + + # iso8859_13 codec + 'iso_8859_13' : 'iso8859_13', + 'l7' : 'iso8859_13', + 'latin7' : 'iso8859_13', + + # iso8859_14 codec + 'iso_8859_14' : 'iso8859_14', + 'iso_8859_14_1998' : 'iso8859_14', + 'iso_celtic' : 'iso8859_14', + 'iso_ir_199' : 'iso8859_14', + 'l8' : 'iso8859_14', + 'latin8' : 'iso8859_14', + + # iso8859_15 codec + 'iso_8859_15' : 'iso8859_15', + 'l9' : 'iso8859_15', + 'latin9' : 'iso8859_15', + + # iso8859_16 codec + 'iso_8859_16' : 'iso8859_16', + 'iso_8859_16_2001' : 'iso8859_16', + 'iso_ir_226' : 'iso8859_16', + 'l10' : 'iso8859_16', + 'latin10' : 'iso8859_16', + + # iso8859_2 codec + 'csisolatin2' : 'iso8859_2', + 'iso_8859_2' : 'iso8859_2', + 'iso_8859_2_1987' : 'iso8859_2', + 'iso_ir_101' : 'iso8859_2', + 'l2' : 'iso8859_2', + 'latin2' : 'iso8859_2', + + # iso8859_3 codec + 'csisolatin3' : 'iso8859_3', + 'iso_8859_3' : 'iso8859_3', + 'iso_8859_3_1988' : 'iso8859_3', + 'iso_ir_109' : 'iso8859_3', + 'l3' : 'iso8859_3', + 'latin3' : 'iso8859_3', + + # iso8859_4 codec + 'csisolatin4' : 'iso8859_4', + 'iso_8859_4' : 'iso8859_4', + 'iso_8859_4_1988' : 'iso8859_4', + 'iso_ir_110' : 'iso8859_4', + 'l4' : 'iso8859_4', + 'latin4' : 'iso8859_4', + + # iso8859_5 codec + 'csisolatincyrillic' : 'iso8859_5', + 'cyrillic' : 'iso8859_5', + 'iso_8859_5' : 'iso8859_5', + 'iso_8859_5_1988' : 'iso8859_5', + 'iso_ir_144' : 'iso8859_5', + + # iso8859_6 codec + 'arabic' : 'iso8859_6', + 'asmo_708' : 'iso8859_6', + 'csisolatinarabic' : 'iso8859_6', + 'ecma_114' : 'iso8859_6', + 'iso_8859_6' : 'iso8859_6', + 'iso_8859_6_1987' : 'iso8859_6', + 'iso_ir_127' : 'iso8859_6', + + # iso8859_7 codec + 'csisolatingreek' : 'iso8859_7', + 'ecma_118' : 'iso8859_7', + 'elot_928' : 'iso8859_7', + 'greek' : 'iso8859_7', + 'greek8' : 'iso8859_7', + 'iso_8859_7' : 'iso8859_7', + 'iso_8859_7_1987' : 'iso8859_7', + 'iso_ir_126' : 'iso8859_7', + + # iso8859_8 codec + 'csisolatinhebrew' : 'iso8859_8', + 'hebrew' : 'iso8859_8', + 'iso_8859_8' : 'iso8859_8', + 'iso_8859_8_1988' : 'iso8859_8', + 'iso_ir_138' : 'iso8859_8', + + # iso8859_9 codec + 'csisolatin5' : 'iso8859_9', + 'iso_8859_9' : 'iso8859_9', + 'iso_8859_9_1989' : 'iso8859_9', + 'iso_ir_148' : 'iso8859_9', + 'l5' : 'iso8859_9', + 'latin5' : 'iso8859_9', + + # johab codec + 'cp1361' : 'johab', + 'ms1361' : 'johab', + + # koi8_r codec + 'cskoi8r' : 'koi8_r', + + # kz1048 codec + 'kz_1048' : 'kz1048', + 'rk1048' : 'kz1048', + 'strk1048_2002' : 'kz1048', + + # latin_1 codec + # + # Note that the latin_1 codec is implemented internally in C and a + # lot faster than the charmap codec iso8859_1 which uses the same + # encoding. This is why we discourage the use of the iso8859_1 + # codec and alias it to latin_1 instead. + # + '8859' : 'latin_1', + 'cp819' : 'latin_1', + 'csisolatin1' : 'latin_1', + 'ibm819' : 'latin_1', + 'iso8859' : 'latin_1', + 'iso8859_1' : 'latin_1', + 'iso_8859_1' : 'latin_1', + 'iso_8859_1_1987' : 'latin_1', + 'iso_ir_100' : 'latin_1', + 'l1' : 'latin_1', + 'latin' : 'latin_1', + 'latin1' : 'latin_1', + + # mac_cyrillic codec + 'maccyrillic' : 'mac_cyrillic', + + # mac_greek codec + 'macgreek' : 'mac_greek', + + # mac_iceland codec + 'maciceland' : 'mac_iceland', + + # mac_latin2 codec + 'maccentraleurope' : 'mac_latin2', + 'maclatin2' : 'mac_latin2', + + # mac_roman codec + 'macintosh' : 'mac_roman', + 'macroman' : 'mac_roman', + + # mac_turkish codec + 'macturkish' : 'mac_turkish', + + # mbcs codec + 'ansi' : 'mbcs', + 'dbcs' : 'mbcs', + + # ptcp154 codec + 'csptcp154' : 'ptcp154', + 'pt154' : 'ptcp154', + 'cp154' : 'ptcp154', + 'cyrillic_asian' : 'ptcp154', + + # quopri_codec codec + 'quopri' : 'quopri_codec', + 'quoted_printable' : 'quopri_codec', + 'quotedprintable' : 'quopri_codec', + + # rot_13 codec + 'rot13' : 'rot_13', + + # shift_jis codec + 'csshiftjis' : 'shift_jis', + 'shiftjis' : 'shift_jis', + 'sjis' : 'shift_jis', + 's_jis' : 'shift_jis', + + # shift_jis_2004 codec + 'shiftjis2004' : 'shift_jis_2004', + 'sjis_2004' : 'shift_jis_2004', + 's_jis_2004' : 'shift_jis_2004', + + # shift_jisx0213 codec + 'shiftjisx0213' : 'shift_jisx0213', + 'sjisx0213' : 'shift_jisx0213', + 's_jisx0213' : 'shift_jisx0213', + + # tactis codec + 'tis260' : 'tactis', + + # tis_620 codec + 'tis620' : 'tis_620', + 'tis_620_0' : 'tis_620', + 'tis_620_2529_0' : 'tis_620', + 'tis_620_2529_1' : 'tis_620', + 'iso_ir_166' : 'tis_620', + + # utf_16 codec + 'u16' : 'utf_16', + 'utf16' : 'utf_16', + + # utf_16_be codec + 'unicodebigunmarked' : 'utf_16_be', + 'utf_16be' : 'utf_16_be', + + # utf_16_le codec + 'unicodelittleunmarked' : 'utf_16_le', + 'utf_16le' : 'utf_16_le', + + # utf_32 codec + 'u32' : 'utf_32', + 'utf32' : 'utf_32', + + # utf_32_be codec + 'utf_32be' : 'utf_32_be', + + # utf_32_le codec + 'utf_32le' : 'utf_32_le', + + # utf_7 codec + 'u7' : 'utf_7', + 'utf7' : 'utf_7', + 'unicode_1_1_utf_7' : 'utf_7', + + # utf_8 codec + 'u8' : 'utf_8', + 'utf' : 'utf_8', + 'utf8' : 'utf_8', + 'utf8_ucs2' : 'utf_8', + 'utf8_ucs4' : 'utf_8', + + # uu_codec codec + 'uu' : 'uu_codec', + + # zlib_codec codec + 'zip' : 'zlib_codec', + 'zlib' : 'zlib_codec', + + # temporary mac CJK aliases, will be replaced by proper codecs in 3.1 + 'x_mac_japanese' : 'shift_jis', + 'x_mac_korean' : 'euc_kr', + 'x_mac_simp_chinese' : 'gb2312', + 'x_mac_trad_chinese' : 'big5', +} diff --git a/Lib/encodings/ascii.py b/Lib/encodings/ascii.py new file mode 100644 index 0000000..2033cde --- /dev/null +++ b/Lib/encodings/ascii.py @@ -0,0 +1,50 @@ +""" Python 'ascii' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.ascii_encode + decode = codecs.ascii_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.ascii_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.ascii_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +class StreamConverter(StreamWriter,StreamReader): + + encode = codecs.ascii_decode + decode = codecs.ascii_encode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='ascii', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/base64_codec.py b/Lib/encodings/base64_codec.py new file mode 100644 index 0000000..8e7703b --- /dev/null +++ b/Lib/encodings/base64_codec.py @@ -0,0 +1,55 @@ +"""Python 'base64_codec' Codec - base64 content transfer encoding. + +This codec de/encodes from bytes to bytes. + +Written by Marc-Andre Lemburg (mal@lemburg.com). +""" + +import codecs +import base64 + +### Codec APIs + +def base64_encode(input, errors='strict'): + assert errors == 'strict' + return (base64.encodebytes(input), len(input)) + +def base64_decode(input, errors='strict'): + assert errors == 'strict' + return (base64.decodebytes(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return base64_encode(input, errors) + def decode(self, input, errors='strict'): + return base64_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + assert self.errors == 'strict' + return base64.encodebytes(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + assert self.errors == 'strict' + return base64.decodebytes(input) + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='base64', + encode=base64_encode, + decode=base64_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=False, + ) diff --git a/Lib/encodings/big5.py b/Lib/encodings/big5.py new file mode 100644 index 0000000..7adeb0e --- /dev/null +++ b/Lib/encodings/big5.py @@ -0,0 +1,39 @@ +# +# big5.py: Python Unicode Codec for BIG5 +# +# Written by Hye-Shik Chang +# + +import _codecs_tw, codecs +import _multibytecodec as mbc + +codec = _codecs_tw.getcodec('big5') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='big5', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/big5hkscs.py b/Lib/encodings/big5hkscs.py new file mode 100644 index 0000000..350df37 --- /dev/null +++ b/Lib/encodings/big5hkscs.py @@ -0,0 +1,39 @@ +# +# big5hkscs.py: Python Unicode Codec for BIG5HKSCS +# +# Written by Hye-Shik Chang +# + +import _codecs_hk, codecs +import _multibytecodec as mbc + +codec = _codecs_hk.getcodec('big5hkscs') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='big5hkscs', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/bz2_codec.py b/Lib/encodings/bz2_codec.py new file mode 100644 index 0000000..fd9495e --- /dev/null +++ b/Lib/encodings/bz2_codec.py @@ -0,0 +1,78 @@ +"""Python 'bz2_codec' Codec - bz2 compression encoding. + +This codec de/encodes from bytes to bytes and is therefore usable with +bytes.transform() and bytes.untransform(). + +Adapted by Raymond Hettinger from zlib_codec.py which was written +by Marc-Andre Lemburg (mal@lemburg.com). +""" + +import codecs +import bz2 # this codec needs the optional bz2 module ! + +### Codec APIs + +def bz2_encode(input, errors='strict'): + assert errors == 'strict' + return (bz2.compress(input), len(input)) + +def bz2_decode(input, errors='strict'): + assert errors == 'strict' + return (bz2.decompress(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return bz2_encode(input, errors) + def decode(self, input, errors='strict'): + return bz2_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.compressobj = bz2.BZ2Compressor() + + def encode(self, input, final=False): + if final: + c = self.compressobj.compress(input) + return c + self.compressobj.flush() + else: + return self.compressobj.compress(input) + + def reset(self): + self.compressobj = bz2.BZ2Compressor() + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.decompressobj = bz2.BZ2Decompressor() + + def decode(self, input, final=False): + try: + return self.decompressobj.decompress(input) + except EOFError: + return '' + + def reset(self): + self.decompressobj = bz2.BZ2Decompressor() + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name="bz2", + encode=bz2_encode, + decode=bz2_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=False, + ) diff --git a/Lib/encodings/charmap.py b/Lib/encodings/charmap.py new file mode 100644 index 0000000..81189b1 --- /dev/null +++ b/Lib/encodings/charmap.py @@ -0,0 +1,69 @@ +""" Generic Python Character Mapping Codec. + + Use this codec directly rather than through the automatic + conversion mechanisms supplied by unicode() and .encode(). + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.charmap_encode + decode = codecs.charmap_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict', mapping=None): + codecs.IncrementalEncoder.__init__(self, errors) + self.mapping = mapping + + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, self.mapping)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict', mapping=None): + codecs.IncrementalDecoder.__init__(self, errors) + self.mapping = mapping + + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, self.mapping)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + + def __init__(self,stream,errors='strict',mapping=None): + codecs.StreamWriter.__init__(self,stream,errors) + self.mapping = mapping + + def encode(self,input,errors='strict'): + return Codec.encode(input,errors,self.mapping) + +class StreamReader(Codec,codecs.StreamReader): + + def __init__(self,stream,errors='strict',mapping=None): + codecs.StreamReader.__init__(self,stream,errors) + self.mapping = mapping + + def decode(self,input,errors='strict'): + return Codec.decode(input,errors,self.mapping) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='charmap', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/cp037.py b/Lib/encodings/cp037.py new file mode 100644 index 0000000..4edd708 --- /dev/null +++ b/Lib/encodings/cp037.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp037 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp037', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '\xa2' # 0x4A -> CENT SIGN + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '|' # 0x4F -> VERTICAL LINE + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + '!' # 0x5A -> EXCLAMATION MARK + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '\xac' # 0x5F -> NOT SIGN + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\xa6' # 0x6A -> BROKEN BAR + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + '\xae' # 0xAF -> REGISTERED SIGN + '^' # 0xB0 -> CIRCUMFLEX ACCENT + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '[' # 0xBA -> LEFT SQUARE BRACKET + ']' # 0xBB -> RIGHT SQUARE BRACKET + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\\' # 0xE0 -> REVERSE SOLIDUS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1006.py b/Lib/encodings/cp1006.py new file mode 100644 index 0000000..a1221c3 --- /dev/null +++ b/Lib/encodings/cp1006.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1006 generated from 'MAPPINGS/VENDORS/MISC/CP1006.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1006', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u06f0' # 0xA1 -> EXTENDED ARABIC-INDIC DIGIT ZERO + '\u06f1' # 0xA2 -> EXTENDED ARABIC-INDIC DIGIT ONE + '\u06f2' # 0xA3 -> EXTENDED ARABIC-INDIC DIGIT TWO + '\u06f3' # 0xA4 -> EXTENDED ARABIC-INDIC DIGIT THREE + '\u06f4' # 0xA5 -> EXTENDED ARABIC-INDIC DIGIT FOUR + '\u06f5' # 0xA6 -> EXTENDED ARABIC-INDIC DIGIT FIVE + '\u06f6' # 0xA7 -> EXTENDED ARABIC-INDIC DIGIT SIX + '\u06f7' # 0xA8 -> EXTENDED ARABIC-INDIC DIGIT SEVEN + '\u06f8' # 0xA9 -> EXTENDED ARABIC-INDIC DIGIT EIGHT + '\u06f9' # 0xAA -> EXTENDED ARABIC-INDIC DIGIT NINE + '\u060c' # 0xAB -> ARABIC COMMA + '\u061b' # 0xAC -> ARABIC SEMICOLON + '\xad' # 0xAD -> SOFT HYPHEN + '\u061f' # 0xAE -> ARABIC QUESTION MARK + '\ufe81' # 0xAF -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + '\ufe8d' # 0xB0 -> ARABIC LETTER ALEF ISOLATED FORM + '\ufe8e' # 0xB1 -> ARABIC LETTER ALEF FINAL FORM + '\ufe8e' # 0xB2 -> ARABIC LETTER ALEF FINAL FORM + '\ufe8f' # 0xB3 -> ARABIC LETTER BEH ISOLATED FORM + '\ufe91' # 0xB4 -> ARABIC LETTER BEH INITIAL FORM + '\ufb56' # 0xB5 -> ARABIC LETTER PEH ISOLATED FORM + '\ufb58' # 0xB6 -> ARABIC LETTER PEH INITIAL FORM + '\ufe93' # 0xB7 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM + '\ufe95' # 0xB8 -> ARABIC LETTER TEH ISOLATED FORM + '\ufe97' # 0xB9 -> ARABIC LETTER TEH INITIAL FORM + '\ufb66' # 0xBA -> ARABIC LETTER TTEH ISOLATED FORM + '\ufb68' # 0xBB -> ARABIC LETTER TTEH INITIAL FORM + '\ufe99' # 0xBC -> ARABIC LETTER THEH ISOLATED FORM + '\ufe9b' # 0xBD -> ARABIC LETTER THEH INITIAL FORM + '\ufe9d' # 0xBE -> ARABIC LETTER JEEM ISOLATED FORM + '\ufe9f' # 0xBF -> ARABIC LETTER JEEM INITIAL FORM + '\ufb7a' # 0xC0 -> ARABIC LETTER TCHEH ISOLATED FORM + '\ufb7c' # 0xC1 -> ARABIC LETTER TCHEH INITIAL FORM + '\ufea1' # 0xC2 -> ARABIC LETTER HAH ISOLATED FORM + '\ufea3' # 0xC3 -> ARABIC LETTER HAH INITIAL FORM + '\ufea5' # 0xC4 -> ARABIC LETTER KHAH ISOLATED FORM + '\ufea7' # 0xC5 -> ARABIC LETTER KHAH INITIAL FORM + '\ufea9' # 0xC6 -> ARABIC LETTER DAL ISOLATED FORM + '\ufb84' # 0xC7 -> ARABIC LETTER DAHAL ISOLATED FORMN + '\ufeab' # 0xC8 -> ARABIC LETTER THAL ISOLATED FORM + '\ufead' # 0xC9 -> ARABIC LETTER REH ISOLATED FORM + '\ufb8c' # 0xCA -> ARABIC LETTER RREH ISOLATED FORM + '\ufeaf' # 0xCB -> ARABIC LETTER ZAIN ISOLATED FORM + '\ufb8a' # 0xCC -> ARABIC LETTER JEH ISOLATED FORM + '\ufeb1' # 0xCD -> ARABIC LETTER SEEN ISOLATED FORM + '\ufeb3' # 0xCE -> ARABIC LETTER SEEN INITIAL FORM + '\ufeb5' # 0xCF -> ARABIC LETTER SHEEN ISOLATED FORM + '\ufeb7' # 0xD0 -> ARABIC LETTER SHEEN INITIAL FORM + '\ufeb9' # 0xD1 -> ARABIC LETTER SAD ISOLATED FORM + '\ufebb' # 0xD2 -> ARABIC LETTER SAD INITIAL FORM + '\ufebd' # 0xD3 -> ARABIC LETTER DAD ISOLATED FORM + '\ufebf' # 0xD4 -> ARABIC LETTER DAD INITIAL FORM + '\ufec1' # 0xD5 -> ARABIC LETTER TAH ISOLATED FORM + '\ufec5' # 0xD6 -> ARABIC LETTER ZAH ISOLATED FORM + '\ufec9' # 0xD7 -> ARABIC LETTER AIN ISOLATED FORM + '\ufeca' # 0xD8 -> ARABIC LETTER AIN FINAL FORM + '\ufecb' # 0xD9 -> ARABIC LETTER AIN INITIAL FORM + '\ufecc' # 0xDA -> ARABIC LETTER AIN MEDIAL FORM + '\ufecd' # 0xDB -> ARABIC LETTER GHAIN ISOLATED FORM + '\ufece' # 0xDC -> ARABIC LETTER GHAIN FINAL FORM + '\ufecf' # 0xDD -> ARABIC LETTER GHAIN INITIAL FORM + '\ufed0' # 0xDE -> ARABIC LETTER GHAIN MEDIAL FORM + '\ufed1' # 0xDF -> ARABIC LETTER FEH ISOLATED FORM + '\ufed3' # 0xE0 -> ARABIC LETTER FEH INITIAL FORM + '\ufed5' # 0xE1 -> ARABIC LETTER QAF ISOLATED FORM + '\ufed7' # 0xE2 -> ARABIC LETTER QAF INITIAL FORM + '\ufed9' # 0xE3 -> ARABIC LETTER KAF ISOLATED FORM + '\ufedb' # 0xE4 -> ARABIC LETTER KAF INITIAL FORM + '\ufb92' # 0xE5 -> ARABIC LETTER GAF ISOLATED FORM + '\ufb94' # 0xE6 -> ARABIC LETTER GAF INITIAL FORM + '\ufedd' # 0xE7 -> ARABIC LETTER LAM ISOLATED FORM + '\ufedf' # 0xE8 -> ARABIC LETTER LAM INITIAL FORM + '\ufee0' # 0xE9 -> ARABIC LETTER LAM MEDIAL FORM + '\ufee1' # 0xEA -> ARABIC LETTER MEEM ISOLATED FORM + '\ufee3' # 0xEB -> ARABIC LETTER MEEM INITIAL FORM + '\ufb9e' # 0xEC -> ARABIC LETTER NOON GHUNNA ISOLATED FORM + '\ufee5' # 0xED -> ARABIC LETTER NOON ISOLATED FORM + '\ufee7' # 0xEE -> ARABIC LETTER NOON INITIAL FORM + '\ufe85' # 0xEF -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + '\ufeed' # 0xF0 -> ARABIC LETTER WAW ISOLATED FORM + '\ufba6' # 0xF1 -> ARABIC LETTER HEH GOAL ISOLATED FORM + '\ufba8' # 0xF2 -> ARABIC LETTER HEH GOAL INITIAL FORM + '\ufba9' # 0xF3 -> ARABIC LETTER HEH GOAL MEDIAL FORM + '\ufbaa' # 0xF4 -> ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM + '\ufe80' # 0xF5 -> ARABIC LETTER HAMZA ISOLATED FORM + '\ufe89' # 0xF6 -> ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM + '\ufe8a' # 0xF7 -> ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM + '\ufe8b' # 0xF8 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + '\ufef1' # 0xF9 -> ARABIC LETTER YEH ISOLATED FORM + '\ufef2' # 0xFA -> ARABIC LETTER YEH FINAL FORM + '\ufef3' # 0xFB -> ARABIC LETTER YEH INITIAL FORM + '\ufbb0' # 0xFC -> ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM + '\ufbae' # 0xFD -> ARABIC LETTER YEH BARREE ISOLATED FORM + '\ufe7c' # 0xFE -> ARABIC SHADDA ISOLATED FORM + '\ufe7d' # 0xFF -> ARABIC SHADDA MEDIAL FORM +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1026.py b/Lib/encodings/cp1026.py new file mode 100644 index 0000000..46f71f7 --- /dev/null +++ b/Lib/encodings/cp1026.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1026 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1026', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '{' # 0x48 -> LEFT CURLY BRACKET + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '\xc7' # 0x4A -> LATIN CAPITAL LETTER C WITH CEDILLA + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + '\u011e' # 0x5A -> LATIN CAPITAL LETTER G WITH BREVE + '\u0130' # 0x5B -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '[' # 0x68 -> LEFT SQUARE BRACKET + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\u015f' # 0x6A -> LATIN SMALL LETTER S WITH CEDILLA + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '\u0131' # 0x79 -> LATIN SMALL LETTER DOTLESS I + ':' # 0x7A -> COLON + '\xd6' # 0x7B -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u015e' # 0x7C -> LATIN CAPITAL LETTER S WITH CEDILLA + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '\xdc' # 0x7F -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '}' # 0x8C -> RIGHT CURLY BRACKET + '`' # 0x8D -> GRAVE ACCENT + '\xa6' # 0x8E -> BROKEN BAR + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '\xf6' # 0xA1 -> LATIN SMALL LETTER O WITH DIAERESIS + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + ']' # 0xAC -> RIGHT SQUARE BRACKET + '$' # 0xAD -> DOLLAR SIGN + '@' # 0xAE -> COMMERCIAL AT + '\xae' # 0xAF -> REGISTERED SIGN + '\xa2' # 0xB0 -> CENT SIGN + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '\xac' # 0xBA -> NOT SIGN + '|' # 0xBB -> VERTICAL LINE + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '\xe7' # 0xC0 -> LATIN SMALL LETTER C WITH CEDILLA + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '~' # 0xCC -> TILDE + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '\u011f' # 0xD0 -> LATIN SMALL LETTER G WITH BREVE + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\\' # 0xDC -> REVERSE SOLIDUS + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xfc' # 0xE0 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '#' # 0xEC -> NUMBER SIGN + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '"' # 0xFC -> QUOTATION MARK + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1125.py b/Lib/encodings/cp1125.py new file mode 100644 index 0000000..b1fd69d --- /dev/null +++ b/Lib/encodings/cp1125.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec for CP1125 + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1125', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x0082: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x0083: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x0084: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x0085: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x0086: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x0087: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x0088: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x0089: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x008a: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x008b: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x008c: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x008d: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x008e: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x008f: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x0090: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x0091: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x0092: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x0093: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x0094: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x0095: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x0096: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x0097: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x0098: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x0099: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x009a: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x009b: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x009c: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x009d: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x009e: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009f: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a2: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00a3: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00a4: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a5: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a6: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00a7: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00a8: 0x0438, # CYRILLIC SMALL LETTER I + 0x00a9: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00aa: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00ab: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00ac: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00ad: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00ae: 0x043e, # CYRILLIC SMALL LETTER O + 0x00af: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e1: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e2: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e3: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e4: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00e5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00e6: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00e7: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00e8: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00e9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00ea: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x00eb: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00ec: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ed: 0x044d, # CYRILLIC SMALL LETTER E + 0x00ee: 0x044e, # CYRILLIC SMALL LETTER YU + 0x00ef: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00f0: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x00f1: 0x0451, # CYRILLIC SMALL LETTER IO + 0x00f2: 0x0490, # CYRILLIC CAPITAL LETTER GHE WITH UPTURN + 0x00f3: 0x0491, # CYRILLIC SMALL LETTER GHE WITH UPTURN + 0x00f4: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x00f5: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x00f6: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x00f7: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x00f8: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x00f9: 0x0457, # CYRILLIC SMALL LETTER YI + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x2116, # NUMERO SIGN + 0x00fd: 0x00a4, # CURRENCY SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0410' # 0x0080 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0x0081 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0x0082 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0x0083 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0x0084 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0x0085 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0x0086 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0x0087 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0x0088 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0x0089 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0x008a -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0x008b -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0x008c -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0x008d -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0x008e -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0x008f -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0x0090 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0x0091 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0x0092 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0x0093 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0x0094 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0x0095 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0x0096 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0x0097 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0x0098 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0x0099 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0x009b -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0x009d -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0x009e -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0x009f -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0x00a1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0x00a2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0x00a3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0x00a4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0x00a5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0x00a6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0x00a7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0x00a8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0x00a9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0x00aa -> CYRILLIC SMALL LETTER KA + '\u043b' # 0x00ab -> CYRILLIC SMALL LETTER EL + '\u043c' # 0x00ac -> CYRILLIC SMALL LETTER EM + '\u043d' # 0x00ad -> CYRILLIC SMALL LETTER EN + '\u043e' # 0x00ae -> CYRILLIC SMALL LETTER O + '\u043f' # 0x00af -> CYRILLIC SMALL LETTER PE + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u0440' # 0x00e0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0x00e1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0x00e2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0x00e3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0x00e4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0x00e5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0x00e6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0x00e7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0x00e8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0x00e9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0x00ea -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0x00eb -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0x00ed -> CYRILLIC SMALL LETTER E + '\u044e' # 0x00ee -> CYRILLIC SMALL LETTER YU + '\u044f' # 0x00ef -> CYRILLIC SMALL LETTER YA + '\u0401' # 0x00f0 -> CYRILLIC CAPITAL LETTER IO + '\u0451' # 0x00f1 -> CYRILLIC SMALL LETTER IO + '\u0490' # 0x00f2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + '\u0491' # 0x00f3 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + '\u0404' # 0x00f4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0454' # 0x00f5 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0406' # 0x00f6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0x00f7 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0407' # 0x00f8 -> CYRILLIC CAPITAL LETTER YI + '\u0457' # 0x00f9 -> CYRILLIC SMALL LETTER YI + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u2116' # 0x00fc -> NUMERO SIGN + '\xa4' # 0x00fd -> CURRENCY SIGN + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00fd, # CURRENCY SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x0401: 0x00f0, # CYRILLIC CAPITAL LETTER IO + 0x0404: 0x00f4, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0406: 0x00f6, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0407: 0x00f8, # CYRILLIC CAPITAL LETTER YI + 0x0410: 0x0080, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x0081, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x0082, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x0083, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x0084, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x0085, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x0086, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x0087, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x0088, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x0089, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x008a, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x008b, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x008c, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x008d, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x008e, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x008f, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x0090, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x0091, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x0092, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x0093, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x0094, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x0095, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x0096, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x0097, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x0098, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x0099, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x009b, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x009c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x009d, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009e, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x009f, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a1, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00a2, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00a3, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a4, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a5, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00a6, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00a7, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00a8, # CYRILLIC SMALL LETTER I + 0x0439: 0x00a9, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00aa, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00ab, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00ac, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00ad, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00ae, # CYRILLIC SMALL LETTER O + 0x043f: 0x00af, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e0, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e1, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e2, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e3, # CYRILLIC SMALL LETTER U + 0x0444: 0x00e4, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00e5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00e6, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00e7, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00e8, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00e9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x00ea, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00eb, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ec, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00ed, # CYRILLIC SMALL LETTER E + 0x044e: 0x00ee, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00ef, # CYRILLIC SMALL LETTER YA + 0x0451: 0x00f1, # CYRILLIC SMALL LETTER IO + 0x0454: 0x00f5, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0456: 0x00f7, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0457: 0x00f9, # CYRILLIC SMALL LETTER YI + 0x0490: 0x00f2, # CYRILLIC CAPITAL LETTER GHE WITH UPTURN + 0x0491: 0x00f3, # CYRILLIC SMALL LETTER GHE WITH UPTURN + 0x2116: 0x00fc, # NUMERO SIGN + 0x221a: 0x00fb, # SQUARE ROOT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp1140.py b/Lib/encodings/cp1140.py new file mode 100644 index 0000000..0a919d8 --- /dev/null +++ b/Lib/encodings/cp1140.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1140 generated from 'python-mappings/CP1140.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1140', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '\xa2' # 0x4A -> CENT SIGN + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '|' # 0x4F -> VERTICAL LINE + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + '!' # 0x5A -> EXCLAMATION MARK + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '\xac' # 0x5F -> NOT SIGN + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\xa6' # 0x6A -> BROKEN BAR + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + '\u20ac' # 0x9F -> EURO SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + '\xae' # 0xAF -> REGISTERED SIGN + '^' # 0xB0 -> CIRCUMFLEX ACCENT + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '[' # 0xBA -> LEFT SQUARE BRACKET + ']' # 0xBB -> RIGHT SQUARE BRACKET + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\\' # 0xE0 -> REVERSE SOLIDUS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1250.py b/Lib/encodings/cp1250.py new file mode 100644 index 0000000..c2c83aa --- /dev/null +++ b/Lib/encodings/cp1250.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1250 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1250', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\ufffe' # 0x83 -> UNDEFINED + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u015a' # 0x8C -> LATIN CAPITAL LETTER S WITH ACUTE + '\u0164' # 0x8D -> LATIN CAPITAL LETTER T WITH CARON + '\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON + '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u015b' # 0x9C -> LATIN SMALL LETTER S WITH ACUTE + '\u0165' # 0x9D -> LATIN SMALL LETTER T WITH CARON + '\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON + '\u017a' # 0x9F -> LATIN SMALL LETTER Z WITH ACUTE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u02c7' # 0xA1 -> CARON + '\u02d8' # 0xA2 -> BREVE + '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u0104' # 0xA5 -> LATIN CAPITAL LETTER A WITH OGONEK + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u02db' # 0xB2 -> OGONEK + '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\u0105' # 0xB9 -> LATIN SMALL LETTER A WITH OGONEK + '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u013d' # 0xBC -> LATIN CAPITAL LETTER L WITH CARON + '\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT + '\u013e' # 0xBE -> LATIN SMALL LETTER L WITH CARON + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE + '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON + '\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE + '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON + '\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1251.py b/Lib/encodings/cp1251.py new file mode 100644 index 0000000..22bc660 --- /dev/null +++ b/Lib/encodings/cp1251.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1251 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1251', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE + '\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u20ac' # 0x88 -> EURO SIGN + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE + '\u040c' # 0x8D -> CYRILLIC CAPITAL LETTER KJE + '\u040b' # 0x8E -> CYRILLIC CAPITAL LETTER TSHE + '\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE + '\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE + '\u045c' # 0x9D -> CYRILLIC SMALL LETTER KJE + '\u045b' # 0x9E -> CYRILLIC SMALL LETTER TSHE + '\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u040e' # 0xA1 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045e' # 0xA2 -> CYRILLIC SMALL LETTER SHORT U + '\u0408' # 0xA3 -> CYRILLIC CAPITAL LETTER JE + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u0490' # 0xA5 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0404' # 0xAA -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u0407' # 0xAF -> CYRILLIC CAPITAL LETTER YI + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0491' # 0xB4 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + '\u2116' # 0xB9 -> NUMERO SIGN + '\u0454' # 0xBA -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0458' # 0xBC -> CYRILLIC SMALL LETTER JE + '\u0405' # 0xBD -> CYRILLIC CAPITAL LETTER DZE + '\u0455' # 0xBE -> CYRILLIC SMALL LETTER DZE + '\u0457' # 0xBF -> CYRILLIC SMALL LETTER YI + '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1252.py b/Lib/encodings/cp1252.py new file mode 100644 index 0000000..c0e8088 --- /dev/null +++ b/Lib/encodings/cp1252.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1252 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1252', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\ufffe' # 0x8D -> UNDEFINED + '\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\ufffe' # 0x9D -> UNDEFINED + '\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1253.py b/Lib/encodings/cp1253.py new file mode 100644 index 0000000..ec9c097 --- /dev/null +++ b/Lib/encodings/cp1253.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1253 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1253', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0385' # 0xA1 -> GREEK DIALYTIKA TONOS + '\u0386' # 0xA2 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\ufffe' # 0xAA -> UNDEFINED + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u2015' # 0xAF -> HORIZONTAL BAR + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u0384' # 0xB4 -> GREEK TONOS + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA + '\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA + '\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA + '\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0xCC -> GREEK CAPITAL LETTER MU + '\u039d' # 0xCD -> GREEK CAPITAL LETTER NU + '\u039e' # 0xCE -> GREEK CAPITAL LETTER XI + '\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON + '\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO + '\ufffe' # 0xD2 -> UNDEFINED + '\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA + '\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA + '\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + '\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA + '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + '\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA + '\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA + '\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA + '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + '\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0xEC -> GREEK SMALL LETTER MU + '\u03bd' # 0xED -> GREEK SMALL LETTER NU + '\u03be' # 0xEE -> GREEK SMALL LETTER XI + '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + '\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO + '\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA + '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + '\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI + '\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI + '\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI + '\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA + '\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS + '\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1254.py b/Lib/encodings/cp1254.py new file mode 100644 index 0000000..4912327 --- /dev/null +++ b/Lib/encodings/cp1254.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1254 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1254', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I + '\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1255.py b/Lib/encodings/cp1255.py new file mode 100644 index 0000000..91ce26b --- /dev/null +++ b/Lib/encodings/cp1255.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1255 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1255', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\u20aa' # 0xA4 -> NEW SHEQEL SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xd7' # 0xAA -> MULTIPLICATION SIGN + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xf7' # 0xBA -> DIVISION SIGN + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\u05b0' # 0xC0 -> HEBREW POINT SHEVA + '\u05b1' # 0xC1 -> HEBREW POINT HATAF SEGOL + '\u05b2' # 0xC2 -> HEBREW POINT HATAF PATAH + '\u05b3' # 0xC3 -> HEBREW POINT HATAF QAMATS + '\u05b4' # 0xC4 -> HEBREW POINT HIRIQ + '\u05b5' # 0xC5 -> HEBREW POINT TSERE + '\u05b6' # 0xC6 -> HEBREW POINT SEGOL + '\u05b7' # 0xC7 -> HEBREW POINT PATAH + '\u05b8' # 0xC8 -> HEBREW POINT QAMATS + '\u05b9' # 0xC9 -> HEBREW POINT HOLAM + '\ufffe' # 0xCA -> UNDEFINED + '\u05bb' # 0xCB -> HEBREW POINT QUBUTS + '\u05bc' # 0xCC -> HEBREW POINT DAGESH OR MAPIQ + '\u05bd' # 0xCD -> HEBREW POINT METEG + '\u05be' # 0xCE -> HEBREW PUNCTUATION MAQAF + '\u05bf' # 0xCF -> HEBREW POINT RAFE + '\u05c0' # 0xD0 -> HEBREW PUNCTUATION PASEQ + '\u05c1' # 0xD1 -> HEBREW POINT SHIN DOT + '\u05c2' # 0xD2 -> HEBREW POINT SIN DOT + '\u05c3' # 0xD3 -> HEBREW PUNCTUATION SOF PASUQ + '\u05f0' # 0xD4 -> HEBREW LIGATURE YIDDISH DOUBLE VAV + '\u05f1' # 0xD5 -> HEBREW LIGATURE YIDDISH VAV YOD + '\u05f2' # 0xD6 -> HEBREW LIGATURE YIDDISH DOUBLE YOD + '\u05f3' # 0xD7 -> HEBREW PUNCTUATION GERESH + '\u05f4' # 0xD8 -> HEBREW PUNCTUATION GERSHAYIM + '\ufffe' # 0xD9 -> UNDEFINED + '\ufffe' # 0xDA -> UNDEFINED + '\ufffe' # 0xDB -> UNDEFINED + '\ufffe' # 0xDC -> UNDEFINED + '\ufffe' # 0xDD -> UNDEFINED + '\ufffe' # 0xDE -> UNDEFINED + '\ufffe' # 0xDF -> UNDEFINED + '\u05d0' # 0xE0 -> HEBREW LETTER ALEF + '\u05d1' # 0xE1 -> HEBREW LETTER BET + '\u05d2' # 0xE2 -> HEBREW LETTER GIMEL + '\u05d3' # 0xE3 -> HEBREW LETTER DALET + '\u05d4' # 0xE4 -> HEBREW LETTER HE + '\u05d5' # 0xE5 -> HEBREW LETTER VAV + '\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN + '\u05d7' # 0xE7 -> HEBREW LETTER HET + '\u05d8' # 0xE8 -> HEBREW LETTER TET + '\u05d9' # 0xE9 -> HEBREW LETTER YOD + '\u05da' # 0xEA -> HEBREW LETTER FINAL KAF + '\u05db' # 0xEB -> HEBREW LETTER KAF + '\u05dc' # 0xEC -> HEBREW LETTER LAMED + '\u05dd' # 0xED -> HEBREW LETTER FINAL MEM + '\u05de' # 0xEE -> HEBREW LETTER MEM + '\u05df' # 0xEF -> HEBREW LETTER FINAL NUN + '\u05e0' # 0xF0 -> HEBREW LETTER NUN + '\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH + '\u05e2' # 0xF2 -> HEBREW LETTER AYIN + '\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE + '\u05e4' # 0xF4 -> HEBREW LETTER PE + '\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0xF6 -> HEBREW LETTER TSADI + '\u05e7' # 0xF7 -> HEBREW LETTER QOF + '\u05e8' # 0xF8 -> HEBREW LETTER RESH + '\u05e9' # 0xF9 -> HEBREW LETTER SHIN + '\u05ea' # 0xFA -> HEBREW LETTER TAV + '\ufffe' # 0xFB -> UNDEFINED + '\ufffe' # 0xFC -> UNDEFINED + '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + '\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1256.py b/Lib/encodings/cp1256.py new file mode 100644 index 0000000..fd6afab --- /dev/null +++ b/Lib/encodings/cp1256.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1256 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1256', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\u067e' # 0x81 -> ARABIC LETTER PEH + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0679' # 0x8A -> ARABIC LETTER TTEH + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\u0686' # 0x8D -> ARABIC LETTER TCHEH + '\u0698' # 0x8E -> ARABIC LETTER JEH + '\u0688' # 0x8F -> ARABIC LETTER DDAL + '\u06af' # 0x90 -> ARABIC LETTER GAF + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u06a9' # 0x98 -> ARABIC LETTER KEHEH + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0691' # 0x9A -> ARABIC LETTER RREH + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\u200c' # 0x9D -> ZERO WIDTH NON-JOINER + '\u200d' # 0x9E -> ZERO WIDTH JOINER + '\u06ba' # 0x9F -> ARABIC LETTER NOON GHUNNA + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u060c' # 0xA1 -> ARABIC COMMA + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u06be' # 0xAA -> ARABIC LETTER HEH DOACHASHMEE + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\u061b' # 0xBA -> ARABIC SEMICOLON + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\u061f' # 0xBF -> ARABIC QUESTION MARK + '\u06c1' # 0xC0 -> ARABIC LETTER HEH GOAL + '\u0621' # 0xC1 -> ARABIC LETTER HAMZA + '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0xC7 -> ARABIC LETTER ALEF + '\u0628' # 0xC8 -> ARABIC LETTER BEH + '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xCA -> ARABIC LETTER TEH + '\u062b' # 0xCB -> ARABIC LETTER THEH + '\u062c' # 0xCC -> ARABIC LETTER JEEM + '\u062d' # 0xCD -> ARABIC LETTER HAH + '\u062e' # 0xCE -> ARABIC LETTER KHAH + '\u062f' # 0xCF -> ARABIC LETTER DAL + '\u0630' # 0xD0 -> ARABIC LETTER THAL + '\u0631' # 0xD1 -> ARABIC LETTER REH + '\u0632' # 0xD2 -> ARABIC LETTER ZAIN + '\u0633' # 0xD3 -> ARABIC LETTER SEEN + '\u0634' # 0xD4 -> ARABIC LETTER SHEEN + '\u0635' # 0xD5 -> ARABIC LETTER SAD + '\u0636' # 0xD6 -> ARABIC LETTER DAD + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0637' # 0xD8 -> ARABIC LETTER TAH + '\u0638' # 0xD9 -> ARABIC LETTER ZAH + '\u0639' # 0xDA -> ARABIC LETTER AIN + '\u063a' # 0xDB -> ARABIC LETTER GHAIN + '\u0640' # 0xDC -> ARABIC TATWEEL + '\u0641' # 0xDD -> ARABIC LETTER FEH + '\u0642' # 0xDE -> ARABIC LETTER QAF + '\u0643' # 0xDF -> ARABIC LETTER KAF + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\u0644' # 0xE1 -> ARABIC LETTER LAM + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0645' # 0xE3 -> ARABIC LETTER MEEM + '\u0646' # 0xE4 -> ARABIC LETTER NOON + '\u0647' # 0xE5 -> ARABIC LETTER HEH + '\u0648' # 0xE6 -> ARABIC LETTER WAW + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0649' # 0xEC -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xED -> ARABIC LETTER YEH + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u064b' # 0xF0 -> ARABIC FATHATAN + '\u064c' # 0xF1 -> ARABIC DAMMATAN + '\u064d' # 0xF2 -> ARABIC KASRATAN + '\u064e' # 0xF3 -> ARABIC FATHA + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u064f' # 0xF5 -> ARABIC DAMMA + '\u0650' # 0xF6 -> ARABIC KASRA + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0651' # 0xF8 -> ARABIC SHADDA + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\u0652' # 0xFA -> ARABIC SUKUN + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + '\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1257.py b/Lib/encodings/cp1257.py new file mode 100644 index 0000000..9ebc90d --- /dev/null +++ b/Lib/encodings/cp1257.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1257 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1257', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\ufffe' # 0x83 -> UNDEFINED + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\xa8' # 0x8D -> DIAERESIS + '\u02c7' # 0x8E -> CARON + '\xb8' # 0x8F -> CEDILLA + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\xaf' # 0x9D -> MACRON + '\u02db' # 0x9E -> OGONEK + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\ufffe' # 0xA1 -> UNDEFINED + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\ufffe' # 0xA5 -> UNDEFINED + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xc6' # 0xAF -> LATIN CAPITAL LETTER AE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xe6' # 0xBF -> LATIN SMALL LETTER AE + '\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON + '\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE + '\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON + '\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE + '\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE + '\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK + '\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK + '\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON + '\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK + '\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE + '\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE + '\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA + '\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA + '\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON + '\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA + '\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK + '\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE + '\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE + '\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp1258.py b/Lib/encodings/cp1258.py new file mode 100644 index 0000000..784378a --- /dev/null +++ b/Lib/encodings/cp1258.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1258 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1258', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u0300' # 0xCC -> COMBINING GRAVE ACCENT + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\u0309' # 0xD2 -> COMBINING HOOK ABOVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u01a0' # 0xD5 -> LATIN CAPITAL LETTER O WITH HORN + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u01af' # 0xDD -> LATIN CAPITAL LETTER U WITH HORN + '\u0303' # 0xDE -> COMBINING TILDE + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0301' # 0xEC -> COMBINING ACUTE ACCENT + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\u0323' # 0xF2 -> COMBINING DOT BELOW + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u01a1' # 0xF5 -> LATIN SMALL LETTER O WITH HORN + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u01b0' # 0xFD -> LATIN SMALL LETTER U WITH HORN + '\u20ab' # 0xFE -> DONG SIGN + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp273.py b/Lib/encodings/cp273.py new file mode 100644 index 0000000..69c6d77 --- /dev/null +++ b/Lib/encodings/cp273.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp273 generated from 'python-mappings/CP273.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp273', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL (NUL) + '\x01' # 0x01 -> START OF HEADING (SOH) + '\x02' # 0x02 -> START OF TEXT (STX) + '\x03' # 0x03 -> END OF TEXT (ETX) + '\x9c' # 0x04 -> STRING TERMINATOR (ST) + '\t' # 0x05 -> CHARACTER TABULATION (HT) + '\x86' # 0x06 -> START OF SELECTED AREA (SSA) + '\x7f' # 0x07 -> DELETE (DEL) + '\x97' # 0x08 -> END OF GUARDED AREA (EPA) + '\x8d' # 0x09 -> REVERSE LINE FEED (RI) + '\x8e' # 0x0A -> SINGLE-SHIFT TWO (SS2) + '\x0b' # 0x0B -> LINE TABULATION (VT) + '\x0c' # 0x0C -> FORM FEED (FF) + '\r' # 0x0D -> CARRIAGE RETURN (CR) + '\x0e' # 0x0E -> SHIFT OUT (SO) + '\x0f' # 0x0F -> SHIFT IN (SI) + '\x10' # 0x10 -> DATALINK ESCAPE (DLE) + '\x11' # 0x11 -> DEVICE CONTROL ONE (DC1) + '\x12' # 0x12 -> DEVICE CONTROL TWO (DC2) + '\x13' # 0x13 -> DEVICE CONTROL THREE (DC3) + '\x9d' # 0x14 -> OPERATING SYSTEM COMMAND (OSC) + '\x85' # 0x15 -> NEXT LINE (NEL) + '\x08' # 0x16 -> BACKSPACE (BS) + '\x87' # 0x17 -> END OF SELECTED AREA (ESA) + '\x18' # 0x18 -> CANCEL (CAN) + '\x19' # 0x19 -> END OF MEDIUM (EM) + '\x92' # 0x1A -> PRIVATE USE TWO (PU2) + '\x8f' # 0x1B -> SINGLE-SHIFT THREE (SS3) + '\x1c' # 0x1C -> FILE SEPARATOR (IS4) + '\x1d' # 0x1D -> GROUP SEPARATOR (IS3) + '\x1e' # 0x1E -> RECORD SEPARATOR (IS2) + '\x1f' # 0x1F -> UNIT SEPARATOR (IS1) + '\x80' # 0x20 -> PADDING CHARACTER (PAD) + '\x81' # 0x21 -> HIGH OCTET PRESET (HOP) + '\x82' # 0x22 -> BREAK PERMITTED HERE (BPH) + '\x83' # 0x23 -> NO BREAK HERE (NBH) + '\x84' # 0x24 -> INDEX (IND) + '\n' # 0x25 -> LINE FEED (LF) + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK (ETB) + '\x1b' # 0x27 -> ESCAPE (ESC) + '\x88' # 0x28 -> CHARACTER TABULATION SET (HTS) + '\x89' # 0x29 -> CHARACTER TABULATION WITH JUSTIFICATION (HTJ) + '\x8a' # 0x2A -> LINE TABULATION SET (VTS) + '\x8b' # 0x2B -> PARTIAL LINE FORWARD (PLD) + '\x8c' # 0x2C -> PARTIAL LINE BACKWARD (PLU) + '\x05' # 0x2D -> ENQUIRY (ENQ) + '\x06' # 0x2E -> ACKNOWLEDGE (ACK) + '\x07' # 0x2F -> BELL (BEL) + '\x90' # 0x30 -> DEVICE CONTROL STRING (DCS) + '\x91' # 0x31 -> PRIVATE USE ONE (PU1) + '\x16' # 0x32 -> SYNCHRONOUS IDLE (SYN) + '\x93' # 0x33 -> SET TRANSMIT STATE (STS) + '\x94' # 0x34 -> CANCEL CHARACTER (CCH) + '\x95' # 0x35 -> MESSAGE WAITING (MW) + '\x96' # 0x36 -> START OF GUARDED AREA (SPA) + '\x04' # 0x37 -> END OF TRANSMISSION (EOT) + '\x98' # 0x38 -> START OF STRING (SOS) + '\x99' # 0x39 -> SINGLE GRAPHIC CHARACTER INTRODUCER (SGCI) + '\x9a' # 0x3A -> SINGLE CHARACTER INTRODUCER (SCI) + '\x9b' # 0x3B -> CONTROL SEQUENCE INTRODUCER (CSI) + '\x14' # 0x3C -> DEVICE CONTROL FOUR (DC4) + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE (NAK) + '\x9e' # 0x3E -> PRIVACY MESSAGE (PM) + '\x1a' # 0x3F -> SUBSTITUTE (SUB) + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '{' # 0x43 -> LEFT CURLY BRACKET + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '\xc4' # 0x4A -> LATIN CAPITAL LETTER A WITH DIAERESIS + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '~' # 0x59 -> TILDE + '\xdc' # 0x5A -> LATIN CAPITAL LETTER U WITH DIAERESIS + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '[' # 0x63 -> LEFT SQUARE BRACKET + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\xf6' # 0x6A -> LATIN SMALL LETTER O WITH DIAERESIS + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '\xa7' # 0x7C -> SECTION SIGN + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (Icelandic) + '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (Icelandic) + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LETTER AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LETTER AE + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '\xdf' # 0xA1 -> LATIN SMALL LETTER SHARP S (German) + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (Icelandic) + '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xae' # 0xAF -> REGISTERED SIGN + '\xa2' # 0xB0 -> CENT SIGN + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '@' # 0xB5 -> COMMERCIAL AT + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '\xac' # 0xBA -> NOT SIGN + '|' # 0xBB -> VERTICAL LINE + '\u203e' # 0xBC -> OVERLINE + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '\xe4' # 0xC0 -> LATIN SMALL LETTER A WITH DIAERESIS + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xa6' # 0xCC -> BROKEN BAR + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '\xfc' # 0xD0 -> LATIN SMALL LETTER U WITH DIAERESIS + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '}' # 0xDC -> RIGHT CURLY BRACKET + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0xE0 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\\' # 0xEC -> REVERSE SOLIDUS + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + ']' # 0xFC -> RIGHT SQUARE BRACKET + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> APPLICATION PROGRAM COMMAND (APC) +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp424.py b/Lib/encodings/cp424.py new file mode 100644 index 0000000..6753daf --- /dev/null +++ b/Lib/encodings/cp424.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp424 generated from 'MAPPINGS/VENDORS/MISC/CP424.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp424', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> SELECT + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> REQUIRED NEW LINE + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> GRAPHIC ESCAPE + '\x8d' # 0x09 -> SUPERSCRIPT + '\x8e' # 0x0A -> REPEAT + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> RESTORE/ENABLE PRESENTATION + '\x85' # 0x15 -> NEW LINE + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> PROGRAM OPERATOR COMMUNICATION + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> UNIT BACK SPACE + '\x8f' # 0x1B -> CUSTOMER USE ONE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> DIGIT SELECT + '\x81' # 0x21 -> START OF SIGNIFICANCE + '\x82' # 0x22 -> FIELD SEPARATOR + '\x83' # 0x23 -> WORD UNDERSCORE + '\x84' # 0x24 -> BYPASS OR INHIBIT PRESENTATION + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> SET ATTRIBUTE + '\x89' # 0x29 -> START FIELD EXTENDED + '\x8a' # 0x2A -> SET MODE OR SWITCH + '\x8b' # 0x2B -> CONTROL SEQUENCE PREFIX + '\x8c' # 0x2C -> MODIFY FIELD ATTRIBUTE + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> + '\x91' # 0x31 -> + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> INDEX RETURN + '\x94' # 0x34 -> PRESENTATION POSITION + '\x95' # 0x35 -> TRANSPARENT + '\x96' # 0x36 -> NUMERIC BACKSPACE + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> SUBSCRIPT + '\x99' # 0x39 -> INDENT TABULATION + '\x9a' # 0x3A -> REVERSE FORM FEED + '\x9b' # 0x3B -> CUSTOMER USE THREE + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\u05d0' # 0x41 -> HEBREW LETTER ALEF + '\u05d1' # 0x42 -> HEBREW LETTER BET + '\u05d2' # 0x43 -> HEBREW LETTER GIMEL + '\u05d3' # 0x44 -> HEBREW LETTER DALET + '\u05d4' # 0x45 -> HEBREW LETTER HE + '\u05d5' # 0x46 -> HEBREW LETTER VAV + '\u05d6' # 0x47 -> HEBREW LETTER ZAYIN + '\u05d7' # 0x48 -> HEBREW LETTER HET + '\u05d8' # 0x49 -> HEBREW LETTER TET + '\xa2' # 0x4A -> CENT SIGN + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '|' # 0x4F -> VERTICAL LINE + '&' # 0x50 -> AMPERSAND + '\u05d9' # 0x51 -> HEBREW LETTER YOD + '\u05da' # 0x52 -> HEBREW LETTER FINAL KAF + '\u05db' # 0x53 -> HEBREW LETTER KAF + '\u05dc' # 0x54 -> HEBREW LETTER LAMED + '\u05dd' # 0x55 -> HEBREW LETTER FINAL MEM + '\u05de' # 0x56 -> HEBREW LETTER MEM + '\u05df' # 0x57 -> HEBREW LETTER FINAL NUN + '\u05e0' # 0x58 -> HEBREW LETTER NUN + '\u05e1' # 0x59 -> HEBREW LETTER SAMEKH + '!' # 0x5A -> EXCLAMATION MARK + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '\xac' # 0x5F -> NOT SIGN + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\u05e2' # 0x62 -> HEBREW LETTER AYIN + '\u05e3' # 0x63 -> HEBREW LETTER FINAL PE + '\u05e4' # 0x64 -> HEBREW LETTER PE + '\u05e5' # 0x65 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0x66 -> HEBREW LETTER TSADI + '\u05e7' # 0x67 -> HEBREW LETTER QOF + '\u05e8' # 0x68 -> HEBREW LETTER RESH + '\u05e9' # 0x69 -> HEBREW LETTER SHIN + '\xa6' # 0x6A -> BROKEN BAR + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\ufffe' # 0x70 -> UNDEFINED + '\u05ea' # 0x71 -> HEBREW LETTER TAV + '\ufffe' # 0x72 -> UNDEFINED + '\ufffe' # 0x73 -> UNDEFINED + '\xa0' # 0x74 -> NO-BREAK SPACE + '\ufffe' # 0x75 -> UNDEFINED + '\ufffe' # 0x76 -> UNDEFINED + '\ufffe' # 0x77 -> UNDEFINED + '\u2017' # 0x78 -> DOUBLE LOW LINE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\ufffe' # 0x80 -> UNDEFINED + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\ufffe' # 0x9A -> UNDEFINED + '\ufffe' # 0x9B -> UNDEFINED + '\ufffe' # 0x9C -> UNDEFINED + '\xb8' # 0x9D -> CEDILLA + '\ufffe' # 0x9E -> UNDEFINED + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\ufffe' # 0xAA -> UNDEFINED + '\ufffe' # 0xAB -> UNDEFINED + '\ufffe' # 0xAC -> UNDEFINED + '\ufffe' # 0xAD -> UNDEFINED + '\ufffe' # 0xAE -> UNDEFINED + '\xae' # 0xAF -> REGISTERED SIGN + '^' # 0xB0 -> CIRCUMFLEX ACCENT + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '[' # 0xBA -> LEFT SQUARE BRACKET + ']' # 0xBB -> RIGHT SQUARE BRACKET + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\ufffe' # 0xCB -> UNDEFINED + '\ufffe' # 0xCC -> UNDEFINED + '\ufffe' # 0xCD -> UNDEFINED + '\ufffe' # 0xCE -> UNDEFINED + '\ufffe' # 0xCF -> UNDEFINED + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\ufffe' # 0xDB -> UNDEFINED + '\ufffe' # 0xDC -> UNDEFINED + '\ufffe' # 0xDD -> UNDEFINED + '\ufffe' # 0xDE -> UNDEFINED + '\ufffe' # 0xDF -> UNDEFINED + '\\' # 0xE0 -> REVERSE SOLIDUS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\ufffe' # 0xEB -> UNDEFINED + '\ufffe' # 0xEC -> UNDEFINED + '\ufffe' # 0xED -> UNDEFINED + '\ufffe' # 0xEE -> UNDEFINED + '\ufffe' # 0xEF -> UNDEFINED + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\ufffe' # 0xFB -> UNDEFINED + '\ufffe' # 0xFC -> UNDEFINED + '\ufffe' # 0xFD -> UNDEFINED + '\ufffe' # 0xFE -> UNDEFINED + '\x9f' # 0xFF -> EIGHT ONES +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp437.py b/Lib/encodings/cp437.py new file mode 100644 index 0000000..b6c75e2 --- /dev/null +++ b/Lib/encodings/cp437.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec cp437 generated from 'VENDORS/MICSFT/PC/CP437.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp437', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00a5, # YEN SIGN + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xa5' # 0x009d -> YEN SIGN + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a5: 0x009d, # YEN SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp500.py b/Lib/encodings/cp500.py new file mode 100644 index 0000000..5f61535 --- /dev/null +++ b/Lib/encodings/cp500.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp500 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp500', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '[' # 0x4A -> LEFT SQUARE BRACKET + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + ']' # 0x5A -> RIGHT SQUARE BRACKET + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\xa6' # 0x6A -> BROKEN BAR + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + '\xae' # 0xAF -> REGISTERED SIGN + '\xa2' # 0xB0 -> CENT SIGN + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '\xac' # 0xBA -> NOT SIGN + '|' # 0xBB -> VERTICAL LINE + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\\' # 0xE0 -> REVERSE SOLIDUS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp65001.py b/Lib/encodings/cp65001.py new file mode 100644 index 0000000..95cb2ae --- /dev/null +++ b/Lib/encodings/cp65001.py @@ -0,0 +1,43 @@ +""" +Code page 65001: Windows UTF-8 (CP_UTF8). +""" + +import codecs +import functools + +if not hasattr(codecs, 'code_page_encode'): + raise LookupError("cp65001 encoding is only available on Windows") + +### Codec APIs + +encode = functools.partial(codecs.code_page_encode, 65001) +_decode = functools.partial(codecs.code_page_decode, 65001) + +def decode(input, errors='strict'): + return codecs.code_page_decode(65001, input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = _decode + +class StreamWriter(codecs.StreamWriter): + encode = encode + +class StreamReader(codecs.StreamReader): + decode = _decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp65001', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/cp720.py b/Lib/encodings/cp720.py new file mode 100644 index 0000000..96d6096 --- /dev/null +++ b/Lib/encodings/cp720.py @@ -0,0 +1,309 @@ +"""Python Character Mapping Codec cp720 generated on Windows: +Vista 6.0.6002 SP2 Multiprocessor Free with the command: + python Tools/unicode/genwincodec.py 720 +"""#" + + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp720', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\x80' + '\x81' + '\xe9' # 0x82 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x83 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\x84' + '\xe0' # 0x85 -> LATIN SMALL LETTER A WITH GRAVE + '\x86' + '\xe7' # 0x87 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x88 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x89 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x8A -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x8B -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x8C -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\x8d' + '\x8e' + '\x8f' + '\x90' + '\u0651' # 0x91 -> ARABIC SHADDA + '\u0652' # 0x92 -> ARABIC SUKUN + '\xf4' # 0x93 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xa4' # 0x94 -> CURRENCY SIGN + '\u0640' # 0x95 -> ARABIC TATWEEL + '\xfb' # 0x96 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x97 -> LATIN SMALL LETTER U WITH GRAVE + '\u0621' # 0x98 -> ARABIC LETTER HAMZA + '\u0622' # 0x99 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0x9A -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0x9B -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\xa3' # 0x9C -> POUND SIGN + '\u0625' # 0x9D -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0x9E -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0x9F -> ARABIC LETTER ALEF + '\u0628' # 0xA0 -> ARABIC LETTER BEH + '\u0629' # 0xA1 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xA2 -> ARABIC LETTER TEH + '\u062b' # 0xA3 -> ARABIC LETTER THEH + '\u062c' # 0xA4 -> ARABIC LETTER JEEM + '\u062d' # 0xA5 -> ARABIC LETTER HAH + '\u062e' # 0xA6 -> ARABIC LETTER KHAH + '\u062f' # 0xA7 -> ARABIC LETTER DAL + '\u0630' # 0xA8 -> ARABIC LETTER THAL + '\u0631' # 0xA9 -> ARABIC LETTER REH + '\u0632' # 0xAA -> ARABIC LETTER ZAIN + '\u0633' # 0xAB -> ARABIC LETTER SEEN + '\u0634' # 0xAC -> ARABIC LETTER SHEEN + '\u0635' # 0xAD -> ARABIC LETTER SAD + '\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0xB0 -> LIGHT SHADE + '\u2592' # 0xB1 -> MEDIUM SHADE + '\u2593' # 0xB2 -> DARK SHADE + '\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0xB5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0xB6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0xB8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0xBD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0xBE -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0xC6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0xC7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0xCF -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0xD0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0xD1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0xD2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0xD3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0xD4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0xD5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0xD6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0xD7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0xD8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0xDB -> FULL BLOCK + '\u2584' # 0xDC -> LOWER HALF BLOCK + '\u258c' # 0xDD -> LEFT HALF BLOCK + '\u2590' # 0xDE -> RIGHT HALF BLOCK + '\u2580' # 0xDF -> UPPER HALF BLOCK + '\u0636' # 0xE0 -> ARABIC LETTER DAD + '\u0637' # 0xE1 -> ARABIC LETTER TAH + '\u0638' # 0xE2 -> ARABIC LETTER ZAH + '\u0639' # 0xE3 -> ARABIC LETTER AIN + '\u063a' # 0xE4 -> ARABIC LETTER GHAIN + '\u0641' # 0xE5 -> ARABIC LETTER FEH + '\xb5' # 0xE6 -> MICRO SIGN + '\u0642' # 0xE7 -> ARABIC LETTER QAF + '\u0643' # 0xE8 -> ARABIC LETTER KAF + '\u0644' # 0xE9 -> ARABIC LETTER LAM + '\u0645' # 0xEA -> ARABIC LETTER MEEM + '\u0646' # 0xEB -> ARABIC LETTER NOON + '\u0647' # 0xEC -> ARABIC LETTER HEH + '\u0648' # 0xED -> ARABIC LETTER WAW + '\u0649' # 0xEE -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xEF -> ARABIC LETTER YEH + '\u2261' # 0xF0 -> IDENTICAL TO + '\u064b' # 0xF1 -> ARABIC FATHATAN + '\u064c' # 0xF2 -> ARABIC DAMMATAN + '\u064d' # 0xF3 -> ARABIC KASRATAN + '\u064e' # 0xF4 -> ARABIC FATHA + '\u064f' # 0xF5 -> ARABIC DAMMA + '\u0650' # 0xF6 -> ARABIC KASRA + '\u2248' # 0xF7 -> ALMOST EQUAL TO + '\xb0' # 0xF8 -> DEGREE SIGN + '\u2219' # 0xF9 -> BULLET OPERATOR + '\xb7' # 0xFA -> MIDDLE DOT + '\u221a' # 0xFB -> SQUARE ROOT + '\u207f' # 0xFC -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0xFD -> SUPERSCRIPT TWO + '\u25a0' # 0xFE -> BLACK SQUARE + '\xa0' # 0xFF -> NO-BREAK SPACE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp737.py b/Lib/encodings/cp737.py new file mode 100644 index 0000000..9685bae --- /dev/null +++ b/Lib/encodings/cp737.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec cp737 generated from 'VENDORS/MICSFT/PC/CP737.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp737', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0391, # GREEK CAPITAL LETTER ALPHA + 0x0081: 0x0392, # GREEK CAPITAL LETTER BETA + 0x0082: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x0083: 0x0394, # GREEK CAPITAL LETTER DELTA + 0x0084: 0x0395, # GREEK CAPITAL LETTER EPSILON + 0x0085: 0x0396, # GREEK CAPITAL LETTER ZETA + 0x0086: 0x0397, # GREEK CAPITAL LETTER ETA + 0x0087: 0x0398, # GREEK CAPITAL LETTER THETA + 0x0088: 0x0399, # GREEK CAPITAL LETTER IOTA + 0x0089: 0x039a, # GREEK CAPITAL LETTER KAPPA + 0x008a: 0x039b, # GREEK CAPITAL LETTER LAMDA + 0x008b: 0x039c, # GREEK CAPITAL LETTER MU + 0x008c: 0x039d, # GREEK CAPITAL LETTER NU + 0x008d: 0x039e, # GREEK CAPITAL LETTER XI + 0x008e: 0x039f, # GREEK CAPITAL LETTER OMICRON + 0x008f: 0x03a0, # GREEK CAPITAL LETTER PI + 0x0090: 0x03a1, # GREEK CAPITAL LETTER RHO + 0x0091: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x0092: 0x03a4, # GREEK CAPITAL LETTER TAU + 0x0093: 0x03a5, # GREEK CAPITAL LETTER UPSILON + 0x0094: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x0095: 0x03a7, # GREEK CAPITAL LETTER CHI + 0x0096: 0x03a8, # GREEK CAPITAL LETTER PSI + 0x0097: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x0098: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x0099: 0x03b2, # GREEK SMALL LETTER BETA + 0x009a: 0x03b3, # GREEK SMALL LETTER GAMMA + 0x009b: 0x03b4, # GREEK SMALL LETTER DELTA + 0x009c: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x009d: 0x03b6, # GREEK SMALL LETTER ZETA + 0x009e: 0x03b7, # GREEK SMALL LETTER ETA + 0x009f: 0x03b8, # GREEK SMALL LETTER THETA + 0x00a0: 0x03b9, # GREEK SMALL LETTER IOTA + 0x00a1: 0x03ba, # GREEK SMALL LETTER KAPPA + 0x00a2: 0x03bb, # GREEK SMALL LETTER LAMDA + 0x00a3: 0x03bc, # GREEK SMALL LETTER MU + 0x00a4: 0x03bd, # GREEK SMALL LETTER NU + 0x00a5: 0x03be, # GREEK SMALL LETTER XI + 0x00a6: 0x03bf, # GREEK SMALL LETTER OMICRON + 0x00a7: 0x03c0, # GREEK SMALL LETTER PI + 0x00a8: 0x03c1, # GREEK SMALL LETTER RHO + 0x00a9: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00aa: 0x03c2, # GREEK SMALL LETTER FINAL SIGMA + 0x00ab: 0x03c4, # GREEK SMALL LETTER TAU + 0x00ac: 0x03c5, # GREEK SMALL LETTER UPSILON + 0x00ad: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ae: 0x03c7, # GREEK SMALL LETTER CHI + 0x00af: 0x03c8, # GREEK SMALL LETTER PSI + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03c9, # GREEK SMALL LETTER OMEGA + 0x00e1: 0x03ac, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x00e2: 0x03ad, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x00e3: 0x03ae, # GREEK SMALL LETTER ETA WITH TONOS + 0x00e4: 0x03ca, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x00e5: 0x03af, # GREEK SMALL LETTER IOTA WITH TONOS + 0x00e6: 0x03cc, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x00e7: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x00e8: 0x03cb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x00e9: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x00ea: 0x0386, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x00eb: 0x0388, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x00ec: 0x0389, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x00ed: 0x038a, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x00ee: 0x038c, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x00ef: 0x038e, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x00f0: 0x038f, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x03aa, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x00f5: 0x03ab, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0391' # 0x0080 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0x0081 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0x0082 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0x0083 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0x0084 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0x0085 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0x0086 -> GREEK CAPITAL LETTER ETA + '\u0398' # 0x0087 -> GREEK CAPITAL LETTER THETA + '\u0399' # 0x0088 -> GREEK CAPITAL LETTER IOTA + '\u039a' # 0x0089 -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0x008a -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0x008b -> GREEK CAPITAL LETTER MU + '\u039d' # 0x008c -> GREEK CAPITAL LETTER NU + '\u039e' # 0x008d -> GREEK CAPITAL LETTER XI + '\u039f' # 0x008e -> GREEK CAPITAL LETTER OMICRON + '\u03a0' # 0x008f -> GREEK CAPITAL LETTER PI + '\u03a1' # 0x0090 -> GREEK CAPITAL LETTER RHO + '\u03a3' # 0x0091 -> GREEK CAPITAL LETTER SIGMA + '\u03a4' # 0x0092 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0x0093 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0x0094 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0x0095 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0x0096 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0x0097 -> GREEK CAPITAL LETTER OMEGA + '\u03b1' # 0x0098 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0x0099 -> GREEK SMALL LETTER BETA + '\u03b3' # 0x009a -> GREEK SMALL LETTER GAMMA + '\u03b4' # 0x009b -> GREEK SMALL LETTER DELTA + '\u03b5' # 0x009c -> GREEK SMALL LETTER EPSILON + '\u03b6' # 0x009d -> GREEK SMALL LETTER ZETA + '\u03b7' # 0x009e -> GREEK SMALL LETTER ETA + '\u03b8' # 0x009f -> GREEK SMALL LETTER THETA + '\u03b9' # 0x00a0 -> GREEK SMALL LETTER IOTA + '\u03ba' # 0x00a1 -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0x00a2 -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0x00a3 -> GREEK SMALL LETTER MU + '\u03bd' # 0x00a4 -> GREEK SMALL LETTER NU + '\u03be' # 0x00a5 -> GREEK SMALL LETTER XI + '\u03bf' # 0x00a6 -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0x00a7 -> GREEK SMALL LETTER PI + '\u03c1' # 0x00a8 -> GREEK SMALL LETTER RHO + '\u03c3' # 0x00a9 -> GREEK SMALL LETTER SIGMA + '\u03c2' # 0x00aa -> GREEK SMALL LETTER FINAL SIGMA + '\u03c4' # 0x00ab -> GREEK SMALL LETTER TAU + '\u03c5' # 0x00ac -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0x00ad -> GREEK SMALL LETTER PHI + '\u03c7' # 0x00ae -> GREEK SMALL LETTER CHI + '\u03c8' # 0x00af -> GREEK SMALL LETTER PSI + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03c9' # 0x00e0 -> GREEK SMALL LETTER OMEGA + '\u03ac' # 0x00e1 -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u03ad' # 0x00e2 -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0x00e3 -> GREEK SMALL LETTER ETA WITH TONOS + '\u03ca' # 0x00e4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03af' # 0x00e5 -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03cc' # 0x00e6 -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0x00e7 -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03cb' # 0x00e8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03ce' # 0x00e9 -> GREEK SMALL LETTER OMEGA WITH TONOS + '\u0386' # 0x00ea -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\u0388' # 0x00eb -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0389' # 0x00ec -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0x00ed -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\u038c' # 0x00ee -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\u038e' # 0x00ef -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u038f' # 0x00f0 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u03aa' # 0x00f4 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u03ab' # 0x00f5 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00f7: 0x00f6, # DIVISION SIGN + 0x0386: 0x00ea, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0388: 0x00eb, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x0389: 0x00ec, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x038a: 0x00ed, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x038c: 0x00ee, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x038e: 0x00ef, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x038f: 0x00f0, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0391: 0x0080, # GREEK CAPITAL LETTER ALPHA + 0x0392: 0x0081, # GREEK CAPITAL LETTER BETA + 0x0393: 0x0082, # GREEK CAPITAL LETTER GAMMA + 0x0394: 0x0083, # GREEK CAPITAL LETTER DELTA + 0x0395: 0x0084, # GREEK CAPITAL LETTER EPSILON + 0x0396: 0x0085, # GREEK CAPITAL LETTER ZETA + 0x0397: 0x0086, # GREEK CAPITAL LETTER ETA + 0x0398: 0x0087, # GREEK CAPITAL LETTER THETA + 0x0399: 0x0088, # GREEK CAPITAL LETTER IOTA + 0x039a: 0x0089, # GREEK CAPITAL LETTER KAPPA + 0x039b: 0x008a, # GREEK CAPITAL LETTER LAMDA + 0x039c: 0x008b, # GREEK CAPITAL LETTER MU + 0x039d: 0x008c, # GREEK CAPITAL LETTER NU + 0x039e: 0x008d, # GREEK CAPITAL LETTER XI + 0x039f: 0x008e, # GREEK CAPITAL LETTER OMICRON + 0x03a0: 0x008f, # GREEK CAPITAL LETTER PI + 0x03a1: 0x0090, # GREEK CAPITAL LETTER RHO + 0x03a3: 0x0091, # GREEK CAPITAL LETTER SIGMA + 0x03a4: 0x0092, # GREEK CAPITAL LETTER TAU + 0x03a5: 0x0093, # GREEK CAPITAL LETTER UPSILON + 0x03a6: 0x0094, # GREEK CAPITAL LETTER PHI + 0x03a7: 0x0095, # GREEK CAPITAL LETTER CHI + 0x03a8: 0x0096, # GREEK CAPITAL LETTER PSI + 0x03a9: 0x0097, # GREEK CAPITAL LETTER OMEGA + 0x03aa: 0x00f4, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x03ab: 0x00f5, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x03ac: 0x00e1, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x03ad: 0x00e2, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x03ae: 0x00e3, # GREEK SMALL LETTER ETA WITH TONOS + 0x03af: 0x00e5, # GREEK SMALL LETTER IOTA WITH TONOS + 0x03b1: 0x0098, # GREEK SMALL LETTER ALPHA + 0x03b2: 0x0099, # GREEK SMALL LETTER BETA + 0x03b3: 0x009a, # GREEK SMALL LETTER GAMMA + 0x03b4: 0x009b, # GREEK SMALL LETTER DELTA + 0x03b5: 0x009c, # GREEK SMALL LETTER EPSILON + 0x03b6: 0x009d, # GREEK SMALL LETTER ZETA + 0x03b7: 0x009e, # GREEK SMALL LETTER ETA + 0x03b8: 0x009f, # GREEK SMALL LETTER THETA + 0x03b9: 0x00a0, # GREEK SMALL LETTER IOTA + 0x03ba: 0x00a1, # GREEK SMALL LETTER KAPPA + 0x03bb: 0x00a2, # GREEK SMALL LETTER LAMDA + 0x03bc: 0x00a3, # GREEK SMALL LETTER MU + 0x03bd: 0x00a4, # GREEK SMALL LETTER NU + 0x03be: 0x00a5, # GREEK SMALL LETTER XI + 0x03bf: 0x00a6, # GREEK SMALL LETTER OMICRON + 0x03c0: 0x00a7, # GREEK SMALL LETTER PI + 0x03c1: 0x00a8, # GREEK SMALL LETTER RHO + 0x03c2: 0x00aa, # GREEK SMALL LETTER FINAL SIGMA + 0x03c3: 0x00a9, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00ab, # GREEK SMALL LETTER TAU + 0x03c5: 0x00ac, # GREEK SMALL LETTER UPSILON + 0x03c6: 0x00ad, # GREEK SMALL LETTER PHI + 0x03c7: 0x00ae, # GREEK SMALL LETTER CHI + 0x03c8: 0x00af, # GREEK SMALL LETTER PSI + 0x03c9: 0x00e0, # GREEK SMALL LETTER OMEGA + 0x03ca: 0x00e4, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x03cb: 0x00e8, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x03cc: 0x00e6, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x03cd: 0x00e7, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x03ce: 0x00e9, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp775.py b/Lib/encodings/cp775.py new file mode 100644 index 0000000..fe06e7b --- /dev/null +++ b/Lib/encodings/cp775.py @@ -0,0 +1,697 @@ +""" Python Character Mapping Codec cp775 generated from 'VENDORS/MICSFT/PC/CP775.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp775', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x0101, # LATIN SMALL LETTER A WITH MACRON + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x0123, # LATIN SMALL LETTER G WITH CEDILLA + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x0107, # LATIN SMALL LETTER C WITH ACUTE + 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE + 0x0089: 0x0113, # LATIN SMALL LETTER E WITH MACRON + 0x008a: 0x0156, # LATIN CAPITAL LETTER R WITH CEDILLA + 0x008b: 0x0157, # LATIN SMALL LETTER R WITH CEDILLA + 0x008c: 0x012b, # LATIN SMALL LETTER I WITH MACRON + 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x014d, # LATIN SMALL LETTER O WITH MACRON + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA + 0x0096: 0x00a2, # CENT SIGN + 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE + 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x00a4, # CURRENCY SIGN + 0x00a0: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON + 0x00a1: 0x012a, # LATIN CAPITAL LETTER I WITH MACRON + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x00a4: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00a5: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE + 0x00a6: 0x201d, # RIGHT DOUBLE QUOTATION MARK + 0x00a7: 0x00a6, # BROKEN BAR + 0x00a8: 0x00a9, # COPYRIGHT SIGN + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK + 0x00b6: 0x010c, # LATIN CAPITAL LETTER C WITH CARON + 0x00b7: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK + 0x00b8: 0x0116, # LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x012e, # LATIN CAPITAL LETTER I WITH OGONEK + 0x00be: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x0172, # LATIN CAPITAL LETTER U WITH OGONEK + 0x00c7: 0x016a, # LATIN CAPITAL LETTER U WITH MACRON + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON + 0x00d0: 0x0105, # LATIN SMALL LETTER A WITH OGONEK + 0x00d1: 0x010d, # LATIN SMALL LETTER C WITH CARON + 0x00d2: 0x0119, # LATIN SMALL LETTER E WITH OGONEK + 0x00d3: 0x0117, # LATIN SMALL LETTER E WITH DOT ABOVE + 0x00d4: 0x012f, # LATIN SMALL LETTER I WITH OGONEK + 0x00d5: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00d6: 0x0173, # LATIN SMALL LETTER U WITH OGONEK + 0x00d7: 0x016b, # LATIN SMALL LETTER U WITH MACRON + 0x00d8: 0x017e, # LATIN SMALL LETTER Z WITH CARON + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e2: 0x014c, # LATIN CAPITAL LETTER O WITH MACRON + 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x0144, # LATIN SMALL LETTER N WITH ACUTE + 0x00e8: 0x0136, # LATIN CAPITAL LETTER K WITH CEDILLA + 0x00e9: 0x0137, # LATIN SMALL LETTER K WITH CEDILLA + 0x00ea: 0x013b, # LATIN CAPITAL LETTER L WITH CEDILLA + 0x00eb: 0x013c, # LATIN SMALL LETTER L WITH CEDILLA + 0x00ec: 0x0146, # LATIN SMALL LETTER N WITH CEDILLA + 0x00ed: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON + 0x00ee: 0x0145, # LATIN CAPITAL LETTER N WITH CEDILLA + 0x00ef: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x201c, # LEFT DOUBLE QUOTATION MARK + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x201e, # DOUBLE LOW-9 QUOTATION MARK + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0106' # 0x0080 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\u0101' # 0x0083 -> LATIN SMALL LETTER A WITH MACRON + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u0123' # 0x0085 -> LATIN SMALL LETTER G WITH CEDILLA + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\u0107' # 0x0087 -> LATIN SMALL LETTER C WITH ACUTE + '\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE + '\u0113' # 0x0089 -> LATIN SMALL LETTER E WITH MACRON + '\u0156' # 0x008a -> LATIN CAPITAL LETTER R WITH CEDILLA + '\u0157' # 0x008b -> LATIN SMALL LETTER R WITH CEDILLA + '\u012b' # 0x008c -> LATIN SMALL LETTER I WITH MACRON + '\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\u014d' # 0x0093 -> LATIN SMALL LETTER O WITH MACRON + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u0122' # 0x0095 -> LATIN CAPITAL LETTER G WITH CEDILLA + '\xa2' # 0x0096 -> CENT SIGN + '\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\xa4' # 0x009f -> CURRENCY SIGN + '\u0100' # 0x00a0 -> LATIN CAPITAL LETTER A WITH MACRON + '\u012a' # 0x00a1 -> LATIN CAPITAL LETTER I WITH MACRON + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\u017b' # 0x00a3 -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017c' # 0x00a4 -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u017a' # 0x00a5 -> LATIN SMALL LETTER Z WITH ACUTE + '\u201d' # 0x00a6 -> RIGHT DOUBLE QUOTATION MARK + '\xa6' # 0x00a7 -> BROKEN BAR + '\xa9' # 0x00a8 -> COPYRIGHT SIGN + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\u0141' # 0x00ad -> LATIN CAPITAL LETTER L WITH STROKE + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u0104' # 0x00b5 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u010c' # 0x00b6 -> LATIN CAPITAL LETTER C WITH CARON + '\u0118' # 0x00b7 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0116' # 0x00b8 -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u012e' # 0x00bd -> LATIN CAPITAL LETTER I WITH OGONEK + '\u0160' # 0x00be -> LATIN CAPITAL LETTER S WITH CARON + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u0172' # 0x00c6 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u016a' # 0x00c7 -> LATIN CAPITAL LETTER U WITH MACRON + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u017d' # 0x00cf -> LATIN CAPITAL LETTER Z WITH CARON + '\u0105' # 0x00d0 -> LATIN SMALL LETTER A WITH OGONEK + '\u010d' # 0x00d1 -> LATIN SMALL LETTER C WITH CARON + '\u0119' # 0x00d2 -> LATIN SMALL LETTER E WITH OGONEK + '\u0117' # 0x00d3 -> LATIN SMALL LETTER E WITH DOT ABOVE + '\u012f' # 0x00d4 -> LATIN SMALL LETTER I WITH OGONEK + '\u0161' # 0x00d5 -> LATIN SMALL LETTER S WITH CARON + '\u0173' # 0x00d6 -> LATIN SMALL LETTER U WITH OGONEK + '\u016b' # 0x00d7 -> LATIN SMALL LETTER U WITH MACRON + '\u017e' # 0x00d8 -> LATIN SMALL LETTER Z WITH CARON + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) + '\u014c' # 0x00e2 -> LATIN CAPITAL LETTER O WITH MACRON + '\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\u0144' # 0x00e7 -> LATIN SMALL LETTER N WITH ACUTE + '\u0136' # 0x00e8 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u0137' # 0x00e9 -> LATIN SMALL LETTER K WITH CEDILLA + '\u013b' # 0x00ea -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u013c' # 0x00eb -> LATIN SMALL LETTER L WITH CEDILLA + '\u0146' # 0x00ec -> LATIN SMALL LETTER N WITH CEDILLA + '\u0112' # 0x00ed -> LATIN CAPITAL LETTER E WITH MACRON + '\u0145' # 0x00ee -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u2019' # 0x00ef -> RIGHT SINGLE QUOTATION MARK + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u201c' # 0x00f2 -> LEFT DOUBLE QUOTATION MARK + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u201e' # 0x00f7 -> DOUBLE LOW-9 QUOTATION MARK + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a2: 0x0096, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x009f, # CURRENCY SIGN + 0x00a6: 0x00a7, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a9: 0x00a8, # COPYRIGHT SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0100: 0x00a0, # LATIN CAPITAL LETTER A WITH MACRON + 0x0101: 0x0083, # LATIN SMALL LETTER A WITH MACRON + 0x0104: 0x00b5, # LATIN CAPITAL LETTER A WITH OGONEK + 0x0105: 0x00d0, # LATIN SMALL LETTER A WITH OGONEK + 0x0106: 0x0080, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0107: 0x0087, # LATIN SMALL LETTER C WITH ACUTE + 0x010c: 0x00b6, # LATIN CAPITAL LETTER C WITH CARON + 0x010d: 0x00d1, # LATIN SMALL LETTER C WITH CARON + 0x0112: 0x00ed, # LATIN CAPITAL LETTER E WITH MACRON + 0x0113: 0x0089, # LATIN SMALL LETTER E WITH MACRON + 0x0116: 0x00b8, # LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x0117: 0x00d3, # LATIN SMALL LETTER E WITH DOT ABOVE + 0x0118: 0x00b7, # LATIN CAPITAL LETTER E WITH OGONEK + 0x0119: 0x00d2, # LATIN SMALL LETTER E WITH OGONEK + 0x0122: 0x0095, # LATIN CAPITAL LETTER G WITH CEDILLA + 0x0123: 0x0085, # LATIN SMALL LETTER G WITH CEDILLA + 0x012a: 0x00a1, # LATIN CAPITAL LETTER I WITH MACRON + 0x012b: 0x008c, # LATIN SMALL LETTER I WITH MACRON + 0x012e: 0x00bd, # LATIN CAPITAL LETTER I WITH OGONEK + 0x012f: 0x00d4, # LATIN SMALL LETTER I WITH OGONEK + 0x0136: 0x00e8, # LATIN CAPITAL LETTER K WITH CEDILLA + 0x0137: 0x00e9, # LATIN SMALL LETTER K WITH CEDILLA + 0x013b: 0x00ea, # LATIN CAPITAL LETTER L WITH CEDILLA + 0x013c: 0x00eb, # LATIN SMALL LETTER L WITH CEDILLA + 0x0141: 0x00ad, # LATIN CAPITAL LETTER L WITH STROKE + 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE + 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE + 0x0144: 0x00e7, # LATIN SMALL LETTER N WITH ACUTE + 0x0145: 0x00ee, # LATIN CAPITAL LETTER N WITH CEDILLA + 0x0146: 0x00ec, # LATIN SMALL LETTER N WITH CEDILLA + 0x014c: 0x00e2, # LATIN CAPITAL LETTER O WITH MACRON + 0x014d: 0x0093, # LATIN SMALL LETTER O WITH MACRON + 0x0156: 0x008a, # LATIN CAPITAL LETTER R WITH CEDILLA + 0x0157: 0x008b, # LATIN SMALL LETTER R WITH CEDILLA + 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE + 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE + 0x0160: 0x00be, # LATIN CAPITAL LETTER S WITH CARON + 0x0161: 0x00d5, # LATIN SMALL LETTER S WITH CARON + 0x016a: 0x00c7, # LATIN CAPITAL LETTER U WITH MACRON + 0x016b: 0x00d7, # LATIN SMALL LETTER U WITH MACRON + 0x0172: 0x00c6, # LATIN CAPITAL LETTER U WITH OGONEK + 0x0173: 0x00d6, # LATIN SMALL LETTER U WITH OGONEK + 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x017a: 0x00a5, # LATIN SMALL LETTER Z WITH ACUTE + 0x017b: 0x00a3, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x017c: 0x00a4, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x017d: 0x00cf, # LATIN CAPITAL LETTER Z WITH CARON + 0x017e: 0x00d8, # LATIN SMALL LETTER Z WITH CARON + 0x2019: 0x00ef, # RIGHT SINGLE QUOTATION MARK + 0x201c: 0x00f2, # LEFT DOUBLE QUOTATION MARK + 0x201d: 0x00a6, # RIGHT DOUBLE QUOTATION MARK + 0x201e: 0x00f7, # DOUBLE LOW-9 QUOTATION MARK + 0x2219: 0x00f9, # BULLET OPERATOR + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp850.py b/Lib/encodings/cp850.py new file mode 100644 index 0000000..f98aef9 --- /dev/null +++ b/Lib/encodings/cp850.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP850.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp850', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH + 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: 0x0131, # LATIN SMALL LETTER DOTLESS I + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN + 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2017, # DOUBLE LOW LINE + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa9' # 0x00b8 -> COPYRIGHT SIGN + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0x00bd -> CENT SIGN + '\xa5' # 0x00be -> YEN SIGN + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH + '\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH + '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + '\u0131' # 0x00d5 -> LATIN SMALL LETTER DOTLESS I + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\xa6' # 0x00dd -> BROKEN BAR + '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN + '\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xaf' # 0x00ee -> MACRON + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2017' # 0x00f2 -> DOUBLE LOW LINE + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0131: 0x00d5, # LATIN SMALL LETTER DOTLESS I + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x2017: 0x00f2, # DOUBLE LOW LINE + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp852.py b/Lib/encodings/cp852.py new file mode 100644 index 0000000..34d8a0e --- /dev/null +++ b/Lib/encodings/cp852.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP852.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp852', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x016f, # LATIN SMALL LETTER U WITH RING ABOVE + 0x0086: 0x0107, # LATIN SMALL LETTER C WITH ACUTE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x0150, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + 0x008b: 0x0151, # LATIN SMALL LETTER O WITH DOUBLE ACUTE + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x0139, # LATIN CAPITAL LETTER L WITH ACUTE + 0x0092: 0x013a, # LATIN SMALL LETTER L WITH ACUTE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x013d, # LATIN CAPITAL LETTER L WITH CARON + 0x0096: 0x013e, # LATIN SMALL LETTER L WITH CARON + 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE + 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x0164, # LATIN CAPITAL LETTER T WITH CARON + 0x009c: 0x0165, # LATIN SMALL LETTER T WITH CARON + 0x009d: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x010d, # LATIN SMALL LETTER C WITH CARON + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK + 0x00a5: 0x0105, # LATIN SMALL LETTER A WITH OGONEK + 0x00a6: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON + 0x00a7: 0x017e, # LATIN SMALL LETTER Z WITH CARON + 0x00a8: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK + 0x00a9: 0x0119, # LATIN SMALL LETTER E WITH OGONEK + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE + 0x00ac: 0x010c, # LATIN CAPITAL LETTER C WITH CARON + 0x00ad: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x011a, # LATIN CAPITAL LETTER E WITH CARON + 0x00b8: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x00be: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x0102, # LATIN CAPITAL LETTER A WITH BREVE + 0x00c7: 0x0103, # LATIN SMALL LETTER A WITH BREVE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x0111, # LATIN SMALL LETTER D WITH STROKE + 0x00d1: 0x0110, # LATIN CAPITAL LETTER D WITH STROKE + 0x00d2: 0x010e, # LATIN CAPITAL LETTER D WITH CARON + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x010f, # LATIN SMALL LETTER D WITH CARON + 0x00d5: 0x0147, # LATIN CAPITAL LETTER N WITH CARON + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x011b, # LATIN SMALL LETTER E WITH CARON + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x0162, # LATIN CAPITAL LETTER T WITH CEDILLA + 0x00de: 0x016e, # LATIN CAPITAL LETTER U WITH RING ABOVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE + 0x00e4: 0x0144, # LATIN SMALL LETTER N WITH ACUTE + 0x00e5: 0x0148, # LATIN SMALL LETTER N WITH CARON + 0x00e6: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00e7: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00e8: 0x0154, # LATIN CAPITAL LETTER R WITH ACUTE + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x0155, # LATIN SMALL LETTER R WITH ACUTE + 0x00eb: 0x0170, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x02dd, # DOUBLE ACUTE ACCENT + 0x00f2: 0x02db, # OGONEK + 0x00f3: 0x02c7, # CARON + 0x00f4: 0x02d8, # BREVE + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x02d9, # DOT ABOVE + 0x00fb: 0x0171, # LATIN SMALL LETTER U WITH DOUBLE ACUTE + 0x00fc: 0x0158, # LATIN CAPITAL LETTER R WITH CARON + 0x00fd: 0x0159, # LATIN SMALL LETTER R WITH CARON + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u016f' # 0x0085 -> LATIN SMALL LETTER U WITH RING ABOVE + '\u0107' # 0x0086 -> LATIN SMALL LETTER C WITH ACUTE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0150' # 0x008a -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\u0151' # 0x008b -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0106' # 0x008f -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0139' # 0x0091 -> LATIN CAPITAL LETTER L WITH ACUTE + '\u013a' # 0x0092 -> LATIN SMALL LETTER L WITH ACUTE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u013d' # 0x0095 -> LATIN CAPITAL LETTER L WITH CARON + '\u013e' # 0x0096 -> LATIN SMALL LETTER L WITH CARON + '\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0164' # 0x009b -> LATIN CAPITAL LETTER T WITH CARON + '\u0165' # 0x009c -> LATIN SMALL LETTER T WITH CARON + '\u0141' # 0x009d -> LATIN CAPITAL LETTER L WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\u010d' # 0x009f -> LATIN SMALL LETTER C WITH CARON + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\u0104' # 0x00a4 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0105' # 0x00a5 -> LATIN SMALL LETTER A WITH OGONEK + '\u017d' # 0x00a6 -> LATIN CAPITAL LETTER Z WITH CARON + '\u017e' # 0x00a7 -> LATIN SMALL LETTER Z WITH CARON + '\u0118' # 0x00a8 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0119' # 0x00a9 -> LATIN SMALL LETTER E WITH OGONEK + '\xac' # 0x00aa -> NOT SIGN + '\u017a' # 0x00ab -> LATIN SMALL LETTER Z WITH ACUTE + '\u010c' # 0x00ac -> LATIN CAPITAL LETTER C WITH CARON + '\u015f' # 0x00ad -> LATIN SMALL LETTER S WITH CEDILLA + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u011a' # 0x00b7 -> LATIN CAPITAL LETTER E WITH CARON + '\u015e' # 0x00b8 -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u017b' # 0x00bd -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017c' # 0x00be -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u0102' # 0x00c6 -> LATIN CAPITAL LETTER A WITH BREVE + '\u0103' # 0x00c7 -> LATIN SMALL LETTER A WITH BREVE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\u0111' # 0x00d0 -> LATIN SMALL LETTER D WITH STROKE + '\u0110' # 0x00d1 -> LATIN CAPITAL LETTER D WITH STROKE + '\u010e' # 0x00d2 -> LATIN CAPITAL LETTER D WITH CARON + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u010f' # 0x00d4 -> LATIN SMALL LETTER D WITH CARON + '\u0147' # 0x00d5 -> LATIN CAPITAL LETTER N WITH CARON + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u011b' # 0x00d8 -> LATIN SMALL LETTER E WITH CARON + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u0162' # 0x00dd -> LATIN CAPITAL LETTER T WITH CEDILLA + '\u016e' # 0x00de -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0144' # 0x00e4 -> LATIN SMALL LETTER N WITH ACUTE + '\u0148' # 0x00e5 -> LATIN SMALL LETTER N WITH CARON + '\u0160' # 0x00e6 -> LATIN CAPITAL LETTER S WITH CARON + '\u0161' # 0x00e7 -> LATIN SMALL LETTER S WITH CARON + '\u0154' # 0x00e8 -> LATIN CAPITAL LETTER R WITH ACUTE + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0155' # 0x00ea -> LATIN SMALL LETTER R WITH ACUTE + '\u0170' # 0x00eb -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0163' # 0x00ee -> LATIN SMALL LETTER T WITH CEDILLA + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\u02dd' # 0x00f1 -> DOUBLE ACUTE ACCENT + '\u02db' # 0x00f2 -> OGONEK + '\u02c7' # 0x00f3 -> CARON + '\u02d8' # 0x00f4 -> BREVE + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\u02d9' # 0x00fa -> DOT ABOVE + '\u0171' # 0x00fb -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\u0158' # 0x00fc -> LATIN CAPITAL LETTER R WITH CARON + '\u0159' # 0x00fd -> LATIN SMALL LETTER R WITH CARON + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b8: 0x00f7, # CEDILLA + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x0102: 0x00c6, # LATIN CAPITAL LETTER A WITH BREVE + 0x0103: 0x00c7, # LATIN SMALL LETTER A WITH BREVE + 0x0104: 0x00a4, # LATIN CAPITAL LETTER A WITH OGONEK + 0x0105: 0x00a5, # LATIN SMALL LETTER A WITH OGONEK + 0x0106: 0x008f, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0107: 0x0086, # LATIN SMALL LETTER C WITH ACUTE + 0x010c: 0x00ac, # LATIN CAPITAL LETTER C WITH CARON + 0x010d: 0x009f, # LATIN SMALL LETTER C WITH CARON + 0x010e: 0x00d2, # LATIN CAPITAL LETTER D WITH CARON + 0x010f: 0x00d4, # LATIN SMALL LETTER D WITH CARON + 0x0110: 0x00d1, # LATIN CAPITAL LETTER D WITH STROKE + 0x0111: 0x00d0, # LATIN SMALL LETTER D WITH STROKE + 0x0118: 0x00a8, # LATIN CAPITAL LETTER E WITH OGONEK + 0x0119: 0x00a9, # LATIN SMALL LETTER E WITH OGONEK + 0x011a: 0x00b7, # LATIN CAPITAL LETTER E WITH CARON + 0x011b: 0x00d8, # LATIN SMALL LETTER E WITH CARON + 0x0139: 0x0091, # LATIN CAPITAL LETTER L WITH ACUTE + 0x013a: 0x0092, # LATIN SMALL LETTER L WITH ACUTE + 0x013d: 0x0095, # LATIN CAPITAL LETTER L WITH CARON + 0x013e: 0x0096, # LATIN SMALL LETTER L WITH CARON + 0x0141: 0x009d, # LATIN CAPITAL LETTER L WITH STROKE + 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE + 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE + 0x0144: 0x00e4, # LATIN SMALL LETTER N WITH ACUTE + 0x0147: 0x00d5, # LATIN CAPITAL LETTER N WITH CARON + 0x0148: 0x00e5, # LATIN SMALL LETTER N WITH CARON + 0x0150: 0x008a, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + 0x0151: 0x008b, # LATIN SMALL LETTER O WITH DOUBLE ACUTE + 0x0154: 0x00e8, # LATIN CAPITAL LETTER R WITH ACUTE + 0x0155: 0x00ea, # LATIN SMALL LETTER R WITH ACUTE + 0x0158: 0x00fc, # LATIN CAPITAL LETTER R WITH CARON + 0x0159: 0x00fd, # LATIN SMALL LETTER R WITH CARON + 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE + 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE + 0x015e: 0x00b8, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x015f: 0x00ad, # LATIN SMALL LETTER S WITH CEDILLA + 0x0160: 0x00e6, # LATIN CAPITAL LETTER S WITH CARON + 0x0161: 0x00e7, # LATIN SMALL LETTER S WITH CARON + 0x0162: 0x00dd, # LATIN CAPITAL LETTER T WITH CEDILLA + 0x0163: 0x00ee, # LATIN SMALL LETTER T WITH CEDILLA + 0x0164: 0x009b, # LATIN CAPITAL LETTER T WITH CARON + 0x0165: 0x009c, # LATIN SMALL LETTER T WITH CARON + 0x016e: 0x00de, # LATIN CAPITAL LETTER U WITH RING ABOVE + 0x016f: 0x0085, # LATIN SMALL LETTER U WITH RING ABOVE + 0x0170: 0x00eb, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + 0x0171: 0x00fb, # LATIN SMALL LETTER U WITH DOUBLE ACUTE + 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x017a: 0x00ab, # LATIN SMALL LETTER Z WITH ACUTE + 0x017b: 0x00bd, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x017c: 0x00be, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x017d: 0x00a6, # LATIN CAPITAL LETTER Z WITH CARON + 0x017e: 0x00a7, # LATIN SMALL LETTER Z WITH CARON + 0x02c7: 0x00f3, # CARON + 0x02d8: 0x00f4, # BREVE + 0x02d9: 0x00fa, # DOT ABOVE + 0x02db: 0x00f2, # OGONEK + 0x02dd: 0x00f1, # DOUBLE ACUTE ACCENT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp855.py b/Lib/encodings/cp855.py new file mode 100644 index 0000000..4fe9210 --- /dev/null +++ b/Lib/encodings/cp855.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP855.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp855', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0452, # CYRILLIC SMALL LETTER DJE + 0x0081: 0x0402, # CYRILLIC CAPITAL LETTER DJE + 0x0082: 0x0453, # CYRILLIC SMALL LETTER GJE + 0x0083: 0x0403, # CYRILLIC CAPITAL LETTER GJE + 0x0084: 0x0451, # CYRILLIC SMALL LETTER IO + 0x0085: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x0086: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0087: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0088: 0x0455, # CYRILLIC SMALL LETTER DZE + 0x0089: 0x0405, # CYRILLIC CAPITAL LETTER DZE + 0x008a: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x008b: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x008c: 0x0457, # CYRILLIC SMALL LETTER YI + 0x008d: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x008e: 0x0458, # CYRILLIC SMALL LETTER JE + 0x008f: 0x0408, # CYRILLIC CAPITAL LETTER JE + 0x0090: 0x0459, # CYRILLIC SMALL LETTER LJE + 0x0091: 0x0409, # CYRILLIC CAPITAL LETTER LJE + 0x0092: 0x045a, # CYRILLIC SMALL LETTER NJE + 0x0093: 0x040a, # CYRILLIC CAPITAL LETTER NJE + 0x0094: 0x045b, # CYRILLIC SMALL LETTER TSHE + 0x0095: 0x040b, # CYRILLIC CAPITAL LETTER TSHE + 0x0096: 0x045c, # CYRILLIC SMALL LETTER KJE + 0x0097: 0x040c, # CYRILLIC CAPITAL LETTER KJE + 0x0098: 0x045e, # CYRILLIC SMALL LETTER SHORT U + 0x0099: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U + 0x009a: 0x045f, # CYRILLIC SMALL LETTER DZHE + 0x009b: 0x040f, # CYRILLIC CAPITAL LETTER DZHE + 0x009c: 0x044e, # CYRILLIC SMALL LETTER YU + 0x009d: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009e: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x009f: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x00a2: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a3: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x00a4: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00a5: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x00a6: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a7: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x00a8: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a9: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x00aa: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00ab: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x00ac: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00ad: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00b6: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x00b7: 0x0438, # CYRILLIC SMALL LETTER I + 0x00b8: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00be: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00c7: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00d1: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x00d2: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00d3: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x00d4: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00d5: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x00d6: 0x043e, # CYRILLIC SMALL LETTER O + 0x00d7: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x00d8: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x00de: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00e1: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e2: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x00e3: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e4: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x00e5: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e6: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x00e7: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e8: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x00e9: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00ea: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x00eb: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00ec: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x00ed: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ee: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x00ef: 0x2116, # NUMERO SIGN + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00f2: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x00f3: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00f4: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x00f5: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00f6: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x00f7: 0x044d, # CYRILLIC SMALL LETTER E + 0x00f8: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x00f9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00fa: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x00fb: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00fc: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x00fd: 0x00a7, # SECTION SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0452' # 0x0080 -> CYRILLIC SMALL LETTER DJE + '\u0402' # 0x0081 -> CYRILLIC CAPITAL LETTER DJE + '\u0453' # 0x0082 -> CYRILLIC SMALL LETTER GJE + '\u0403' # 0x0083 -> CYRILLIC CAPITAL LETTER GJE + '\u0451' # 0x0084 -> CYRILLIC SMALL LETTER IO + '\u0401' # 0x0085 -> CYRILLIC CAPITAL LETTER IO + '\u0454' # 0x0086 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0404' # 0x0087 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0455' # 0x0088 -> CYRILLIC SMALL LETTER DZE + '\u0405' # 0x0089 -> CYRILLIC CAPITAL LETTER DZE + '\u0456' # 0x008a -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0406' # 0x008b -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0457' # 0x008c -> CYRILLIC SMALL LETTER YI + '\u0407' # 0x008d -> CYRILLIC CAPITAL LETTER YI + '\u0458' # 0x008e -> CYRILLIC SMALL LETTER JE + '\u0408' # 0x008f -> CYRILLIC CAPITAL LETTER JE + '\u0459' # 0x0090 -> CYRILLIC SMALL LETTER LJE + '\u0409' # 0x0091 -> CYRILLIC CAPITAL LETTER LJE + '\u045a' # 0x0092 -> CYRILLIC SMALL LETTER NJE + '\u040a' # 0x0093 -> CYRILLIC CAPITAL LETTER NJE + '\u045b' # 0x0094 -> CYRILLIC SMALL LETTER TSHE + '\u040b' # 0x0095 -> CYRILLIC CAPITAL LETTER TSHE + '\u045c' # 0x0096 -> CYRILLIC SMALL LETTER KJE + '\u040c' # 0x0097 -> CYRILLIC CAPITAL LETTER KJE + '\u045e' # 0x0098 -> CYRILLIC SMALL LETTER SHORT U + '\u040e' # 0x0099 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045f' # 0x009a -> CYRILLIC SMALL LETTER DZHE + '\u040f' # 0x009b -> CYRILLIC CAPITAL LETTER DZHE + '\u044e' # 0x009c -> CYRILLIC SMALL LETTER YU + '\u042e' # 0x009d -> CYRILLIC CAPITAL LETTER YU + '\u044a' # 0x009e -> CYRILLIC SMALL LETTER HARD SIGN + '\u042a' # 0x009f -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + '\u0410' # 0x00a1 -> CYRILLIC CAPITAL LETTER A + '\u0431' # 0x00a2 -> CYRILLIC SMALL LETTER BE + '\u0411' # 0x00a3 -> CYRILLIC CAPITAL LETTER BE + '\u0446' # 0x00a4 -> CYRILLIC SMALL LETTER TSE + '\u0426' # 0x00a5 -> CYRILLIC CAPITAL LETTER TSE + '\u0434' # 0x00a6 -> CYRILLIC SMALL LETTER DE + '\u0414' # 0x00a7 -> CYRILLIC CAPITAL LETTER DE + '\u0435' # 0x00a8 -> CYRILLIC SMALL LETTER IE + '\u0415' # 0x00a9 -> CYRILLIC CAPITAL LETTER IE + '\u0444' # 0x00aa -> CYRILLIC SMALL LETTER EF + '\u0424' # 0x00ab -> CYRILLIC CAPITAL LETTER EF + '\u0433' # 0x00ac -> CYRILLIC SMALL LETTER GHE + '\u0413' # 0x00ad -> CYRILLIC CAPITAL LETTER GHE + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u0445' # 0x00b5 -> CYRILLIC SMALL LETTER HA + '\u0425' # 0x00b6 -> CYRILLIC CAPITAL LETTER HA + '\u0438' # 0x00b7 -> CYRILLIC SMALL LETTER I + '\u0418' # 0x00b8 -> CYRILLIC CAPITAL LETTER I + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u0439' # 0x00bd -> CYRILLIC SMALL LETTER SHORT I + '\u0419' # 0x00be -> CYRILLIC CAPITAL LETTER SHORT I + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u043a' # 0x00c6 -> CYRILLIC SMALL LETTER KA + '\u041a' # 0x00c7 -> CYRILLIC CAPITAL LETTER KA + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\u043b' # 0x00d0 -> CYRILLIC SMALL LETTER EL + '\u041b' # 0x00d1 -> CYRILLIC CAPITAL LETTER EL + '\u043c' # 0x00d2 -> CYRILLIC SMALL LETTER EM + '\u041c' # 0x00d3 -> CYRILLIC CAPITAL LETTER EM + '\u043d' # 0x00d4 -> CYRILLIC SMALL LETTER EN + '\u041d' # 0x00d5 -> CYRILLIC CAPITAL LETTER EN + '\u043e' # 0x00d6 -> CYRILLIC SMALL LETTER O + '\u041e' # 0x00d7 -> CYRILLIC CAPITAL LETTER O + '\u043f' # 0x00d8 -> CYRILLIC SMALL LETTER PE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u041f' # 0x00dd -> CYRILLIC CAPITAL LETTER PE + '\u044f' # 0x00de -> CYRILLIC SMALL LETTER YA + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u042f' # 0x00e0 -> CYRILLIC CAPITAL LETTER YA + '\u0440' # 0x00e1 -> CYRILLIC SMALL LETTER ER + '\u0420' # 0x00e2 -> CYRILLIC CAPITAL LETTER ER + '\u0441' # 0x00e3 -> CYRILLIC SMALL LETTER ES + '\u0421' # 0x00e4 -> CYRILLIC CAPITAL LETTER ES + '\u0442' # 0x00e5 -> CYRILLIC SMALL LETTER TE + '\u0422' # 0x00e6 -> CYRILLIC CAPITAL LETTER TE + '\u0443' # 0x00e7 -> CYRILLIC SMALL LETTER U + '\u0423' # 0x00e8 -> CYRILLIC CAPITAL LETTER U + '\u0436' # 0x00e9 -> CYRILLIC SMALL LETTER ZHE + '\u0416' # 0x00ea -> CYRILLIC CAPITAL LETTER ZHE + '\u0432' # 0x00eb -> CYRILLIC SMALL LETTER VE + '\u0412' # 0x00ec -> CYRILLIC CAPITAL LETTER VE + '\u044c' # 0x00ed -> CYRILLIC SMALL LETTER SOFT SIGN + '\u042c' # 0x00ee -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u2116' # 0x00ef -> NUMERO SIGN + '\xad' # 0x00f0 -> SOFT HYPHEN + '\u044b' # 0x00f1 -> CYRILLIC SMALL LETTER YERU + '\u042b' # 0x00f2 -> CYRILLIC CAPITAL LETTER YERU + '\u0437' # 0x00f3 -> CYRILLIC SMALL LETTER ZE + '\u0417' # 0x00f4 -> CYRILLIC CAPITAL LETTER ZE + '\u0448' # 0x00f5 -> CYRILLIC SMALL LETTER SHA + '\u0428' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHA + '\u044d' # 0x00f7 -> CYRILLIC SMALL LETTER E + '\u042d' # 0x00f8 -> CYRILLIC CAPITAL LETTER E + '\u0449' # 0x00f9 -> CYRILLIC SMALL LETTER SHCHA + '\u0429' # 0x00fa -> CYRILLIC CAPITAL LETTER SHCHA + '\u0447' # 0x00fb -> CYRILLIC SMALL LETTER CHE + '\u0427' # 0x00fc -> CYRILLIC CAPITAL LETTER CHE + '\xa7' # 0x00fd -> SECTION SIGN + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a7: 0x00fd, # SECTION SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x0401: 0x0085, # CYRILLIC CAPITAL LETTER IO + 0x0402: 0x0081, # CYRILLIC CAPITAL LETTER DJE + 0x0403: 0x0083, # CYRILLIC CAPITAL LETTER GJE + 0x0404: 0x0087, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0405: 0x0089, # CYRILLIC CAPITAL LETTER DZE + 0x0406: 0x008b, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0407: 0x008d, # CYRILLIC CAPITAL LETTER YI + 0x0408: 0x008f, # CYRILLIC CAPITAL LETTER JE + 0x0409: 0x0091, # CYRILLIC CAPITAL LETTER LJE + 0x040a: 0x0093, # CYRILLIC CAPITAL LETTER NJE + 0x040b: 0x0095, # CYRILLIC CAPITAL LETTER TSHE + 0x040c: 0x0097, # CYRILLIC CAPITAL LETTER KJE + 0x040e: 0x0099, # CYRILLIC CAPITAL LETTER SHORT U + 0x040f: 0x009b, # CYRILLIC CAPITAL LETTER DZHE + 0x0410: 0x00a1, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x00a3, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x00ec, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x00ad, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x00a7, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x00a9, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x00ea, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x00f4, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x00b8, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x00be, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x00c7, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x00d1, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x00d3, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x00d5, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x00d7, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x00dd, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x00e2, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x00e4, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x00e6, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x00e8, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x00ab, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x00b6, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x00a5, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x00fc, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x00f6, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x00fa, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009f, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x00f2, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x00ee, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x00f8, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009d, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x00e0, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a2, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00eb, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00ac, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a6, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a8, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00e9, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00f3, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00b7, # CYRILLIC SMALL LETTER I + 0x0439: 0x00bd, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00c6, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00d0, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00d2, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00d4, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00d6, # CYRILLIC SMALL LETTER O + 0x043f: 0x00d8, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e1, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e3, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e5, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e7, # CYRILLIC SMALL LETTER U + 0x0444: 0x00aa, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00b5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00a4, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00fb, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00f5, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00f9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x009e, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00f1, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ed, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00f7, # CYRILLIC SMALL LETTER E + 0x044e: 0x009c, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00de, # CYRILLIC SMALL LETTER YA + 0x0451: 0x0084, # CYRILLIC SMALL LETTER IO + 0x0452: 0x0080, # CYRILLIC SMALL LETTER DJE + 0x0453: 0x0082, # CYRILLIC SMALL LETTER GJE + 0x0454: 0x0086, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0455: 0x0088, # CYRILLIC SMALL LETTER DZE + 0x0456: 0x008a, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0457: 0x008c, # CYRILLIC SMALL LETTER YI + 0x0458: 0x008e, # CYRILLIC SMALL LETTER JE + 0x0459: 0x0090, # CYRILLIC SMALL LETTER LJE + 0x045a: 0x0092, # CYRILLIC SMALL LETTER NJE + 0x045b: 0x0094, # CYRILLIC SMALL LETTER TSHE + 0x045c: 0x0096, # CYRILLIC SMALL LETTER KJE + 0x045e: 0x0098, # CYRILLIC SMALL LETTER SHORT U + 0x045f: 0x009a, # CYRILLIC SMALL LETTER DZHE + 0x2116: 0x00ef, # NUMERO SIGN + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp856.py b/Lib/encodings/cp856.py new file mode 100644 index 0000000..cacbfb2 --- /dev/null +++ b/Lib/encodings/cp856.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp856 generated from 'MAPPINGS/VENDORS/MISC/CP856.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp856', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u05d0' # 0x80 -> HEBREW LETTER ALEF + '\u05d1' # 0x81 -> HEBREW LETTER BET + '\u05d2' # 0x82 -> HEBREW LETTER GIMEL + '\u05d3' # 0x83 -> HEBREW LETTER DALET + '\u05d4' # 0x84 -> HEBREW LETTER HE + '\u05d5' # 0x85 -> HEBREW LETTER VAV + '\u05d6' # 0x86 -> HEBREW LETTER ZAYIN + '\u05d7' # 0x87 -> HEBREW LETTER HET + '\u05d8' # 0x88 -> HEBREW LETTER TET + '\u05d9' # 0x89 -> HEBREW LETTER YOD + '\u05da' # 0x8A -> HEBREW LETTER FINAL KAF + '\u05db' # 0x8B -> HEBREW LETTER KAF + '\u05dc' # 0x8C -> HEBREW LETTER LAMED + '\u05dd' # 0x8D -> HEBREW LETTER FINAL MEM + '\u05de' # 0x8E -> HEBREW LETTER MEM + '\u05df' # 0x8F -> HEBREW LETTER FINAL NUN + '\u05e0' # 0x90 -> HEBREW LETTER NUN + '\u05e1' # 0x91 -> HEBREW LETTER SAMEKH + '\u05e2' # 0x92 -> HEBREW LETTER AYIN + '\u05e3' # 0x93 -> HEBREW LETTER FINAL PE + '\u05e4' # 0x94 -> HEBREW LETTER PE + '\u05e5' # 0x95 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0x96 -> HEBREW LETTER TSADI + '\u05e7' # 0x97 -> HEBREW LETTER QOF + '\u05e8' # 0x98 -> HEBREW LETTER RESH + '\u05e9' # 0x99 -> HEBREW LETTER SHIN + '\u05ea' # 0x9A -> HEBREW LETTER TAV + '\ufffe' # 0x9B -> UNDEFINED + '\xa3' # 0x9C -> POUND SIGN + '\ufffe' # 0x9D -> UNDEFINED + '\xd7' # 0x9E -> MULTIPLICATION SIGN + '\ufffe' # 0x9F -> UNDEFINED + '\ufffe' # 0xA0 -> UNDEFINED + '\ufffe' # 0xA1 -> UNDEFINED + '\ufffe' # 0xA2 -> UNDEFINED + '\ufffe' # 0xA3 -> UNDEFINED + '\ufffe' # 0xA4 -> UNDEFINED + '\ufffe' # 0xA5 -> UNDEFINED + '\ufffe' # 0xA6 -> UNDEFINED + '\ufffe' # 0xA7 -> UNDEFINED + '\ufffe' # 0xA8 -> UNDEFINED + '\xae' # 0xA9 -> REGISTERED SIGN + '\xac' # 0xAA -> NOT SIGN + '\xbd' # 0xAB -> VULGAR FRACTION ONE HALF + '\xbc' # 0xAC -> VULGAR FRACTION ONE QUARTER + '\ufffe' # 0xAD -> UNDEFINED + '\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0xB0 -> LIGHT SHADE + '\u2592' # 0xB1 -> MEDIUM SHADE + '\u2593' # 0xB2 -> DARK SHADE + '\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\ufffe' # 0xB5 -> UNDEFINED + '\ufffe' # 0xB6 -> UNDEFINED + '\ufffe' # 0xB7 -> UNDEFINED + '\xa9' # 0xB8 -> COPYRIGHT SIGN + '\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0xBD -> CENT SIGN + '\xa5' # 0xBE -> YEN SIGN + '\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\ufffe' # 0xC6 -> UNDEFINED + '\ufffe' # 0xC7 -> UNDEFINED + '\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0xCF -> CURRENCY SIGN + '\ufffe' # 0xD0 -> UNDEFINED + '\ufffe' # 0xD1 -> UNDEFINED + '\ufffe' # 0xD2 -> UNDEFINED + '\ufffe' # 0xD3 -> UNDEFINEDS + '\ufffe' # 0xD4 -> UNDEFINED + '\ufffe' # 0xD5 -> UNDEFINED + '\ufffe' # 0xD6 -> UNDEFINEDE + '\ufffe' # 0xD7 -> UNDEFINED + '\ufffe' # 0xD8 -> UNDEFINED + '\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0xDB -> FULL BLOCK + '\u2584' # 0xDC -> LOWER HALF BLOCK + '\xa6' # 0xDD -> BROKEN BAR + '\ufffe' # 0xDE -> UNDEFINED + '\u2580' # 0xDF -> UPPER HALF BLOCK + '\ufffe' # 0xE0 -> UNDEFINED + '\ufffe' # 0xE1 -> UNDEFINED + '\ufffe' # 0xE2 -> UNDEFINED + '\ufffe' # 0xE3 -> UNDEFINED + '\ufffe' # 0xE4 -> UNDEFINED + '\ufffe' # 0xE5 -> UNDEFINED + '\xb5' # 0xE6 -> MICRO SIGN + '\ufffe' # 0xE7 -> UNDEFINED + '\ufffe' # 0xE8 -> UNDEFINED + '\ufffe' # 0xE9 -> UNDEFINED + '\ufffe' # 0xEA -> UNDEFINED + '\ufffe' # 0xEB -> UNDEFINED + '\ufffe' # 0xEC -> UNDEFINED + '\ufffe' # 0xED -> UNDEFINED + '\xaf' # 0xEE -> MACRON + '\xb4' # 0xEF -> ACUTE ACCENT + '\xad' # 0xF0 -> SOFT HYPHEN + '\xb1' # 0xF1 -> PLUS-MINUS SIGN + '\u2017' # 0xF2 -> DOUBLE LOW LINE + '\xbe' # 0xF3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0xF4 -> PILCROW SIGN + '\xa7' # 0xF5 -> SECTION SIGN + '\xf7' # 0xF6 -> DIVISION SIGN + '\xb8' # 0xF7 -> CEDILLA + '\xb0' # 0xF8 -> DEGREE SIGN + '\xa8' # 0xF9 -> DIAERESIS + '\xb7' # 0xFA -> MIDDLE DOT + '\xb9' # 0xFB -> SUPERSCRIPT ONE + '\xb3' # 0xFC -> SUPERSCRIPT THREE + '\xb2' # 0xFD -> SUPERSCRIPT TWO + '\u25a0' # 0xFE -> BLACK SQUARE + '\xa0' # 0xFF -> NO-BREAK SPACE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp857.py b/Lib/encodings/cp857.py new file mode 100644 index 0000000..741b059 --- /dev/null +++ b/Lib/encodings/cp857.py @@ -0,0 +1,694 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP857.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp857', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x0131, # LATIN SMALL LETTER DOTLESS I + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x009f: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x011e, # LATIN CAPITAL LETTER G WITH BREVE + 0x00a7: 0x011f, # LATIN SMALL LETTER G WITH BREVE + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00d1: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: None, # UNDEFINED + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: None, # UNDEFINED + 0x00e8: 0x00d7, # MULTIPLICATION SIGN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ed: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: None, # UNDEFINED + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u0131' # 0x008d -> LATIN SMALL LETTER DOTLESS I + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\u0130' # 0x0098 -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\u015e' # 0x009e -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u015f' # 0x009f -> LATIN SMALL LETTER S WITH CEDILLA + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\u011e' # 0x00a6 -> LATIN CAPITAL LETTER G WITH BREVE + '\u011f' # 0x00a7 -> LATIN SMALL LETTER G WITH BREVE + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa9' # 0x00b8 -> COPYRIGHT SIGN + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0x00bd -> CENT SIGN + '\xa5' # 0x00be -> YEN SIGN + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\xba' # 0x00d0 -> MASCULINE ORDINAL INDICATOR + '\xaa' # 0x00d1 -> FEMININE ORDINAL INDICATOR + '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + '\ufffe' # 0x00d5 -> UNDEFINED + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\xa6' # 0x00dd -> BROKEN BAR + '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\ufffe' # 0x00e7 -> UNDEFINED + '\xd7' # 0x00e8 -> MULTIPLICATION SIGN + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + '\xec' # 0x00ec -> LATIN SMALL LETTER I WITH GRAVE + '\xff' # 0x00ed -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xaf' # 0x00ee -> MACRON + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\ufffe' # 0x00f2 -> UNDEFINED + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00d1, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00d0, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x00e8, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x00ed, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x011e: 0x00a6, # LATIN CAPITAL LETTER G WITH BREVE + 0x011f: 0x00a7, # LATIN SMALL LETTER G WITH BREVE + 0x0130: 0x0098, # LATIN CAPITAL LETTER I WITH DOT ABOVE + 0x0131: 0x008d, # LATIN SMALL LETTER DOTLESS I + 0x015e: 0x009e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x015f: 0x009f, # LATIN SMALL LETTER S WITH CEDILLA + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp858.py b/Lib/encodings/cp858.py new file mode 100644 index 0000000..7579f52 --- /dev/null +++ b/Lib/encodings/cp858.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec for CP858, modified from cp850. + +""" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp858', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH + 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: 0x20ac, # EURO SIGN + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN + 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2017, # DOUBLE LOW LINE + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa9' # 0x00b8 -> COPYRIGHT SIGN + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0x00bd -> CENT SIGN + '\xa5' # 0x00be -> YEN SIGN + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH + '\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH + '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + '\u20ac' # 0x00d5 -> EURO SIGN + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\xa6' # 0x00dd -> BROKEN BAR + '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN + '\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xaf' # 0x00ee -> MACRON + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2017' # 0x00f2 -> DOUBLE LOW LINE + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x20ac: 0x00d5, # EURO SIGN + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x2017: 0x00f2, # DOUBLE LOW LINE + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp860.py b/Lib/encodings/cp860.py new file mode 100644 index 0000000..65903e7 --- /dev/null +++ b/Lib/encodings/cp860.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP860.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp860', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x008c: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x008f: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x0092: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x0099: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0x0084 -> LATIN SMALL LETTER A WITH TILDE + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xc1' # 0x0086 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xca' # 0x0089 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xcd' # 0x008b -> LATIN CAPITAL LETTER I WITH ACUTE + '\xd4' # 0x008c -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc3' # 0x008e -> LATIN CAPITAL LETTER A WITH TILDE + '\xc2' # 0x008f -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xc0' # 0x0091 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc8' # 0x0092 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0x0094 -> LATIN SMALL LETTER O WITH TILDE + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xda' # 0x0096 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xcc' # 0x0098 -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd5' # 0x0099 -> LATIN CAPITAL LETTER O WITH TILDE + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE + '\u20a7' # 0x009e -> PESETA SIGN + '\xd3' # 0x009f -> LATIN CAPITAL LETTER O WITH ACUTE + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xd2' # 0x00a9 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x0091, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x0086, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x008f, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x008e, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x0092, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x0089, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cc: 0x0098, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x008b, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00a9, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x009f, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x008c, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x0099, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x0096, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x0084, # LATIN SMALL LETTER A WITH TILDE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x0094, # LATIN SMALL LETTER O WITH TILDE + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp861.py b/Lib/encodings/cp861.py new file mode 100644 index 0000000..860a05f --- /dev/null +++ b/Lib/encodings/cp861.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP861.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp861', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x008c: 0x00f0, # LATIN SMALL LETTER ETH + 0x008d: 0x00de, # LATIN CAPITAL LETTER THORN + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00fe, # LATIN SMALL LETTER THORN + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x0098: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00a5: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00a6: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00a7: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xd0' # 0x008b -> LATIN CAPITAL LETTER ETH + '\xf0' # 0x008c -> LATIN SMALL LETTER ETH + '\xde' # 0x008d -> LATIN CAPITAL LETTER THORN + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xfe' # 0x0095 -> LATIN SMALL LETTER THORN + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xdd' # 0x0097 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xfd' # 0x0098 -> LATIN SMALL LETTER Y WITH ACUTE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xc1' # 0x00a4 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcd' # 0x00a5 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xd3' # 0x00a6 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xda' # 0x00a7 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a3: 0x009c, # POUND SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c1: 0x00a4, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00cd: 0x00a5, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d0: 0x008b, # LATIN CAPITAL LETTER ETH + 0x00d3: 0x00a6, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00da: 0x00a7, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x0097, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x008d, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f0: 0x008c, # LATIN SMALL LETTER ETH + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x0098, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x0095, # LATIN SMALL LETTER THORN + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp862.py b/Lib/encodings/cp862.py new file mode 100644 index 0000000..3df22f9 --- /dev/null +++ b/Lib/encodings/cp862.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP862.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp862', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x05d0, # HEBREW LETTER ALEF + 0x0081: 0x05d1, # HEBREW LETTER BET + 0x0082: 0x05d2, # HEBREW LETTER GIMEL + 0x0083: 0x05d3, # HEBREW LETTER DALET + 0x0084: 0x05d4, # HEBREW LETTER HE + 0x0085: 0x05d5, # HEBREW LETTER VAV + 0x0086: 0x05d6, # HEBREW LETTER ZAYIN + 0x0087: 0x05d7, # HEBREW LETTER HET + 0x0088: 0x05d8, # HEBREW LETTER TET + 0x0089: 0x05d9, # HEBREW LETTER YOD + 0x008a: 0x05da, # HEBREW LETTER FINAL KAF + 0x008b: 0x05db, # HEBREW LETTER KAF + 0x008c: 0x05dc, # HEBREW LETTER LAMED + 0x008d: 0x05dd, # HEBREW LETTER FINAL MEM + 0x008e: 0x05de, # HEBREW LETTER MEM + 0x008f: 0x05df, # HEBREW LETTER FINAL NUN + 0x0090: 0x05e0, # HEBREW LETTER NUN + 0x0091: 0x05e1, # HEBREW LETTER SAMEKH + 0x0092: 0x05e2, # HEBREW LETTER AYIN + 0x0093: 0x05e3, # HEBREW LETTER FINAL PE + 0x0094: 0x05e4, # HEBREW LETTER PE + 0x0095: 0x05e5, # HEBREW LETTER FINAL TSADI + 0x0096: 0x05e6, # HEBREW LETTER TSADI + 0x0097: 0x05e7, # HEBREW LETTER QOF + 0x0098: 0x05e8, # HEBREW LETTER RESH + 0x0099: 0x05e9, # HEBREW LETTER SHIN + 0x009a: 0x05ea, # HEBREW LETTER TAV + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00a5, # YEN SIGN + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u05d0' # 0x0080 -> HEBREW LETTER ALEF + '\u05d1' # 0x0081 -> HEBREW LETTER BET + '\u05d2' # 0x0082 -> HEBREW LETTER GIMEL + '\u05d3' # 0x0083 -> HEBREW LETTER DALET + '\u05d4' # 0x0084 -> HEBREW LETTER HE + '\u05d5' # 0x0085 -> HEBREW LETTER VAV + '\u05d6' # 0x0086 -> HEBREW LETTER ZAYIN + '\u05d7' # 0x0087 -> HEBREW LETTER HET + '\u05d8' # 0x0088 -> HEBREW LETTER TET + '\u05d9' # 0x0089 -> HEBREW LETTER YOD + '\u05da' # 0x008a -> HEBREW LETTER FINAL KAF + '\u05db' # 0x008b -> HEBREW LETTER KAF + '\u05dc' # 0x008c -> HEBREW LETTER LAMED + '\u05dd' # 0x008d -> HEBREW LETTER FINAL MEM + '\u05de' # 0x008e -> HEBREW LETTER MEM + '\u05df' # 0x008f -> HEBREW LETTER FINAL NUN + '\u05e0' # 0x0090 -> HEBREW LETTER NUN + '\u05e1' # 0x0091 -> HEBREW LETTER SAMEKH + '\u05e2' # 0x0092 -> HEBREW LETTER AYIN + '\u05e3' # 0x0093 -> HEBREW LETTER FINAL PE + '\u05e4' # 0x0094 -> HEBREW LETTER PE + '\u05e5' # 0x0095 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0x0096 -> HEBREW LETTER TSADI + '\u05e7' # 0x0097 -> HEBREW LETTER QOF + '\u05e8' # 0x0098 -> HEBREW LETTER RESH + '\u05e9' # 0x0099 -> HEBREW LETTER SHIN + '\u05ea' # 0x009a -> HEBREW LETTER TAV + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xa5' # 0x009d -> YEN SIGN + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a5: 0x009d, # YEN SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x05d0: 0x0080, # HEBREW LETTER ALEF + 0x05d1: 0x0081, # HEBREW LETTER BET + 0x05d2: 0x0082, # HEBREW LETTER GIMEL + 0x05d3: 0x0083, # HEBREW LETTER DALET + 0x05d4: 0x0084, # HEBREW LETTER HE + 0x05d5: 0x0085, # HEBREW LETTER VAV + 0x05d6: 0x0086, # HEBREW LETTER ZAYIN + 0x05d7: 0x0087, # HEBREW LETTER HET + 0x05d8: 0x0088, # HEBREW LETTER TET + 0x05d9: 0x0089, # HEBREW LETTER YOD + 0x05da: 0x008a, # HEBREW LETTER FINAL KAF + 0x05db: 0x008b, # HEBREW LETTER KAF + 0x05dc: 0x008c, # HEBREW LETTER LAMED + 0x05dd: 0x008d, # HEBREW LETTER FINAL MEM + 0x05de: 0x008e, # HEBREW LETTER MEM + 0x05df: 0x008f, # HEBREW LETTER FINAL NUN + 0x05e0: 0x0090, # HEBREW LETTER NUN + 0x05e1: 0x0091, # HEBREW LETTER SAMEKH + 0x05e2: 0x0092, # HEBREW LETTER AYIN + 0x05e3: 0x0093, # HEBREW LETTER FINAL PE + 0x05e4: 0x0094, # HEBREW LETTER PE + 0x05e5: 0x0095, # HEBREW LETTER FINAL TSADI + 0x05e6: 0x0096, # HEBREW LETTER TSADI + 0x05e7: 0x0097, # HEBREW LETTER QOF + 0x05e8: 0x0098, # HEBREW LETTER RESH + 0x05e9: 0x0099, # HEBREW LETTER SHIN + 0x05ea: 0x009a, # HEBREW LETTER TAV + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp863.py b/Lib/encodings/cp863.py new file mode 100644 index 0000000..764180b --- /dev/null +++ b/Lib/encodings/cp863.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP863.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp863', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00b6, # PILCROW SIGN + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x2017, # DOUBLE LOW LINE + 0x008e: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x008f: 0x00a7, # SECTION SIGN + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x0092: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x0095: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00a4, # CURRENCY SIGN + 0x0099: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x009e: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00a6, # BROKEN BAR + 0x00a1: 0x00b4, # ACUTE ACCENT + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00a8, # DIAERESIS + 0x00a5: 0x00b8, # CEDILLA + 0x00a6: 0x00b3, # SUPERSCRIPT THREE + 0x00a7: 0x00af, # MACRON + 0x00a8: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xc2' # 0x0084 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xb6' # 0x0086 -> PILCROW SIGN + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u2017' # 0x008d -> DOUBLE LOW LINE + '\xc0' # 0x008e -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa7' # 0x008f -> SECTION SIGN + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xc8' # 0x0091 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xca' # 0x0092 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xcb' # 0x0094 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcf' # 0x0095 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xa4' # 0x0098 -> CURRENCY SIGN + '\xd4' # 0x0099 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE + '\xdb' # 0x009e -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xa6' # 0x00a0 -> BROKEN BAR + '\xb4' # 0x00a1 -> ACUTE ACCENT + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xa8' # 0x00a4 -> DIAERESIS + '\xb8' # 0x00a5 -> CEDILLA + '\xb3' # 0x00a6 -> SUPERSCRIPT THREE + '\xaf' # 0x00a7 -> MACRON + '\xce' # 0x00a8 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xbe' # 0x00ad -> VULGAR FRACTION THREE QUARTERS + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x0098, # CURRENCY SIGN + 0x00a6: 0x00a0, # BROKEN BAR + 0x00a7: 0x008f, # SECTION SIGN + 0x00a8: 0x00a4, # DIAERESIS + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00af: 0x00a7, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00a6, # SUPERSCRIPT THREE + 0x00b4: 0x00a1, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x0086, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00a5, # CEDILLA + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00ad, # VULGAR FRACTION THREE QUARTERS + 0x00c0: 0x008e, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c2: 0x0084, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x0091, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x0092, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x0094, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00ce: 0x00a8, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x0095, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d4: 0x0099, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00db: 0x009e, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x2017: 0x008d, # DOUBLE LOW LINE + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp864.py b/Lib/encodings/cp864.py new file mode 100644 index 0000000..53df482 --- /dev/null +++ b/Lib/encodings/cp864.py @@ -0,0 +1,690 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP864.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp864', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0025: 0x066a, # ARABIC PERCENT SIGN + 0x0080: 0x00b0, # DEGREE SIGN + 0x0081: 0x00b7, # MIDDLE DOT + 0x0082: 0x2219, # BULLET OPERATOR + 0x0083: 0x221a, # SQUARE ROOT + 0x0084: 0x2592, # MEDIUM SHADE + 0x0085: 0x2500, # FORMS LIGHT HORIZONTAL + 0x0086: 0x2502, # FORMS LIGHT VERTICAL + 0x0087: 0x253c, # FORMS LIGHT VERTICAL AND HORIZONTAL + 0x0088: 0x2524, # FORMS LIGHT VERTICAL AND LEFT + 0x0089: 0x252c, # FORMS LIGHT DOWN AND HORIZONTAL + 0x008a: 0x251c, # FORMS LIGHT VERTICAL AND RIGHT + 0x008b: 0x2534, # FORMS LIGHT UP AND HORIZONTAL + 0x008c: 0x2510, # FORMS LIGHT DOWN AND LEFT + 0x008d: 0x250c, # FORMS LIGHT DOWN AND RIGHT + 0x008e: 0x2514, # FORMS LIGHT UP AND RIGHT + 0x008f: 0x2518, # FORMS LIGHT UP AND LEFT + 0x0090: 0x03b2, # GREEK SMALL BETA + 0x0091: 0x221e, # INFINITY + 0x0092: 0x03c6, # GREEK SMALL PHI + 0x0093: 0x00b1, # PLUS-OR-MINUS SIGN + 0x0094: 0x00bd, # FRACTION 1/2 + 0x0095: 0x00bc, # FRACTION 1/4 + 0x0096: 0x2248, # ALMOST EQUAL TO + 0x0097: 0x00ab, # LEFT POINTING GUILLEMET + 0x0098: 0x00bb, # RIGHT POINTING GUILLEMET + 0x0099: 0xfef7, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + 0x009a: 0xfef8, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + 0x009b: None, # UNDEFINED + 0x009c: None, # UNDEFINED + 0x009d: 0xfefb, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + 0x009e: 0xfefc, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM + 0x009f: None, # UNDEFINED + 0x00a1: 0x00ad, # SOFT HYPHEN + 0x00a2: 0xfe82, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + 0x00a5: 0xfe84, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + 0x00a6: None, # UNDEFINED + 0x00a7: None, # UNDEFINED + 0x00a8: 0xfe8e, # ARABIC LETTER ALEF FINAL FORM + 0x00a9: 0xfe8f, # ARABIC LETTER BEH ISOLATED FORM + 0x00aa: 0xfe95, # ARABIC LETTER TEH ISOLATED FORM + 0x00ab: 0xfe99, # ARABIC LETTER THEH ISOLATED FORM + 0x00ac: 0x060c, # ARABIC COMMA + 0x00ad: 0xfe9d, # ARABIC LETTER JEEM ISOLATED FORM + 0x00ae: 0xfea1, # ARABIC LETTER HAH ISOLATED FORM + 0x00af: 0xfea5, # ARABIC LETTER KHAH ISOLATED FORM + 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO + 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE + 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO + 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE + 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR + 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE + 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX + 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN + 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT + 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE + 0x00ba: 0xfed1, # ARABIC LETTER FEH ISOLATED FORM + 0x00bb: 0x061b, # ARABIC SEMICOLON + 0x00bc: 0xfeb1, # ARABIC LETTER SEEN ISOLATED FORM + 0x00bd: 0xfeb5, # ARABIC LETTER SHEEN ISOLATED FORM + 0x00be: 0xfeb9, # ARABIC LETTER SAD ISOLATED FORM + 0x00bf: 0x061f, # ARABIC QUESTION MARK + 0x00c0: 0x00a2, # CENT SIGN + 0x00c1: 0xfe80, # ARABIC LETTER HAMZA ISOLATED FORM + 0x00c2: 0xfe81, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + 0x00c3: 0xfe83, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + 0x00c4: 0xfe85, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + 0x00c5: 0xfeca, # ARABIC LETTER AIN FINAL FORM + 0x00c6: 0xfe8b, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + 0x00c7: 0xfe8d, # ARABIC LETTER ALEF ISOLATED FORM + 0x00c8: 0xfe91, # ARABIC LETTER BEH INITIAL FORM + 0x00c9: 0xfe93, # ARABIC LETTER TEH MARBUTA ISOLATED FORM + 0x00ca: 0xfe97, # ARABIC LETTER TEH INITIAL FORM + 0x00cb: 0xfe9b, # ARABIC LETTER THEH INITIAL FORM + 0x00cc: 0xfe9f, # ARABIC LETTER JEEM INITIAL FORM + 0x00cd: 0xfea3, # ARABIC LETTER HAH INITIAL FORM + 0x00ce: 0xfea7, # ARABIC LETTER KHAH INITIAL FORM + 0x00cf: 0xfea9, # ARABIC LETTER DAL ISOLATED FORM + 0x00d0: 0xfeab, # ARABIC LETTER THAL ISOLATED FORM + 0x00d1: 0xfead, # ARABIC LETTER REH ISOLATED FORM + 0x00d2: 0xfeaf, # ARABIC LETTER ZAIN ISOLATED FORM + 0x00d3: 0xfeb3, # ARABIC LETTER SEEN INITIAL FORM + 0x00d4: 0xfeb7, # ARABIC LETTER SHEEN INITIAL FORM + 0x00d5: 0xfebb, # ARABIC LETTER SAD INITIAL FORM + 0x00d6: 0xfebf, # ARABIC LETTER DAD INITIAL FORM + 0x00d7: 0xfec1, # ARABIC LETTER TAH ISOLATED FORM + 0x00d8: 0xfec5, # ARABIC LETTER ZAH ISOLATED FORM + 0x00d9: 0xfecb, # ARABIC LETTER AIN INITIAL FORM + 0x00da: 0xfecf, # ARABIC LETTER GHAIN INITIAL FORM + 0x00db: 0x00a6, # BROKEN VERTICAL BAR + 0x00dc: 0x00ac, # NOT SIGN + 0x00dd: 0x00f7, # DIVISION SIGN + 0x00de: 0x00d7, # MULTIPLICATION SIGN + 0x00df: 0xfec9, # ARABIC LETTER AIN ISOLATED FORM + 0x00e0: 0x0640, # ARABIC TATWEEL + 0x00e1: 0xfed3, # ARABIC LETTER FEH INITIAL FORM + 0x00e2: 0xfed7, # ARABIC LETTER QAF INITIAL FORM + 0x00e3: 0xfedb, # ARABIC LETTER KAF INITIAL FORM + 0x00e4: 0xfedf, # ARABIC LETTER LAM INITIAL FORM + 0x00e5: 0xfee3, # ARABIC LETTER MEEM INITIAL FORM + 0x00e6: 0xfee7, # ARABIC LETTER NOON INITIAL FORM + 0x00e7: 0xfeeb, # ARABIC LETTER HEH INITIAL FORM + 0x00e8: 0xfeed, # ARABIC LETTER WAW ISOLATED FORM + 0x00e9: 0xfeef, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM + 0x00ea: 0xfef3, # ARABIC LETTER YEH INITIAL FORM + 0x00eb: 0xfebd, # ARABIC LETTER DAD ISOLATED FORM + 0x00ec: 0xfecc, # ARABIC LETTER AIN MEDIAL FORM + 0x00ed: 0xfece, # ARABIC LETTER GHAIN FINAL FORM + 0x00ee: 0xfecd, # ARABIC LETTER GHAIN ISOLATED FORM + 0x00ef: 0xfee1, # ARABIC LETTER MEEM ISOLATED FORM + 0x00f0: 0xfe7d, # ARABIC SHADDA MEDIAL FORM + 0x00f1: 0x0651, # ARABIC SHADDAH + 0x00f2: 0xfee5, # ARABIC LETTER NOON ISOLATED FORM + 0x00f3: 0xfee9, # ARABIC LETTER HEH ISOLATED FORM + 0x00f4: 0xfeec, # ARABIC LETTER HEH MEDIAL FORM + 0x00f5: 0xfef0, # ARABIC LETTER ALEF MAKSURA FINAL FORM + 0x00f6: 0xfef2, # ARABIC LETTER YEH FINAL FORM + 0x00f7: 0xfed0, # ARABIC LETTER GHAIN MEDIAL FORM + 0x00f8: 0xfed5, # ARABIC LETTER QAF ISOLATED FORM + 0x00f9: 0xfef5, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + 0x00fa: 0xfef6, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + 0x00fb: 0xfedd, # ARABIC LETTER LAM ISOLATED FORM + 0x00fc: 0xfed9, # ARABIC LETTER KAF ISOLATED FORM + 0x00fd: 0xfef1, # ARABIC LETTER YEH ISOLATED FORM + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: None, # UNDEFINED +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '\u066a' # 0x0025 -> ARABIC PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xb0' # 0x0080 -> DEGREE SIGN + '\xb7' # 0x0081 -> MIDDLE DOT + '\u2219' # 0x0082 -> BULLET OPERATOR + '\u221a' # 0x0083 -> SQUARE ROOT + '\u2592' # 0x0084 -> MEDIUM SHADE + '\u2500' # 0x0085 -> FORMS LIGHT HORIZONTAL + '\u2502' # 0x0086 -> FORMS LIGHT VERTICAL + '\u253c' # 0x0087 -> FORMS LIGHT VERTICAL AND HORIZONTAL + '\u2524' # 0x0088 -> FORMS LIGHT VERTICAL AND LEFT + '\u252c' # 0x0089 -> FORMS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x008a -> FORMS LIGHT VERTICAL AND RIGHT + '\u2534' # 0x008b -> FORMS LIGHT UP AND HORIZONTAL + '\u2510' # 0x008c -> FORMS LIGHT DOWN AND LEFT + '\u250c' # 0x008d -> FORMS LIGHT DOWN AND RIGHT + '\u2514' # 0x008e -> FORMS LIGHT UP AND RIGHT + '\u2518' # 0x008f -> FORMS LIGHT UP AND LEFT + '\u03b2' # 0x0090 -> GREEK SMALL BETA + '\u221e' # 0x0091 -> INFINITY + '\u03c6' # 0x0092 -> GREEK SMALL PHI + '\xb1' # 0x0093 -> PLUS-OR-MINUS SIGN + '\xbd' # 0x0094 -> FRACTION 1/2 + '\xbc' # 0x0095 -> FRACTION 1/4 + '\u2248' # 0x0096 -> ALMOST EQUAL TO + '\xab' # 0x0097 -> LEFT POINTING GUILLEMET + '\xbb' # 0x0098 -> RIGHT POINTING GUILLEMET + '\ufef7' # 0x0099 -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + '\ufef8' # 0x009a -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + '\ufffe' # 0x009b -> UNDEFINED + '\ufffe' # 0x009c -> UNDEFINED + '\ufefb' # 0x009d -> ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + '\ufefc' # 0x009e -> ARABIC LIGATURE LAM WITH ALEF FINAL FORM + '\ufffe' # 0x009f -> UNDEFINED + '\xa0' # 0x00a0 -> NON-BREAKING SPACE + '\xad' # 0x00a1 -> SOFT HYPHEN + '\ufe82' # 0x00a2 -> ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + '\xa3' # 0x00a3 -> POUND SIGN + '\xa4' # 0x00a4 -> CURRENCY SIGN + '\ufe84' # 0x00a5 -> ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + '\ufffe' # 0x00a6 -> UNDEFINED + '\ufffe' # 0x00a7 -> UNDEFINED + '\ufe8e' # 0x00a8 -> ARABIC LETTER ALEF FINAL FORM + '\ufe8f' # 0x00a9 -> ARABIC LETTER BEH ISOLATED FORM + '\ufe95' # 0x00aa -> ARABIC LETTER TEH ISOLATED FORM + '\ufe99' # 0x00ab -> ARABIC LETTER THEH ISOLATED FORM + '\u060c' # 0x00ac -> ARABIC COMMA + '\ufe9d' # 0x00ad -> ARABIC LETTER JEEM ISOLATED FORM + '\ufea1' # 0x00ae -> ARABIC LETTER HAH ISOLATED FORM + '\ufea5' # 0x00af -> ARABIC LETTER KHAH ISOLATED FORM + '\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO + '\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE + '\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO + '\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE + '\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR + '\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE + '\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX + '\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN + '\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT + '\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE + '\ufed1' # 0x00ba -> ARABIC LETTER FEH ISOLATED FORM + '\u061b' # 0x00bb -> ARABIC SEMICOLON + '\ufeb1' # 0x00bc -> ARABIC LETTER SEEN ISOLATED FORM + '\ufeb5' # 0x00bd -> ARABIC LETTER SHEEN ISOLATED FORM + '\ufeb9' # 0x00be -> ARABIC LETTER SAD ISOLATED FORM + '\u061f' # 0x00bf -> ARABIC QUESTION MARK + '\xa2' # 0x00c0 -> CENT SIGN + '\ufe80' # 0x00c1 -> ARABIC LETTER HAMZA ISOLATED FORM + '\ufe81' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + '\ufe83' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + '\ufe85' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + '\ufeca' # 0x00c5 -> ARABIC LETTER AIN FINAL FORM + '\ufe8b' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + '\ufe8d' # 0x00c7 -> ARABIC LETTER ALEF ISOLATED FORM + '\ufe91' # 0x00c8 -> ARABIC LETTER BEH INITIAL FORM + '\ufe93' # 0x00c9 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM + '\ufe97' # 0x00ca -> ARABIC LETTER TEH INITIAL FORM + '\ufe9b' # 0x00cb -> ARABIC LETTER THEH INITIAL FORM + '\ufe9f' # 0x00cc -> ARABIC LETTER JEEM INITIAL FORM + '\ufea3' # 0x00cd -> ARABIC LETTER HAH INITIAL FORM + '\ufea7' # 0x00ce -> ARABIC LETTER KHAH INITIAL FORM + '\ufea9' # 0x00cf -> ARABIC LETTER DAL ISOLATED FORM + '\ufeab' # 0x00d0 -> ARABIC LETTER THAL ISOLATED FORM + '\ufead' # 0x00d1 -> ARABIC LETTER REH ISOLATED FORM + '\ufeaf' # 0x00d2 -> ARABIC LETTER ZAIN ISOLATED FORM + '\ufeb3' # 0x00d3 -> ARABIC LETTER SEEN INITIAL FORM + '\ufeb7' # 0x00d4 -> ARABIC LETTER SHEEN INITIAL FORM + '\ufebb' # 0x00d5 -> ARABIC LETTER SAD INITIAL FORM + '\ufebf' # 0x00d6 -> ARABIC LETTER DAD INITIAL FORM + '\ufec1' # 0x00d7 -> ARABIC LETTER TAH ISOLATED FORM + '\ufec5' # 0x00d8 -> ARABIC LETTER ZAH ISOLATED FORM + '\ufecb' # 0x00d9 -> ARABIC LETTER AIN INITIAL FORM + '\ufecf' # 0x00da -> ARABIC LETTER GHAIN INITIAL FORM + '\xa6' # 0x00db -> BROKEN VERTICAL BAR + '\xac' # 0x00dc -> NOT SIGN + '\xf7' # 0x00dd -> DIVISION SIGN + '\xd7' # 0x00de -> MULTIPLICATION SIGN + '\ufec9' # 0x00df -> ARABIC LETTER AIN ISOLATED FORM + '\u0640' # 0x00e0 -> ARABIC TATWEEL + '\ufed3' # 0x00e1 -> ARABIC LETTER FEH INITIAL FORM + '\ufed7' # 0x00e2 -> ARABIC LETTER QAF INITIAL FORM + '\ufedb' # 0x00e3 -> ARABIC LETTER KAF INITIAL FORM + '\ufedf' # 0x00e4 -> ARABIC LETTER LAM INITIAL FORM + '\ufee3' # 0x00e5 -> ARABIC LETTER MEEM INITIAL FORM + '\ufee7' # 0x00e6 -> ARABIC LETTER NOON INITIAL FORM + '\ufeeb' # 0x00e7 -> ARABIC LETTER HEH INITIAL FORM + '\ufeed' # 0x00e8 -> ARABIC LETTER WAW ISOLATED FORM + '\ufeef' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA ISOLATED FORM + '\ufef3' # 0x00ea -> ARABIC LETTER YEH INITIAL FORM + '\ufebd' # 0x00eb -> ARABIC LETTER DAD ISOLATED FORM + '\ufecc' # 0x00ec -> ARABIC LETTER AIN MEDIAL FORM + '\ufece' # 0x00ed -> ARABIC LETTER GHAIN FINAL FORM + '\ufecd' # 0x00ee -> ARABIC LETTER GHAIN ISOLATED FORM + '\ufee1' # 0x00ef -> ARABIC LETTER MEEM ISOLATED FORM + '\ufe7d' # 0x00f0 -> ARABIC SHADDA MEDIAL FORM + '\u0651' # 0x00f1 -> ARABIC SHADDAH + '\ufee5' # 0x00f2 -> ARABIC LETTER NOON ISOLATED FORM + '\ufee9' # 0x00f3 -> ARABIC LETTER HEH ISOLATED FORM + '\ufeec' # 0x00f4 -> ARABIC LETTER HEH MEDIAL FORM + '\ufef0' # 0x00f5 -> ARABIC LETTER ALEF MAKSURA FINAL FORM + '\ufef2' # 0x00f6 -> ARABIC LETTER YEH FINAL FORM + '\ufed0' # 0x00f7 -> ARABIC LETTER GHAIN MEDIAL FORM + '\ufed5' # 0x00f8 -> ARABIC LETTER QAF ISOLATED FORM + '\ufef5' # 0x00f9 -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + '\ufef6' # 0x00fa -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + '\ufedd' # 0x00fb -> ARABIC LETTER LAM ISOLATED FORM + '\ufed9' # 0x00fc -> ARABIC LETTER KAF ISOLATED FORM + '\ufef1' # 0x00fd -> ARABIC LETTER YEH ISOLATED FORM + '\u25a0' # 0x00fe -> BLACK SQUARE + '\ufffe' # 0x00ff -> UNDEFINED +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00a0, # NON-BREAKING SPACE + 0x00a2: 0x00c0, # CENT SIGN + 0x00a3: 0x00a3, # POUND SIGN + 0x00a4: 0x00a4, # CURRENCY SIGN + 0x00a6: 0x00db, # BROKEN VERTICAL BAR + 0x00ab: 0x0097, # LEFT POINTING GUILLEMET + 0x00ac: 0x00dc, # NOT SIGN + 0x00ad: 0x00a1, # SOFT HYPHEN + 0x00b0: 0x0080, # DEGREE SIGN + 0x00b1: 0x0093, # PLUS-OR-MINUS SIGN + 0x00b7: 0x0081, # MIDDLE DOT + 0x00bb: 0x0098, # RIGHT POINTING GUILLEMET + 0x00bc: 0x0095, # FRACTION 1/4 + 0x00bd: 0x0094, # FRACTION 1/2 + 0x00d7: 0x00de, # MULTIPLICATION SIGN + 0x00f7: 0x00dd, # DIVISION SIGN + 0x03b2: 0x0090, # GREEK SMALL BETA + 0x03c6: 0x0092, # GREEK SMALL PHI + 0x060c: 0x00ac, # ARABIC COMMA + 0x061b: 0x00bb, # ARABIC SEMICOLON + 0x061f: 0x00bf, # ARABIC QUESTION MARK + 0x0640: 0x00e0, # ARABIC TATWEEL + 0x0651: 0x00f1, # ARABIC SHADDAH + 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO + 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE + 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO + 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE + 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR + 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE + 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX + 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN + 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT + 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE + 0x066a: 0x0025, # ARABIC PERCENT SIGN + 0x2219: 0x0082, # BULLET OPERATOR + 0x221a: 0x0083, # SQUARE ROOT + 0x221e: 0x0091, # INFINITY + 0x2248: 0x0096, # ALMOST EQUAL TO + 0x2500: 0x0085, # FORMS LIGHT HORIZONTAL + 0x2502: 0x0086, # FORMS LIGHT VERTICAL + 0x250c: 0x008d, # FORMS LIGHT DOWN AND RIGHT + 0x2510: 0x008c, # FORMS LIGHT DOWN AND LEFT + 0x2514: 0x008e, # FORMS LIGHT UP AND RIGHT + 0x2518: 0x008f, # FORMS LIGHT UP AND LEFT + 0x251c: 0x008a, # FORMS LIGHT VERTICAL AND RIGHT + 0x2524: 0x0088, # FORMS LIGHT VERTICAL AND LEFT + 0x252c: 0x0089, # FORMS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x008b, # FORMS LIGHT UP AND HORIZONTAL + 0x253c: 0x0087, # FORMS LIGHT VERTICAL AND HORIZONTAL + 0x2592: 0x0084, # MEDIUM SHADE + 0x25a0: 0x00fe, # BLACK SQUARE + 0xfe7d: 0x00f0, # ARABIC SHADDA MEDIAL FORM + 0xfe80: 0x00c1, # ARABIC LETTER HAMZA ISOLATED FORM + 0xfe81: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + 0xfe82: 0x00a2, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + 0xfe83: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + 0xfe84: 0x00a5, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + 0xfe85: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + 0xfe8b: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + 0xfe8d: 0x00c7, # ARABIC LETTER ALEF ISOLATED FORM + 0xfe8e: 0x00a8, # ARABIC LETTER ALEF FINAL FORM + 0xfe8f: 0x00a9, # ARABIC LETTER BEH ISOLATED FORM + 0xfe91: 0x00c8, # ARABIC LETTER BEH INITIAL FORM + 0xfe93: 0x00c9, # ARABIC LETTER TEH MARBUTA ISOLATED FORM + 0xfe95: 0x00aa, # ARABIC LETTER TEH ISOLATED FORM + 0xfe97: 0x00ca, # ARABIC LETTER TEH INITIAL FORM + 0xfe99: 0x00ab, # ARABIC LETTER THEH ISOLATED FORM + 0xfe9b: 0x00cb, # ARABIC LETTER THEH INITIAL FORM + 0xfe9d: 0x00ad, # ARABIC LETTER JEEM ISOLATED FORM + 0xfe9f: 0x00cc, # ARABIC LETTER JEEM INITIAL FORM + 0xfea1: 0x00ae, # ARABIC LETTER HAH ISOLATED FORM + 0xfea3: 0x00cd, # ARABIC LETTER HAH INITIAL FORM + 0xfea5: 0x00af, # ARABIC LETTER KHAH ISOLATED FORM + 0xfea7: 0x00ce, # ARABIC LETTER KHAH INITIAL FORM + 0xfea9: 0x00cf, # ARABIC LETTER DAL ISOLATED FORM + 0xfeab: 0x00d0, # ARABIC LETTER THAL ISOLATED FORM + 0xfead: 0x00d1, # ARABIC LETTER REH ISOLATED FORM + 0xfeaf: 0x00d2, # ARABIC LETTER ZAIN ISOLATED FORM + 0xfeb1: 0x00bc, # ARABIC LETTER SEEN ISOLATED FORM + 0xfeb3: 0x00d3, # ARABIC LETTER SEEN INITIAL FORM + 0xfeb5: 0x00bd, # ARABIC LETTER SHEEN ISOLATED FORM + 0xfeb7: 0x00d4, # ARABIC LETTER SHEEN INITIAL FORM + 0xfeb9: 0x00be, # ARABIC LETTER SAD ISOLATED FORM + 0xfebb: 0x00d5, # ARABIC LETTER SAD INITIAL FORM + 0xfebd: 0x00eb, # ARABIC LETTER DAD ISOLATED FORM + 0xfebf: 0x00d6, # ARABIC LETTER DAD INITIAL FORM + 0xfec1: 0x00d7, # ARABIC LETTER TAH ISOLATED FORM + 0xfec5: 0x00d8, # ARABIC LETTER ZAH ISOLATED FORM + 0xfec9: 0x00df, # ARABIC LETTER AIN ISOLATED FORM + 0xfeca: 0x00c5, # ARABIC LETTER AIN FINAL FORM + 0xfecb: 0x00d9, # ARABIC LETTER AIN INITIAL FORM + 0xfecc: 0x00ec, # ARABIC LETTER AIN MEDIAL FORM + 0xfecd: 0x00ee, # ARABIC LETTER GHAIN ISOLATED FORM + 0xfece: 0x00ed, # ARABIC LETTER GHAIN FINAL FORM + 0xfecf: 0x00da, # ARABIC LETTER GHAIN INITIAL FORM + 0xfed0: 0x00f7, # ARABIC LETTER GHAIN MEDIAL FORM + 0xfed1: 0x00ba, # ARABIC LETTER FEH ISOLATED FORM + 0xfed3: 0x00e1, # ARABIC LETTER FEH INITIAL FORM + 0xfed5: 0x00f8, # ARABIC LETTER QAF ISOLATED FORM + 0xfed7: 0x00e2, # ARABIC LETTER QAF INITIAL FORM + 0xfed9: 0x00fc, # ARABIC LETTER KAF ISOLATED FORM + 0xfedb: 0x00e3, # ARABIC LETTER KAF INITIAL FORM + 0xfedd: 0x00fb, # ARABIC LETTER LAM ISOLATED FORM + 0xfedf: 0x00e4, # ARABIC LETTER LAM INITIAL FORM + 0xfee1: 0x00ef, # ARABIC LETTER MEEM ISOLATED FORM + 0xfee3: 0x00e5, # ARABIC LETTER MEEM INITIAL FORM + 0xfee5: 0x00f2, # ARABIC LETTER NOON ISOLATED FORM + 0xfee7: 0x00e6, # ARABIC LETTER NOON INITIAL FORM + 0xfee9: 0x00f3, # ARABIC LETTER HEH ISOLATED FORM + 0xfeeb: 0x00e7, # ARABIC LETTER HEH INITIAL FORM + 0xfeec: 0x00f4, # ARABIC LETTER HEH MEDIAL FORM + 0xfeed: 0x00e8, # ARABIC LETTER WAW ISOLATED FORM + 0xfeef: 0x00e9, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM + 0xfef0: 0x00f5, # ARABIC LETTER ALEF MAKSURA FINAL FORM + 0xfef1: 0x00fd, # ARABIC LETTER YEH ISOLATED FORM + 0xfef2: 0x00f6, # ARABIC LETTER YEH FINAL FORM + 0xfef3: 0x00ea, # ARABIC LETTER YEH INITIAL FORM + 0xfef5: 0x00f9, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + 0xfef6: 0x00fa, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + 0xfef7: 0x0099, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + 0xfef8: 0x009a, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + 0xfefb: 0x009d, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + 0xfefc: 0x009e, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM +} diff --git a/Lib/encodings/cp865.py b/Lib/encodings/cp865.py new file mode 100644 index 0000000..6726cf3 --- /dev/null +++ b/Lib/encodings/cp865.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP865.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp865', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00a4, # CURRENCY SIGN + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xa4' # 0x00af -> CURRENCY SIGN + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00af, # CURRENCY SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp866.py b/Lib/encodings/cp866.py new file mode 100644 index 0000000..bec7ae3 --- /dev/null +++ b/Lib/encodings/cp866.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP866.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp866', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x0082: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x0083: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x0084: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x0085: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x0086: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x0087: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x0088: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x0089: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x008a: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x008b: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x008c: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x008d: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x008e: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x008f: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x0090: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x0091: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x0092: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x0093: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x0094: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x0095: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x0096: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x0097: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x0098: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x0099: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x009a: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x009b: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x009c: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x009d: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x009e: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009f: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a2: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00a3: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00a4: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a5: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a6: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00a7: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00a8: 0x0438, # CYRILLIC SMALL LETTER I + 0x00a9: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00aa: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00ab: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00ac: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00ad: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00ae: 0x043e, # CYRILLIC SMALL LETTER O + 0x00af: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e1: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e2: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e3: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e4: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00e5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00e6: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00e7: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00e8: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00e9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00ea: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x00eb: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00ec: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ed: 0x044d, # CYRILLIC SMALL LETTER E + 0x00ee: 0x044e, # CYRILLIC SMALL LETTER YU + 0x00ef: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00f0: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x00f1: 0x0451, # CYRILLIC SMALL LETTER IO + 0x00f2: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x00f3: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x00f4: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x00f5: 0x0457, # CYRILLIC SMALL LETTER YI + 0x00f6: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U + 0x00f7: 0x045e, # CYRILLIC SMALL LETTER SHORT U + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x2116, # NUMERO SIGN + 0x00fd: 0x00a4, # CURRENCY SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0410' # 0x0080 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0x0081 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0x0082 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0x0083 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0x0084 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0x0085 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0x0086 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0x0087 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0x0088 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0x0089 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0x008a -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0x008b -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0x008c -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0x008d -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0x008e -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0x008f -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0x0090 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0x0091 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0x0092 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0x0093 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0x0094 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0x0095 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0x0096 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0x0097 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0x0098 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0x0099 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0x009b -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0x009d -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0x009e -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0x009f -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0x00a1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0x00a2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0x00a3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0x00a4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0x00a5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0x00a6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0x00a7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0x00a8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0x00a9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0x00aa -> CYRILLIC SMALL LETTER KA + '\u043b' # 0x00ab -> CYRILLIC SMALL LETTER EL + '\u043c' # 0x00ac -> CYRILLIC SMALL LETTER EM + '\u043d' # 0x00ad -> CYRILLIC SMALL LETTER EN + '\u043e' # 0x00ae -> CYRILLIC SMALL LETTER O + '\u043f' # 0x00af -> CYRILLIC SMALL LETTER PE + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u0440' # 0x00e0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0x00e1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0x00e2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0x00e3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0x00e4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0x00e5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0x00e6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0x00e7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0x00e8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0x00e9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0x00ea -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0x00eb -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0x00ed -> CYRILLIC SMALL LETTER E + '\u044e' # 0x00ee -> CYRILLIC SMALL LETTER YU + '\u044f' # 0x00ef -> CYRILLIC SMALL LETTER YA + '\u0401' # 0x00f0 -> CYRILLIC CAPITAL LETTER IO + '\u0451' # 0x00f1 -> CYRILLIC SMALL LETTER IO + '\u0404' # 0x00f2 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0454' # 0x00f3 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0407' # 0x00f4 -> CYRILLIC CAPITAL LETTER YI + '\u0457' # 0x00f5 -> CYRILLIC SMALL LETTER YI + '\u040e' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045e' # 0x00f7 -> CYRILLIC SMALL LETTER SHORT U + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u2116' # 0x00fc -> NUMERO SIGN + '\xa4' # 0x00fd -> CURRENCY SIGN + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00fd, # CURRENCY SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x0401: 0x00f0, # CYRILLIC CAPITAL LETTER IO + 0x0404: 0x00f2, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0407: 0x00f4, # CYRILLIC CAPITAL LETTER YI + 0x040e: 0x00f6, # CYRILLIC CAPITAL LETTER SHORT U + 0x0410: 0x0080, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x0081, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x0082, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x0083, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x0084, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x0085, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x0086, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x0087, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x0088, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x0089, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x008a, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x008b, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x008c, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x008d, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x008e, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x008f, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x0090, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x0091, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x0092, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x0093, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x0094, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x0095, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x0096, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x0097, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x0098, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x0099, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x009b, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x009c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x009d, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009e, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x009f, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a1, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00a2, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00a3, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a4, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a5, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00a6, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00a7, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00a8, # CYRILLIC SMALL LETTER I + 0x0439: 0x00a9, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00aa, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00ab, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00ac, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00ad, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00ae, # CYRILLIC SMALL LETTER O + 0x043f: 0x00af, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e0, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e1, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e2, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e3, # CYRILLIC SMALL LETTER U + 0x0444: 0x00e4, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00e5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00e6, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00e7, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00e8, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00e9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x00ea, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00eb, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ec, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00ed, # CYRILLIC SMALL LETTER E + 0x044e: 0x00ee, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00ef, # CYRILLIC SMALL LETTER YA + 0x0451: 0x00f1, # CYRILLIC SMALL LETTER IO + 0x0454: 0x00f3, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0457: 0x00f5, # CYRILLIC SMALL LETTER YI + 0x045e: 0x00f7, # CYRILLIC SMALL LETTER SHORT U + 0x2116: 0x00fc, # NUMERO SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp869.py b/Lib/encodings/cp869.py new file mode 100644 index 0000000..8d8a29b --- /dev/null +++ b/Lib/encodings/cp869.py @@ -0,0 +1,689 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP869.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp869', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: None, # UNDEFINED + 0x0081: None, # UNDEFINED + 0x0082: None, # UNDEFINED + 0x0083: None, # UNDEFINED + 0x0084: None, # UNDEFINED + 0x0085: None, # UNDEFINED + 0x0086: 0x0386, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0087: None, # UNDEFINED + 0x0088: 0x00b7, # MIDDLE DOT + 0x0089: 0x00ac, # NOT SIGN + 0x008a: 0x00a6, # BROKEN BAR + 0x008b: 0x2018, # LEFT SINGLE QUOTATION MARK + 0x008c: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x008d: 0x0388, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x008e: 0x2015, # HORIZONTAL BAR + 0x008f: 0x0389, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x0090: 0x038a, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x0091: 0x03aa, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x0092: 0x038c, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x0093: None, # UNDEFINED + 0x0094: None, # UNDEFINED + 0x0095: 0x038e, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x0096: 0x03ab, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x0097: 0x00a9, # COPYRIGHT SIGN + 0x0098: 0x038f, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0099: 0x00b2, # SUPERSCRIPT TWO + 0x009a: 0x00b3, # SUPERSCRIPT THREE + 0x009b: 0x03ac, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x03ad, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x009e: 0x03ae, # GREEK SMALL LETTER ETA WITH TONOS + 0x009f: 0x03af, # GREEK SMALL LETTER IOTA WITH TONOS + 0x00a0: 0x03ca, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x00a1: 0x0390, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x00a2: 0x03cc, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x00a3: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x00a4: 0x0391, # GREEK CAPITAL LETTER ALPHA + 0x00a5: 0x0392, # GREEK CAPITAL LETTER BETA + 0x00a6: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00a7: 0x0394, # GREEK CAPITAL LETTER DELTA + 0x00a8: 0x0395, # GREEK CAPITAL LETTER EPSILON + 0x00a9: 0x0396, # GREEK CAPITAL LETTER ZETA + 0x00aa: 0x0397, # GREEK CAPITAL LETTER ETA + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ad: 0x0399, # GREEK CAPITAL LETTER IOTA + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x039a, # GREEK CAPITAL LETTER KAPPA + 0x00b6: 0x039b, # GREEK CAPITAL LETTER LAMDA + 0x00b7: 0x039c, # GREEK CAPITAL LETTER MU + 0x00b8: 0x039d, # GREEK CAPITAL LETTER NU + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x039e, # GREEK CAPITAL LETTER XI + 0x00be: 0x039f, # GREEK CAPITAL LETTER OMICRON + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x03a0, # GREEK CAPITAL LETTER PI + 0x00c7: 0x03a1, # GREEK CAPITAL LETTER RHO + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00d0: 0x03a4, # GREEK CAPITAL LETTER TAU + 0x00d1: 0x03a5, # GREEK CAPITAL LETTER UPSILON + 0x00d2: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00d3: 0x03a7, # GREEK CAPITAL LETTER CHI + 0x00d4: 0x03a8, # GREEK CAPITAL LETTER PSI + 0x00d5: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00d6: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00d7: 0x03b2, # GREEK SMALL LETTER BETA + 0x00d8: 0x03b3, # GREEK SMALL LETTER GAMMA + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00de: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b6, # GREEK SMALL LETTER ZETA + 0x00e1: 0x03b7, # GREEK SMALL LETTER ETA + 0x00e2: 0x03b8, # GREEK SMALL LETTER THETA + 0x00e3: 0x03b9, # GREEK SMALL LETTER IOTA + 0x00e4: 0x03ba, # GREEK SMALL LETTER KAPPA + 0x00e5: 0x03bb, # GREEK SMALL LETTER LAMDA + 0x00e6: 0x03bc, # GREEK SMALL LETTER MU + 0x00e7: 0x03bd, # GREEK SMALL LETTER NU + 0x00e8: 0x03be, # GREEK SMALL LETTER XI + 0x00e9: 0x03bf, # GREEK SMALL LETTER OMICRON + 0x00ea: 0x03c0, # GREEK SMALL LETTER PI + 0x00eb: 0x03c1, # GREEK SMALL LETTER RHO + 0x00ec: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00ed: 0x03c2, # GREEK SMALL LETTER FINAL SIGMA + 0x00ee: 0x03c4, # GREEK SMALL LETTER TAU + 0x00ef: 0x0384, # GREEK TONOS + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x03c5, # GREEK SMALL LETTER UPSILON + 0x00f3: 0x03c6, # GREEK SMALL LETTER PHI + 0x00f4: 0x03c7, # GREEK SMALL LETTER CHI + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x03c8, # GREEK SMALL LETTER PSI + 0x00f7: 0x0385, # GREEK DIALYTIKA TONOS + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x03c9, # GREEK SMALL LETTER OMEGA + 0x00fb: 0x03cb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x00fc: 0x03b0, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x00fd: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\ufffe' # 0x0080 -> UNDEFINED + '\ufffe' # 0x0081 -> UNDEFINED + '\ufffe' # 0x0082 -> UNDEFINED + '\ufffe' # 0x0083 -> UNDEFINED + '\ufffe' # 0x0084 -> UNDEFINED + '\ufffe' # 0x0085 -> UNDEFINED + '\u0386' # 0x0086 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\ufffe' # 0x0087 -> UNDEFINED + '\xb7' # 0x0088 -> MIDDLE DOT + '\xac' # 0x0089 -> NOT SIGN + '\xa6' # 0x008a -> BROKEN BAR + '\u2018' # 0x008b -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x008c -> RIGHT SINGLE QUOTATION MARK + '\u0388' # 0x008d -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u2015' # 0x008e -> HORIZONTAL BAR + '\u0389' # 0x008f -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0x0090 -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\u03aa' # 0x0091 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u038c' # 0x0092 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\ufffe' # 0x0093 -> UNDEFINED + '\ufffe' # 0x0094 -> UNDEFINED + '\u038e' # 0x0095 -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u03ab' # 0x0096 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\xa9' # 0x0097 -> COPYRIGHT SIGN + '\u038f' # 0x0098 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\xb2' # 0x0099 -> SUPERSCRIPT TWO + '\xb3' # 0x009a -> SUPERSCRIPT THREE + '\u03ac' # 0x009b -> GREEK SMALL LETTER ALPHA WITH TONOS + '\xa3' # 0x009c -> POUND SIGN + '\u03ad' # 0x009d -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0x009e -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0x009f -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03ca' # 0x00a0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u0390' # 0x00a1 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u03cc' # 0x00a2 -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0x00a3 -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u0391' # 0x00a4 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0x00a5 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0x00a6 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0x00a7 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0x00a8 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0x00a9 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0x00aa -> GREEK CAPITAL LETTER ETA + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\u0398' # 0x00ac -> GREEK CAPITAL LETTER THETA + '\u0399' # 0x00ad -> GREEK CAPITAL LETTER IOTA + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u039a' # 0x00b5 -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0x00b6 -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0x00b7 -> GREEK CAPITAL LETTER MU + '\u039d' # 0x00b8 -> GREEK CAPITAL LETTER NU + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u039e' # 0x00bd -> GREEK CAPITAL LETTER XI + '\u039f' # 0x00be -> GREEK CAPITAL LETTER OMICRON + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u03a0' # 0x00c6 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0x00c7 -> GREEK CAPITAL LETTER RHO + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u03a3' # 0x00cf -> GREEK CAPITAL LETTER SIGMA + '\u03a4' # 0x00d0 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0x00d1 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0x00d2 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0x00d3 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0x00d4 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0x00d5 -> GREEK CAPITAL LETTER OMEGA + '\u03b1' # 0x00d6 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0x00d7 -> GREEK SMALL LETTER BETA + '\u03b3' # 0x00d8 -> GREEK SMALL LETTER GAMMA + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u03b4' # 0x00dd -> GREEK SMALL LETTER DELTA + '\u03b5' # 0x00de -> GREEK SMALL LETTER EPSILON + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b6' # 0x00e0 -> GREEK SMALL LETTER ZETA + '\u03b7' # 0x00e1 -> GREEK SMALL LETTER ETA + '\u03b8' # 0x00e2 -> GREEK SMALL LETTER THETA + '\u03b9' # 0x00e3 -> GREEK SMALL LETTER IOTA + '\u03ba' # 0x00e4 -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0x00e5 -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0x00e6 -> GREEK SMALL LETTER MU + '\u03bd' # 0x00e7 -> GREEK SMALL LETTER NU + '\u03be' # 0x00e8 -> GREEK SMALL LETTER XI + '\u03bf' # 0x00e9 -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0x00ea -> GREEK SMALL LETTER PI + '\u03c1' # 0x00eb -> GREEK SMALL LETTER RHO + '\u03c3' # 0x00ec -> GREEK SMALL LETTER SIGMA + '\u03c2' # 0x00ed -> GREEK SMALL LETTER FINAL SIGMA + '\u03c4' # 0x00ee -> GREEK SMALL LETTER TAU + '\u0384' # 0x00ef -> GREEK TONOS + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u03c5' # 0x00f2 -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0x00f3 -> GREEK SMALL LETTER PHI + '\u03c7' # 0x00f4 -> GREEK SMALL LETTER CHI + '\xa7' # 0x00f5 -> SECTION SIGN + '\u03c8' # 0x00f6 -> GREEK SMALL LETTER PSI + '\u0385' # 0x00f7 -> GREEK DIALYTIKA TONOS + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\u03c9' # 0x00fa -> GREEK SMALL LETTER OMEGA + '\u03cb' # 0x00fb -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03b0' # 0x00fc -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u03ce' # 0x00fd -> GREEK SMALL LETTER OMEGA WITH TONOS + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a3: 0x009c, # POUND SIGN + 0x00a6: 0x008a, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x0097, # COPYRIGHT SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x0089, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x0099, # SUPERSCRIPT TWO + 0x00b3: 0x009a, # SUPERSCRIPT THREE + 0x00b7: 0x0088, # MIDDLE DOT + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x0384: 0x00ef, # GREEK TONOS + 0x0385: 0x00f7, # GREEK DIALYTIKA TONOS + 0x0386: 0x0086, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0388: 0x008d, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x0389: 0x008f, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x038a: 0x0090, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x038c: 0x0092, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x038e: 0x0095, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x038f: 0x0098, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0390: 0x00a1, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x0391: 0x00a4, # GREEK CAPITAL LETTER ALPHA + 0x0392: 0x00a5, # GREEK CAPITAL LETTER BETA + 0x0393: 0x00a6, # GREEK CAPITAL LETTER GAMMA + 0x0394: 0x00a7, # GREEK CAPITAL LETTER DELTA + 0x0395: 0x00a8, # GREEK CAPITAL LETTER EPSILON + 0x0396: 0x00a9, # GREEK CAPITAL LETTER ZETA + 0x0397: 0x00aa, # GREEK CAPITAL LETTER ETA + 0x0398: 0x00ac, # GREEK CAPITAL LETTER THETA + 0x0399: 0x00ad, # GREEK CAPITAL LETTER IOTA + 0x039a: 0x00b5, # GREEK CAPITAL LETTER KAPPA + 0x039b: 0x00b6, # GREEK CAPITAL LETTER LAMDA + 0x039c: 0x00b7, # GREEK CAPITAL LETTER MU + 0x039d: 0x00b8, # GREEK CAPITAL LETTER NU + 0x039e: 0x00bd, # GREEK CAPITAL LETTER XI + 0x039f: 0x00be, # GREEK CAPITAL LETTER OMICRON + 0x03a0: 0x00c6, # GREEK CAPITAL LETTER PI + 0x03a1: 0x00c7, # GREEK CAPITAL LETTER RHO + 0x03a3: 0x00cf, # GREEK CAPITAL LETTER SIGMA + 0x03a4: 0x00d0, # GREEK CAPITAL LETTER TAU + 0x03a5: 0x00d1, # GREEK CAPITAL LETTER UPSILON + 0x03a6: 0x00d2, # GREEK CAPITAL LETTER PHI + 0x03a7: 0x00d3, # GREEK CAPITAL LETTER CHI + 0x03a8: 0x00d4, # GREEK CAPITAL LETTER PSI + 0x03a9: 0x00d5, # GREEK CAPITAL LETTER OMEGA + 0x03aa: 0x0091, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x03ab: 0x0096, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x03ac: 0x009b, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x03ad: 0x009d, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x03ae: 0x009e, # GREEK SMALL LETTER ETA WITH TONOS + 0x03af: 0x009f, # GREEK SMALL LETTER IOTA WITH TONOS + 0x03b0: 0x00fc, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x03b1: 0x00d6, # GREEK SMALL LETTER ALPHA + 0x03b2: 0x00d7, # GREEK SMALL LETTER BETA + 0x03b3: 0x00d8, # GREEK SMALL LETTER GAMMA + 0x03b4: 0x00dd, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00de, # GREEK SMALL LETTER EPSILON + 0x03b6: 0x00e0, # GREEK SMALL LETTER ZETA + 0x03b7: 0x00e1, # GREEK SMALL LETTER ETA + 0x03b8: 0x00e2, # GREEK SMALL LETTER THETA + 0x03b9: 0x00e3, # GREEK SMALL LETTER IOTA + 0x03ba: 0x00e4, # GREEK SMALL LETTER KAPPA + 0x03bb: 0x00e5, # GREEK SMALL LETTER LAMDA + 0x03bc: 0x00e6, # GREEK SMALL LETTER MU + 0x03bd: 0x00e7, # GREEK SMALL LETTER NU + 0x03be: 0x00e8, # GREEK SMALL LETTER XI + 0x03bf: 0x00e9, # GREEK SMALL LETTER OMICRON + 0x03c0: 0x00ea, # GREEK SMALL LETTER PI + 0x03c1: 0x00eb, # GREEK SMALL LETTER RHO + 0x03c2: 0x00ed, # GREEK SMALL LETTER FINAL SIGMA + 0x03c3: 0x00ec, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00ee, # GREEK SMALL LETTER TAU + 0x03c5: 0x00f2, # GREEK SMALL LETTER UPSILON + 0x03c6: 0x00f3, # GREEK SMALL LETTER PHI + 0x03c7: 0x00f4, # GREEK SMALL LETTER CHI + 0x03c8: 0x00f6, # GREEK SMALL LETTER PSI + 0x03c9: 0x00fa, # GREEK SMALL LETTER OMEGA + 0x03ca: 0x00a0, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x03cb: 0x00fb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x03cc: 0x00a2, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x03cd: 0x00a3, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x03ce: 0x00fd, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x2015: 0x008e, # HORIZONTAL BAR + 0x2018: 0x008b, # LEFT SINGLE QUOTATION MARK + 0x2019: 0x008c, # RIGHT SINGLE QUOTATION MARK + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/Lib/encodings/cp874.py b/Lib/encodings/cp874.py new file mode 100644 index 0000000..59bfcbc --- /dev/null +++ b/Lib/encodings/cp874.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp874 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp874', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\ufffe' # 0x82 -> UNDEFINED + '\ufffe' # 0x83 -> UNDEFINED + '\ufffe' # 0x84 -> UNDEFINED + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\ufffe' # 0x86 -> UNDEFINED + '\ufffe' # 0x87 -> UNDEFINED + '\ufffe' # 0x88 -> UNDEFINED + '\ufffe' # 0x89 -> UNDEFINED + '\ufffe' # 0x8A -> UNDEFINED + '\ufffe' # 0x8B -> UNDEFINED + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\ufffe' # 0x99 -> UNDEFINED + '\ufffe' # 0x9A -> UNDEFINED + '\ufffe' # 0x9B -> UNDEFINED + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + '\u0e0b' # 0xAB -> THAI CHARACTER SO SO + '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + '\u0e0d' # 0xAD -> THAI CHARACTER YO YING + '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + '\u0e19' # 0xB9 -> THAI CHARACTER NO NU + '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + '\u0e1d' # 0xBD -> THAI CHARACTER FO FA + '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + '\u0e21' # 0xC1 -> THAI CHARACTER MO MA + '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + '\u0e24' # 0xC4 -> THAI CHARACTER RU + '\u0e25' # 0xC5 -> THAI CHARACTER LO LING + '\u0e26' # 0xC6 -> THAI CHARACTER LU + '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + '\u0e2d' # 0xCD -> THAI CHARACTER O ANG + '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + '\u0e30' # 0xD0 -> THAI CHARACTER SARA A + '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + '\u0e34' # 0xD4 -> THAI CHARACTER SARA I + '\u0e35' # 0xD5 -> THAI CHARACTER SARA II + '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + '\u0e38' # 0xD8 -> THAI CHARACTER SARA U + '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + '\ufffe' # 0xDB -> UNDEFINED + '\ufffe' # 0xDC -> UNDEFINED + '\ufffe' # 0xDD -> UNDEFINED + '\ufffe' # 0xDE -> UNDEFINED + '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + '\u0e40' # 0xE0 -> THAI CHARACTER SARA E + '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + '\u0e42' # 0xE2 -> THAI CHARACTER SARA O + '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + '\u0e50' # 0xF0 -> THAI DIGIT ZERO + '\u0e51' # 0xF1 -> THAI DIGIT ONE + '\u0e52' # 0xF2 -> THAI DIGIT TWO + '\u0e53' # 0xF3 -> THAI DIGIT THREE + '\u0e54' # 0xF4 -> THAI DIGIT FOUR + '\u0e55' # 0xF5 -> THAI DIGIT FIVE + '\u0e56' # 0xF6 -> THAI DIGIT SIX + '\u0e57' # 0xF7 -> THAI DIGIT SEVEN + '\u0e58' # 0xF8 -> THAI DIGIT EIGHT + '\u0e59' # 0xF9 -> THAI DIGIT NINE + '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + '\ufffe' # 0xFC -> UNDEFINED + '\ufffe' # 0xFD -> UNDEFINED + '\ufffe' # 0xFE -> UNDEFINED + '\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp875.py b/Lib/encodings/cp875.py new file mode 100644 index 0000000..c25a5a4 --- /dev/null +++ b/Lib/encodings/cp875.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp875 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp875', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\u0391' # 0x41 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0x42 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0x43 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0x44 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0x45 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0x46 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0x47 -> GREEK CAPITAL LETTER ETA + '\u0398' # 0x48 -> GREEK CAPITAL LETTER THETA + '\u0399' # 0x49 -> GREEK CAPITAL LETTER IOTA + '[' # 0x4A -> LEFT SQUARE BRACKET + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\u039a' # 0x51 -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0x52 -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0x53 -> GREEK CAPITAL LETTER MU + '\u039d' # 0x54 -> GREEK CAPITAL LETTER NU + '\u039e' # 0x55 -> GREEK CAPITAL LETTER XI + '\u039f' # 0x56 -> GREEK CAPITAL LETTER OMICRON + '\u03a0' # 0x57 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0x58 -> GREEK CAPITAL LETTER RHO + '\u03a3' # 0x59 -> GREEK CAPITAL LETTER SIGMA + ']' # 0x5A -> RIGHT SQUARE BRACKET + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\u03a4' # 0x62 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0x63 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0x64 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0x65 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0x66 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0x67 -> GREEK CAPITAL LETTER OMEGA + '\u03aa' # 0x68 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u03ab' # 0x69 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '|' # 0x6A -> VERTICAL LINE + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xa8' # 0x70 -> DIAERESIS + '\u0386' # 0x71 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\u0388' # 0x72 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0389' # 0x73 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\xa0' # 0x74 -> NO-BREAK SPACE + '\u038a' # 0x75 -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\u038c' # 0x76 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\u038e' # 0x77 -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u038f' # 0x78 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\u0385' # 0x80 -> GREEK DIALYTIKA TONOS + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\u03b1' # 0x8A -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0x8B -> GREEK SMALL LETTER BETA + '\u03b3' # 0x8C -> GREEK SMALL LETTER GAMMA + '\u03b4' # 0x8D -> GREEK SMALL LETTER DELTA + '\u03b5' # 0x8E -> GREEK SMALL LETTER EPSILON + '\u03b6' # 0x8F -> GREEK SMALL LETTER ZETA + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\u03b7' # 0x9A -> GREEK SMALL LETTER ETA + '\u03b8' # 0x9B -> GREEK SMALL LETTER THETA + '\u03b9' # 0x9C -> GREEK SMALL LETTER IOTA + '\u03ba' # 0x9D -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0x9E -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0x9F -> GREEK SMALL LETTER MU + '\xb4' # 0xA0 -> ACUTE ACCENT + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\u03bd' # 0xAA -> GREEK SMALL LETTER NU + '\u03be' # 0xAB -> GREEK SMALL LETTER XI + '\u03bf' # 0xAC -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xAD -> GREEK SMALL LETTER PI + '\u03c1' # 0xAE -> GREEK SMALL LETTER RHO + '\u03c3' # 0xAF -> GREEK SMALL LETTER SIGMA + '\xa3' # 0xB0 -> POUND SIGN + '\u03ac' # 0xB1 -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u03ad' # 0xB2 -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xB3 -> GREEK SMALL LETTER ETA WITH TONOS + '\u03ca' # 0xB4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03af' # 0xB5 -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03cc' # 0xB6 -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0xB7 -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03cb' # 0xB8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03ce' # 0xB9 -> GREEK SMALL LETTER OMEGA WITH TONOS + '\u03c2' # 0xBA -> GREEK SMALL LETTER FINAL SIGMA + '\u03c4' # 0xBB -> GREEK SMALL LETTER TAU + '\u03c5' # 0xBC -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0xBD -> GREEK SMALL LETTER PHI + '\u03c7' # 0xBE -> GREEK SMALL LETTER CHI + '\u03c8' # 0xBF -> GREEK SMALL LETTER PSI + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\u03c9' # 0xCB -> GREEK SMALL LETTER OMEGA + '\u0390' # 0xCC -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u03b0' # 0xCD -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u2018' # 0xCE -> LEFT SINGLE QUOTATION MARK + '\u2015' # 0xCF -> HORIZONTAL BAR + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb1' # 0xDA -> PLUS-MINUS SIGN + '\xbd' # 0xDB -> VULGAR FRACTION ONE HALF + '\x1a' # 0xDC -> SUBSTITUTE + '\u0387' # 0xDD -> GREEK ANO TELEIA + '\u2019' # 0xDE -> RIGHT SINGLE QUOTATION MARK + '\xa6' # 0xDF -> BROKEN BAR + '\\' # 0xE0 -> REVERSE SOLIDUS + '\x1a' # 0xE1 -> SUBSTITUTE + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xa7' # 0xEB -> SECTION SIGN + '\x1a' # 0xEC -> SUBSTITUTE + '\x1a' # 0xED -> SUBSTITUTE + '\xab' # 0xEE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xEF -> NOT SIGN + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xa9' # 0xFB -> COPYRIGHT SIGN + '\x1a' # 0xFC -> SUBSTITUTE + '\x1a' # 0xFD -> SUBSTITUTE + '\xbb' # 0xFE -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/cp932.py b/Lib/encodings/cp932.py new file mode 100644 index 0000000..e01f59b --- /dev/null +++ b/Lib/encodings/cp932.py @@ -0,0 +1,39 @@ +# +# cp932.py: Python Unicode Codec for CP932 +# +# Written by Hye-Shik Chang +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('cp932') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='cp932', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/cp949.py b/Lib/encodings/cp949.py new file mode 100644 index 0000000..627c871 --- /dev/null +++ b/Lib/encodings/cp949.py @@ -0,0 +1,39 @@ +# +# cp949.py: Python Unicode Codec for CP949 +# +# Written by Hye-Shik Chang +# + +import _codecs_kr, codecs +import _multibytecodec as mbc + +codec = _codecs_kr.getcodec('cp949') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='cp949', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/cp950.py b/Lib/encodings/cp950.py new file mode 100644 index 0000000..39eec5e --- /dev/null +++ b/Lib/encodings/cp950.py @@ -0,0 +1,39 @@ +# +# cp950.py: Python Unicode Codec for CP950 +# +# Written by Hye-Shik Chang +# + +import _codecs_tw, codecs +import _multibytecodec as mbc + +codec = _codecs_tw.getcodec('cp950') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='cp950', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/euc_jis_2004.py b/Lib/encodings/euc_jis_2004.py new file mode 100644 index 0000000..72b87ae --- /dev/null +++ b/Lib/encodings/euc_jis_2004.py @@ -0,0 +1,39 @@ +# +# euc_jis_2004.py: Python Unicode Codec for EUC_JIS_2004 +# +# Written by Hye-Shik Chang +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('euc_jis_2004') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_jis_2004', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/euc_jisx0213.py b/Lib/encodings/euc_jisx0213.py new file mode 100644 index 0000000..cc47d04 --- /dev/null +++ b/Lib/encodings/euc_jisx0213.py @@ -0,0 +1,39 @@ +# +# euc_jisx0213.py: Python Unicode Codec for EUC_JISX0213 +# +# Written by Hye-Shik Chang +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('euc_jisx0213') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_jisx0213', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/euc_jp.py b/Lib/encodings/euc_jp.py new file mode 100644 index 0000000..7bcbe41 --- /dev/null +++ b/Lib/encodings/euc_jp.py @@ -0,0 +1,39 @@ +# +# euc_jp.py: Python Unicode Codec for EUC_JP +# +# Written by Hye-Shik Chang +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('euc_jp') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_jp', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/euc_kr.py b/Lib/encodings/euc_kr.py new file mode 100644 index 0000000..c1fb126 --- /dev/null +++ b/Lib/encodings/euc_kr.py @@ -0,0 +1,39 @@ +# +# euc_kr.py: Python Unicode Codec for EUC_KR +# +# Written by Hye-Shik Chang +# + +import _codecs_kr, codecs +import _multibytecodec as mbc + +codec = _codecs_kr.getcodec('euc_kr') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_kr', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/gb18030.py b/Lib/encodings/gb18030.py new file mode 100644 index 0000000..34fb6c3 --- /dev/null +++ b/Lib/encodings/gb18030.py @@ -0,0 +1,39 @@ +# +# gb18030.py: Python Unicode Codec for GB18030 +# +# Written by Hye-Shik Chang +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('gb18030') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='gb18030', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/gb2312.py b/Lib/encodings/gb2312.py new file mode 100644 index 0000000..3c3b837 --- /dev/null +++ b/Lib/encodings/gb2312.py @@ -0,0 +1,39 @@ +# +# gb2312.py: Python Unicode Codec for GB2312 +# +# Written by Hye-Shik Chang +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('gb2312') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='gb2312', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/gbk.py b/Lib/encodings/gbk.py new file mode 100644 index 0000000..1b45db8 --- /dev/null +++ b/Lib/encodings/gbk.py @@ -0,0 +1,39 @@ +# +# gbk.py: Python Unicode Codec for GBK +# +# Written by Hye-Shik Chang +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('gbk') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='gbk', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/hex_codec.py b/Lib/encodings/hex_codec.py new file mode 100644 index 0000000..9fb1072 --- /dev/null +++ b/Lib/encodings/hex_codec.py @@ -0,0 +1,55 @@ +"""Python 'hex_codec' Codec - 2-digit hex content transfer encoding. + +This codec de/encodes from bytes to bytes. + +Written by Marc-Andre Lemburg (mal@lemburg.com). +""" + +import codecs +import binascii + +### Codec APIs + +def hex_encode(input, errors='strict'): + assert errors == 'strict' + return (binascii.b2a_hex(input), len(input)) + +def hex_decode(input, errors='strict'): + assert errors == 'strict' + return (binascii.a2b_hex(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return hex_encode(input, errors) + def decode(self, input, errors='strict'): + return hex_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + assert self.errors == 'strict' + return binascii.b2a_hex(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + assert self.errors == 'strict' + return binascii.a2b_hex(input) + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='hex', + encode=hex_encode, + decode=hex_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=False, + ) diff --git a/Lib/encodings/hp_roman8.py b/Lib/encodings/hp_roman8.py new file mode 100644 index 0000000..58de103 --- /dev/null +++ b/Lib/encodings/hp_roman8.py @@ -0,0 +1,314 @@ +""" Python Character Mapping Codec generated from 'hp_roman8.txt' with gencodec.py. + + Based on data from ftp://dkuug.dk/i18n/charmaps/HP-ROMAN8 (Keld Simonsen) + + Original source: LaserJet IIP Printer User's Manual HP part no + 33471-90901, Hewlet-Packard, June 1989. + + (Used with permission) + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='hp-roman8', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xc0' # 0xA1 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc2' # 0xA2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc8' # 0xA3 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xca' # 0xA4 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xA5 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xce' # 0xA6 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xA7 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xb4' # 0xA8 -> ACUTE ACCENT + '\u02cb' # 0xA9 -> MODIFIER LETTER GRAVE ACCENT (MANDARIN CHINESE FOURTH TONE) + '\u02c6' # 0xAA -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\xa8' # 0xAB -> DIAERESIS + '\u02dc' # 0xAC -> SMALL TILDE + '\xd9' # 0xAD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xdb' # 0xAE -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\u20a4' # 0xAF -> LIRA SIGN + '\xaf' # 0xB0 -> MACRON + '\xdd' # 0xB1 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xfd' # 0xB2 -> LATIN SMALL LETTER Y WITH ACUTE + '\xb0' # 0xB3 -> DEGREE SIGN + '\xc7' # 0xB4 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xe7' # 0xB5 -> LATIN SMALL LETTER C WITH CEDILLA + '\xd1' # 0xB6 -> LATIN CAPITAL LETTER N WITH TILDE + '\xf1' # 0xB7 -> LATIN SMALL LETTER N WITH TILDE + '\xa1' # 0xB8 -> INVERTED EXCLAMATION MARK + '\xbf' # 0xB9 -> INVERTED QUESTION MARK + '\xa4' # 0xBA -> CURRENCY SIGN + '\xa3' # 0xBB -> POUND SIGN + '\xa5' # 0xBC -> YEN SIGN + '\xa7' # 0xBD -> SECTION SIGN + '\u0192' # 0xBE -> LATIN SMALL LETTER F WITH HOOK + '\xa2' # 0xBF -> CENT SIGN + '\xe2' # 0xC0 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xea' # 0xC1 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xf4' # 0xC2 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xfb' # 0xC3 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xe1' # 0xC4 -> LATIN SMALL LETTER A WITH ACUTE + '\xe9' # 0xC5 -> LATIN SMALL LETTER E WITH ACUTE + '\xf3' # 0xC6 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0xC7 -> LATIN SMALL LETTER U WITH ACUTE + '\xe0' # 0xC8 -> LATIN SMALL LETTER A WITH GRAVE + '\xe8' # 0xC9 -> LATIN SMALL LETTER E WITH GRAVE + '\xf2' # 0xCA -> LATIN SMALL LETTER O WITH GRAVE + '\xf9' # 0xCB -> LATIN SMALL LETTER U WITH GRAVE + '\xe4' # 0xCC -> LATIN SMALL LETTER A WITH DIAERESIS + '\xeb' # 0xCD -> LATIN SMALL LETTER E WITH DIAERESIS + '\xf6' # 0xCE -> LATIN SMALL LETTER O WITH DIAERESIS + '\xfc' # 0xCF -> LATIN SMALL LETTER U WITH DIAERESIS + '\xc5' # 0xD0 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xee' # 0xD1 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xd8' # 0xD2 -> LATIN CAPITAL LETTER O WITH STROKE + '\xc6' # 0xD3 -> LATIN CAPITAL LETTER AE + '\xe5' # 0xD4 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xed' # 0xD5 -> LATIN SMALL LETTER I WITH ACUTE + '\xf8' # 0xD6 -> LATIN SMALL LETTER O WITH STROKE + '\xe6' # 0xD7 -> LATIN SMALL LETTER AE + '\xc4' # 0xD8 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xec' # 0xD9 -> LATIN SMALL LETTER I WITH GRAVE + '\xd6' # 0xDA -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0xDB -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xc9' # 0xDC -> LATIN CAPITAL LETTER E WITH ACUTE + '\xef' # 0xDD -> LATIN SMALL LETTER I WITH DIAERESIS + '\xdf' # 0xDE -> LATIN SMALL LETTER SHARP S (GERMAN) + '\xd4' # 0xDF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xc1' # 0xE0 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0xE1 -> LATIN CAPITAL LETTER A WITH TILDE + '\xe3' # 0xE2 -> LATIN SMALL LETTER A WITH TILDE + '\xd0' # 0xE3 -> LATIN CAPITAL LETTER ETH (ICELANDIC) + '\xf0' # 0xE4 -> LATIN SMALL LETTER ETH (ICELANDIC) + '\xcd' # 0xE5 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xcc' # 0xE6 -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xE7 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd2' # 0xE8 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd5' # 0xE9 -> LATIN CAPITAL LETTER O WITH TILDE + '\xf5' # 0xEA -> LATIN SMALL LETTER O WITH TILDE + '\u0160' # 0xEB -> LATIN CAPITAL LETTER S WITH CARON + '\u0161' # 0xEC -> LATIN SMALL LETTER S WITH CARON + '\xda' # 0xED -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0178' # 0xEE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xff' # 0xEF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xde' # 0xF0 -> LATIN CAPITAL LETTER THORN (ICELANDIC) + '\xfe' # 0xF1 -> LATIN SMALL LETTER THORN (ICELANDIC) + '\xb7' # 0xF2 -> MIDDLE DOT + '\xb5' # 0xF3 -> MICRO SIGN + '\xb6' # 0xF4 -> PILCROW SIGN + '\xbe' # 0xF5 -> VULGAR FRACTION THREE QUARTERS + '\u2014' # 0xF6 -> EM DASH + '\xbc' # 0xF7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xF8 -> VULGAR FRACTION ONE HALF + '\xaa' # 0xF9 -> FEMININE ORDINAL INDICATOR + '\xba' # 0xFA -> MASCULINE ORDINAL INDICATOR + '\xab' # 0xFB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u25a0' # 0xFC -> BLACK SQUARE + '\xbb' # 0xFD -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xb1' # 0xFE -> PLUS-MINUS SIGN + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/hz.py b/Lib/encodings/hz.py new file mode 100644 index 0000000..383442a --- /dev/null +++ b/Lib/encodings/hz.py @@ -0,0 +1,39 @@ +# +# hz.py: Python Unicode Codec for HZ +# +# Written by Hye-Shik Chang +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('hz') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='hz', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/idna.py b/Lib/encodings/idna.py new file mode 100644 index 0000000..ea40585 --- /dev/null +++ b/Lib/encodings/idna.py @@ -0,0 +1,309 @@ +# This module implements the RFCs 3490 (IDNA) and 3491 (Nameprep) + +import stringprep, re, codecs +from unicodedata import ucd_3_2_0 as unicodedata + +# IDNA section 3.1 +dots = re.compile("[\u002E\u3002\uFF0E\uFF61]") + +# IDNA section 5 +ace_prefix = b"xn--" +sace_prefix = "xn--" + +# This assumes query strings, so AllowUnassigned is true +def nameprep(label): + # Map + newlabel = [] + for c in label: + if stringprep.in_table_b1(c): + # Map to nothing + continue + newlabel.append(stringprep.map_table_b2(c)) + label = "".join(newlabel) + + # Normalize + label = unicodedata.normalize("NFKC", label) + + # Prohibit + for c in label: + if stringprep.in_table_c12(c) or \ + stringprep.in_table_c22(c) or \ + stringprep.in_table_c3(c) or \ + stringprep.in_table_c4(c) or \ + stringprep.in_table_c5(c) or \ + stringprep.in_table_c6(c) or \ + stringprep.in_table_c7(c) or \ + stringprep.in_table_c8(c) or \ + stringprep.in_table_c9(c): + raise UnicodeError("Invalid character %r" % c) + + # Check bidi + RandAL = [stringprep.in_table_d1(x) for x in label] + for c in RandAL: + if c: + # There is a RandAL char in the string. Must perform further + # tests: + # 1) The characters in section 5.8 MUST be prohibited. + # This is table C.8, which was already checked + # 2) If a string contains any RandALCat character, the string + # MUST NOT contain any LCat character. + if any(stringprep.in_table_d2(x) for x in label): + raise UnicodeError("Violation of BIDI requirement 2") + + # 3) If a string contains any RandALCat character, a + # RandALCat character MUST be the first character of the + # string, and a RandALCat character MUST be the last + # character of the string. + if not RandAL[0] or not RandAL[-1]: + raise UnicodeError("Violation of BIDI requirement 3") + + return label + +def ToASCII(label): + try: + # Step 1: try ASCII + label = label.encode("ascii") + except UnicodeError: + pass + else: + # Skip to step 3: UseSTD3ASCIIRules is false, so + # Skip to step 8. + if 0 < len(label) < 64: + return label + raise UnicodeError("label empty or too long") + + # Step 2: nameprep + label = nameprep(label) + + # Step 3: UseSTD3ASCIIRules is false + # Step 4: try ASCII + try: + label = label.encode("ascii") + except UnicodeError: + pass + else: + # Skip to step 8. + if 0 < len(label) < 64: + return label + raise UnicodeError("label empty or too long") + + # Step 5: Check ACE prefix + if label.startswith(sace_prefix): + raise UnicodeError("Label starts with ACE prefix") + + # Step 6: Encode with PUNYCODE + label = label.encode("punycode") + + # Step 7: Prepend ACE prefix + label = ace_prefix + label + + # Step 8: Check size + if 0 < len(label) < 64: + return label + raise UnicodeError("label empty or too long") + +def ToUnicode(label): + # Step 1: Check for ASCII + if isinstance(label, bytes): + pure_ascii = True + else: + try: + label = label.encode("ascii") + pure_ascii = True + except UnicodeError: + pure_ascii = False + if not pure_ascii: + # Step 2: Perform nameprep + label = nameprep(label) + # It doesn't say this, but apparently, it should be ASCII now + try: + label = label.encode("ascii") + except UnicodeError: + raise UnicodeError("Invalid character in IDN label") + # Step 3: Check for ACE prefix + if not label.startswith(ace_prefix): + return str(label, "ascii") + + # Step 4: Remove ACE prefix + label1 = label[len(ace_prefix):] + + # Step 5: Decode using PUNYCODE + result = label1.decode("punycode") + + # Step 6: Apply ToASCII + label2 = ToASCII(result) + + # Step 7: Compare the result of step 6 with the one of step 3 + # label2 will already be in lower case. + if str(label, "ascii").lower() != str(label2, "ascii"): + raise UnicodeError("IDNA does not round-trip", label, label2) + + # Step 8: return the result of step 5 + return result + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + + if errors != 'strict': + # IDNA is quite clear that implementations must be strict + raise UnicodeError("unsupported error handling "+errors) + + if not input: + return b'', 0 + + try: + result = input.encode('ascii') + except UnicodeEncodeError: + pass + else: + # ASCII name: fast path + labels = result.split(b'.') + for label in labels[:-1]: + if not (0 < len(label) < 64): + raise UnicodeError("label empty or too long") + if len(labels[-1]) >= 64: + raise UnicodeError("label too long") + return result, len(input) + + result = bytearray() + labels = dots.split(input) + if labels and not labels[-1]: + trailing_dot = b'.' + del labels[-1] + else: + trailing_dot = b'' + for label in labels: + if result: + # Join with U+002E + result.extend(b'.') + result.extend(ToASCII(label)) + return bytes(result+trailing_dot), len(input) + + def decode(self, input, errors='strict'): + + if errors != 'strict': + raise UnicodeError("Unsupported error handling "+errors) + + if not input: + return "", 0 + + # IDNA allows decoding to operate on Unicode strings, too. + if not isinstance(input, bytes): + # XXX obviously wrong, see #3232 + input = bytes(input) + + if ace_prefix not in input: + # Fast path + try: + return input.decode('ascii'), len(input) + except UnicodeDecodeError: + pass + + labels = input.split(b".") + + if labels and len(labels[-1]) == 0: + trailing_dot = '.' + del labels[-1] + else: + trailing_dot = '' + + result = [] + for label in labels: + result.append(ToUnicode(label)) + + return ".".join(result)+trailing_dot, len(input) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, input, errors, final): + if errors != 'strict': + # IDNA is quite clear that implementations must be strict + raise UnicodeError("unsupported error handling "+errors) + + if not input: + return (b'', 0) + + labels = dots.split(input) + trailing_dot = b'' + if labels: + if not labels[-1]: + trailing_dot = b'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = b'.' + + result = bytearray() + size = 0 + for label in labels: + if size: + # Join with U+002E + result.extend(b'.') + size += 1 + result.extend(ToASCII(label)) + size += len(label) + + result += trailing_dot + size += len(trailing_dot) + return (bytes(result), size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, input, errors, final): + if errors != 'strict': + raise UnicodeError("Unsupported error handling "+errors) + + if not input: + return ("", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(input, str): + labels = dots.split(input) + else: + # Must be ASCII string + input = str(input, "ascii") + labels = input.split(".") + + trailing_dot = '' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(ToUnicode(label)) + if size: + size += 1 + size += len(label) + + result = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/iso2022_jp.py b/Lib/encodings/iso2022_jp.py new file mode 100644 index 0000000..ab04060 --- /dev/null +++ b/Lib/encodings/iso2022_jp.py @@ -0,0 +1,39 @@ +# +# iso2022_jp.py: Python Unicode Codec for ISO2022_JP +# +# Written by Hye-Shik Chang +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/iso2022_jp_1.py b/Lib/encodings/iso2022_jp_1.py new file mode 100644 index 0000000..997044d --- /dev/null +++ b/Lib/encodings/iso2022_jp_1.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_1.py: Python Unicode Codec for ISO2022_JP_1 +# +# Written by Hye-Shik Chang +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_1') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_1', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/iso2022_jp_2.py b/Lib/encodings/iso2022_jp_2.py new file mode 100644 index 0000000..9106bf7 --- /dev/null +++ b/Lib/encodings/iso2022_jp_2.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_2.py: Python Unicode Codec for ISO2022_JP_2 +# +# Written by Hye-Shik Chang +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_2') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/iso2022_jp_2004.py b/Lib/encodings/iso2022_jp_2004.py new file mode 100644 index 0000000..40198bf --- /dev/null +++ b/Lib/encodings/iso2022_jp_2004.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_2004.py: Python Unicode Codec for ISO2022_JP_2004 +# +# Written by Hye-Shik Chang +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_2004') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_2004', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/iso2022_jp_3.py b/Lib/encodings/iso2022_jp_3.py new file mode 100644 index 0000000..346e08b --- /dev/null +++ b/Lib/encodings/iso2022_jp_3.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_3.py: Python Unicode Codec for ISO2022_JP_3 +# +# Written by Hye-Shik Chang +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_3') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_3', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/iso2022_jp_ext.py b/Lib/encodings/iso2022_jp_ext.py new file mode 100644 index 0000000..752bab9 --- /dev/null +++ b/Lib/encodings/iso2022_jp_ext.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_ext.py: Python Unicode Codec for ISO2022_JP_EXT +# +# Written by Hye-Shik Chang +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_ext') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_ext', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/iso2022_kr.py b/Lib/encodings/iso2022_kr.py new file mode 100644 index 0000000..bf70187 --- /dev/null +++ b/Lib/encodings/iso2022_kr.py @@ -0,0 +1,39 @@ +# +# iso2022_kr.py: Python Unicode Codec for ISO2022_KR +# +# Written by Hye-Shik Chang +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_kr') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_kr', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/iso8859_1.py b/Lib/encodings/iso8859_1.py new file mode 100644 index 0000000..8cfc01f --- /dev/null +++ b/Lib/encodings/iso8859_1.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_1 generated from 'MAPPINGS/ISO8859/8859-1.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-1', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_10.py b/Lib/encodings/iso8859_10.py new file mode 100644 index 0000000..b4fb041 --- /dev/null +++ b/Lib/encodings/iso8859_10.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_10 generated from 'MAPPINGS/ISO8859/8859-10.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-10', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0112' # 0xA2 -> LATIN CAPITAL LETTER E WITH MACRON + '\u0122' # 0xA3 -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u012a' # 0xA4 -> LATIN CAPITAL LETTER I WITH MACRON + '\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE + '\u0136' # 0xA6 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\xa7' # 0xA7 -> SECTION SIGN + '\u013b' # 0xA8 -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u0110' # 0xA9 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0160' # 0xAA -> LATIN CAPITAL LETTER S WITH CARON + '\u0166' # 0xAB -> LATIN CAPITAL LETTER T WITH STROKE + '\u017d' # 0xAC -> LATIN CAPITAL LETTER Z WITH CARON + '\xad' # 0xAD -> SOFT HYPHEN + '\u016a' # 0xAE -> LATIN CAPITAL LETTER U WITH MACRON + '\u014a' # 0xAF -> LATIN CAPITAL LETTER ENG + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + '\u0113' # 0xB2 -> LATIN SMALL LETTER E WITH MACRON + '\u0123' # 0xB3 -> LATIN SMALL LETTER G WITH CEDILLA + '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON + '\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE + '\u0137' # 0xB6 -> LATIN SMALL LETTER K WITH CEDILLA + '\xb7' # 0xB7 -> MIDDLE DOT + '\u013c' # 0xB8 -> LATIN SMALL LETTER L WITH CEDILLA + '\u0111' # 0xB9 -> LATIN SMALL LETTER D WITH STROKE + '\u0161' # 0xBA -> LATIN SMALL LETTER S WITH CARON + '\u0167' # 0xBB -> LATIN SMALL LETTER T WITH STROKE + '\u017e' # 0xBC -> LATIN SMALL LETTER Z WITH CARON + '\u2015' # 0xBD -> HORIZONTAL BAR + '\u016b' # 0xBE -> LATIN SMALL LETTER U WITH MACRON + '\u014b' # 0xBF -> LATIN SMALL LETTER ENG + '\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + '\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u0168' # 0xD7 -> LATIN CAPITAL LETTER U WITH TILDE + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + '\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA + '\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u0169' # 0xF7 -> LATIN SMALL LETTER U WITH TILDE + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + '\u0138' # 0xFF -> LATIN SMALL LETTER KRA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_11.py b/Lib/encodings/iso8859_11.py new file mode 100644 index 0000000..c7258ec --- /dev/null +++ b/Lib/encodings/iso8859_11.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_11 generated from 'MAPPINGS/ISO8859/8859-11.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-11', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + '\u0e0b' # 0xAB -> THAI CHARACTER SO SO + '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + '\u0e0d' # 0xAD -> THAI CHARACTER YO YING + '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + '\u0e19' # 0xB9 -> THAI CHARACTER NO NU + '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + '\u0e1d' # 0xBD -> THAI CHARACTER FO FA + '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + '\u0e21' # 0xC1 -> THAI CHARACTER MO MA + '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + '\u0e24' # 0xC4 -> THAI CHARACTER RU + '\u0e25' # 0xC5 -> THAI CHARACTER LO LING + '\u0e26' # 0xC6 -> THAI CHARACTER LU + '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + '\u0e2d' # 0xCD -> THAI CHARACTER O ANG + '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + '\u0e30' # 0xD0 -> THAI CHARACTER SARA A + '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + '\u0e34' # 0xD4 -> THAI CHARACTER SARA I + '\u0e35' # 0xD5 -> THAI CHARACTER SARA II + '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + '\u0e38' # 0xD8 -> THAI CHARACTER SARA U + '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + '\u0e40' # 0xE0 -> THAI CHARACTER SARA E + '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + '\u0e42' # 0xE2 -> THAI CHARACTER SARA O + '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + '\u0e50' # 0xF0 -> THAI DIGIT ZERO + '\u0e51' # 0xF1 -> THAI DIGIT ONE + '\u0e52' # 0xF2 -> THAI DIGIT TWO + '\u0e53' # 0xF3 -> THAI DIGIT THREE + '\u0e54' # 0xF4 -> THAI DIGIT FOUR + '\u0e55' # 0xF5 -> THAI DIGIT FIVE + '\u0e56' # 0xF6 -> THAI DIGIT SIX + '\u0e57' # 0xF7 -> THAI DIGIT SEVEN + '\u0e58' # 0xF8 -> THAI DIGIT EIGHT + '\u0e59' # 0xF9 -> THAI DIGIT NINE + '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_13.py b/Lib/encodings/iso8859_13.py new file mode 100644 index 0000000..6f8eab2 --- /dev/null +++ b/Lib/encodings/iso8859_13.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_13 generated from 'MAPPINGS/ISO8859/8859-13.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-13', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u201d' # 0xA1 -> RIGHT DOUBLE QUOTATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xc6' # 0xAF -> LATIN CAPITAL LETTER AE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u201c' # 0xB4 -> LEFT DOUBLE QUOTATION MARK + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xe6' # 0xBF -> LATIN SMALL LETTER AE + '\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON + '\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE + '\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON + '\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE + '\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE + '\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK + '\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK + '\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON + '\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK + '\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE + '\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE + '\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA + '\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA + '\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON + '\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA + '\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK + '\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE + '\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE + '\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON + '\u2019' # 0xFF -> RIGHT SINGLE QUOTATION MARK +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_14.py b/Lib/encodings/iso8859_14.py new file mode 100644 index 0000000..7568d4e --- /dev/null +++ b/Lib/encodings/iso8859_14.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_14 generated from 'MAPPINGS/ISO8859/8859-14.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-14', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u1e02' # 0xA1 -> LATIN CAPITAL LETTER B WITH DOT ABOVE + '\u1e03' # 0xA2 -> LATIN SMALL LETTER B WITH DOT ABOVE + '\xa3' # 0xA3 -> POUND SIGN + '\u010a' # 0xA4 -> LATIN CAPITAL LETTER C WITH DOT ABOVE + '\u010b' # 0xA5 -> LATIN SMALL LETTER C WITH DOT ABOVE + '\u1e0a' # 0xA6 -> LATIN CAPITAL LETTER D WITH DOT ABOVE + '\xa7' # 0xA7 -> SECTION SIGN + '\u1e80' # 0xA8 -> LATIN CAPITAL LETTER W WITH GRAVE + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u1e82' # 0xAA -> LATIN CAPITAL LETTER W WITH ACUTE + '\u1e0b' # 0xAB -> LATIN SMALL LETTER D WITH DOT ABOVE + '\u1ef2' # 0xAC -> LATIN CAPITAL LETTER Y WITH GRAVE + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u0178' # 0xAF -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u1e1e' # 0xB0 -> LATIN CAPITAL LETTER F WITH DOT ABOVE + '\u1e1f' # 0xB1 -> LATIN SMALL LETTER F WITH DOT ABOVE + '\u0120' # 0xB2 -> LATIN CAPITAL LETTER G WITH DOT ABOVE + '\u0121' # 0xB3 -> LATIN SMALL LETTER G WITH DOT ABOVE + '\u1e40' # 0xB4 -> LATIN CAPITAL LETTER M WITH DOT ABOVE + '\u1e41' # 0xB5 -> LATIN SMALL LETTER M WITH DOT ABOVE + '\xb6' # 0xB6 -> PILCROW SIGN + '\u1e56' # 0xB7 -> LATIN CAPITAL LETTER P WITH DOT ABOVE + '\u1e81' # 0xB8 -> LATIN SMALL LETTER W WITH GRAVE + '\u1e57' # 0xB9 -> LATIN SMALL LETTER P WITH DOT ABOVE + '\u1e83' # 0xBA -> LATIN SMALL LETTER W WITH ACUTE + '\u1e60' # 0xBB -> LATIN CAPITAL LETTER S WITH DOT ABOVE + '\u1ef3' # 0xBC -> LATIN SMALL LETTER Y WITH GRAVE + '\u1e84' # 0xBD -> LATIN CAPITAL LETTER W WITH DIAERESIS + '\u1e85' # 0xBE -> LATIN SMALL LETTER W WITH DIAERESIS + '\u1e61' # 0xBF -> LATIN SMALL LETTER S WITH DOT ABOVE + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u0174' # 0xD0 -> LATIN CAPITAL LETTER W WITH CIRCUMFLEX + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u1e6a' # 0xD7 -> LATIN CAPITAL LETTER T WITH DOT ABOVE + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0176' # 0xDE -> LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u0175' # 0xF0 -> LATIN SMALL LETTER W WITH CIRCUMFLEX + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u1e6b' # 0xF7 -> LATIN SMALL LETTER T WITH DOT ABOVE + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\u0177' # 0xFE -> LATIN SMALL LETTER Y WITH CIRCUMFLEX + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_15.py b/Lib/encodings/iso8859_15.py new file mode 100644 index 0000000..43bdecd --- /dev/null +++ b/Lib/encodings/iso8859_15.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_15 generated from 'MAPPINGS/ISO8859/8859-15.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-15', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\u20ac' # 0xA4 -> EURO SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON + '\xa7' # 0xA7 -> SECTION SIGN + '\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xBD -> LATIN SMALL LIGATURE OE + '\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_16.py b/Lib/encodings/iso8859_16.py new file mode 100644 index 0000000..e70c96e --- /dev/null +++ b/Lib/encodings/iso8859_16.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_16 generated from 'MAPPINGS/ISO8859/8859-16.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-16', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0105' # 0xA2 -> LATIN SMALL LETTER A WITH OGONEK + '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + '\u20ac' # 0xA4 -> EURO SIGN + '\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK + '\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON + '\xa7' # 0xA7 -> SECTION SIGN + '\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0218' # 0xAA -> LATIN CAPITAL LETTER S WITH COMMA BELOW + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xad' # 0xAD -> SOFT HYPHEN + '\u017a' # 0xAE -> LATIN SMALL LETTER Z WITH ACUTE + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u010c' # 0xB2 -> LATIN CAPITAL LETTER C WITH CARON + '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + '\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON + '\u201d' # 0xB5 -> RIGHT DOUBLE QUOTATION MARK + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON + '\u010d' # 0xB9 -> LATIN SMALL LETTER C WITH CARON + '\u0219' # 0xBA -> LATIN SMALL LETTER S WITH COMMA BELOW + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xBD -> LATIN SMALL LIGATURE OE + '\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0106' # 0xC5 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u015a' # 0xD7 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u0170' # 0xD8 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0118' # 0xDD -> LATIN CAPITAL LETTER E WITH OGONEK + '\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u0107' # 0xE5 -> LATIN SMALL LETTER C WITH ACUTE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u015b' # 0xF7 -> LATIN SMALL LETTER S WITH ACUTE + '\u0171' # 0xF8 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0119' # 0xFD -> LATIN SMALL LETTER E WITH OGONEK + '\u021b' # 0xFE -> LATIN SMALL LETTER T WITH COMMA BELOW + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_2.py b/Lib/encodings/iso8859_2.py new file mode 100644 index 0000000..3698747 --- /dev/null +++ b/Lib/encodings/iso8859_2.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_2 generated from 'MAPPINGS/ISO8859/8859-2.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u02d8' # 0xA2 -> BREVE + '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u013d' # 0xA5 -> LATIN CAPITAL LETTER L WITH CARON + '\u015a' # 0xA6 -> LATIN CAPITAL LETTER S WITH ACUTE + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u0164' # 0xAB -> LATIN CAPITAL LETTER T WITH CARON + '\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xad' # 0xAD -> SOFT HYPHEN + '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + '\u02db' # 0xB2 -> OGONEK + '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\u013e' # 0xB5 -> LATIN SMALL LETTER L WITH CARON + '\u015b' # 0xB6 -> LATIN SMALL LETTER S WITH ACUTE + '\u02c7' # 0xB7 -> CARON + '\xb8' # 0xB8 -> CEDILLA + '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + '\u0165' # 0xBB -> LATIN SMALL LETTER T WITH CARON + '\u017a' # 0xBC -> LATIN SMALL LETTER Z WITH ACUTE + '\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT + '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE + '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON + '\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE + '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON + '\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_3.py b/Lib/encodings/iso8859_3.py new file mode 100644 index 0000000..96d3063 --- /dev/null +++ b/Lib/encodings/iso8859_3.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_3 generated from 'MAPPINGS/ISO8859/8859-3.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-3', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0126' # 0xA1 -> LATIN CAPITAL LETTER H WITH STROKE + '\u02d8' # 0xA2 -> BREVE + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\ufffe' + '\u0124' # 0xA6 -> LATIN CAPITAL LETTER H WITH CIRCUMFLEX + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\u0130' # 0xA9 -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u011e' # 0xAB -> LATIN CAPITAL LETTER G WITH BREVE + '\u0134' # 0xAC -> LATIN CAPITAL LETTER J WITH CIRCUMFLEX + '\xad' # 0xAD -> SOFT HYPHEN + '\ufffe' + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0127' # 0xB1 -> LATIN SMALL LETTER H WITH STROKE + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\u0125' # 0xB6 -> LATIN SMALL LETTER H WITH CIRCUMFLEX + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\u0131' # 0xB9 -> LATIN SMALL LETTER DOTLESS I + '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + '\u011f' # 0xBB -> LATIN SMALL LETTER G WITH BREVE + '\u0135' # 0xBC -> LATIN SMALL LETTER J WITH CIRCUMFLEX + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\ufffe' + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\ufffe' + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u010a' # 0xC5 -> LATIN CAPITAL LETTER C WITH DOT ABOVE + '\u0108' # 0xC6 -> LATIN CAPITAL LETTER C WITH CIRCUMFLEX + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\ufffe' + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0120' # 0xD5 -> LATIN CAPITAL LETTER G WITH DOT ABOVE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u011c' # 0xD8 -> LATIN CAPITAL LETTER G WITH CIRCUMFLEX + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u016c' # 0xDD -> LATIN CAPITAL LETTER U WITH BREVE + '\u015c' # 0xDE -> LATIN CAPITAL LETTER S WITH CIRCUMFLEX + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\ufffe' + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u010b' # 0xE5 -> LATIN SMALL LETTER C WITH DOT ABOVE + '\u0109' # 0xE6 -> LATIN SMALL LETTER C WITH CIRCUMFLEX + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\ufffe' + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0121' # 0xF5 -> LATIN SMALL LETTER G WITH DOT ABOVE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u011d' # 0xF8 -> LATIN SMALL LETTER G WITH CIRCUMFLEX + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u016d' # 0xFD -> LATIN SMALL LETTER U WITH BREVE + '\u015d' # 0xFE -> LATIN SMALL LETTER S WITH CIRCUMFLEX + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_4.py b/Lib/encodings/iso8859_4.py new file mode 100644 index 0000000..65c1e00 --- /dev/null +++ b/Lib/encodings/iso8859_4.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_4 generated from 'MAPPINGS/ISO8859/8859-4.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-4', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0138' # 0xA2 -> LATIN SMALL LETTER KRA + '\u0156' # 0xA3 -> LATIN CAPITAL LETTER R WITH CEDILLA + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE + '\u013b' # 0xA6 -> LATIN CAPITAL LETTER L WITH CEDILLA + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + '\u0112' # 0xAA -> LATIN CAPITAL LETTER E WITH MACRON + '\u0122' # 0xAB -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u0166' # 0xAC -> LATIN CAPITAL LETTER T WITH STROKE + '\xad' # 0xAD -> SOFT HYPHEN + '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + '\u02db' # 0xB2 -> OGONEK + '\u0157' # 0xB3 -> LATIN SMALL LETTER R WITH CEDILLA + '\xb4' # 0xB4 -> ACUTE ACCENT + '\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE + '\u013c' # 0xB6 -> LATIN SMALL LETTER L WITH CEDILLA + '\u02c7' # 0xB7 -> CARON + '\xb8' # 0xB8 -> CEDILLA + '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + '\u0113' # 0xBA -> LATIN SMALL LETTER E WITH MACRON + '\u0123' # 0xBB -> LATIN SMALL LETTER G WITH CEDILLA + '\u0167' # 0xBC -> LATIN SMALL LETTER T WITH STROKE + '\u014a' # 0xBD -> LATIN CAPITAL LETTER ENG + '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + '\u014b' # 0xBF -> LATIN SMALL LETTER ENG + '\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u012a' # 0xCF -> LATIN CAPITAL LETTER I WITH MACRON + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON + '\u0136' # 0xD3 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0168' # 0xDD -> LATIN CAPITAL LETTER U WITH TILDE + '\u016a' # 0xDE -> LATIN CAPITAL LETTER U WITH MACRON + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u012b' # 0xEF -> LATIN SMALL LETTER I WITH MACRON + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA + '\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON + '\u0137' # 0xF3 -> LATIN SMALL LETTER K WITH CEDILLA + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0169' # 0xFD -> LATIN SMALL LETTER U WITH TILDE + '\u016b' # 0xFE -> LATIN SMALL LETTER U WITH MACRON + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_5.py b/Lib/encodings/iso8859_5.py new file mode 100644 index 0000000..a3c868a --- /dev/null +++ b/Lib/encodings/iso8859_5.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_5 generated from 'MAPPINGS/ISO8859/8859-5.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-5', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0401' # 0xA1 -> CYRILLIC CAPITAL LETTER IO + '\u0402' # 0xA2 -> CYRILLIC CAPITAL LETTER DJE + '\u0403' # 0xA3 -> CYRILLIC CAPITAL LETTER GJE + '\u0404' # 0xA4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0405' # 0xA5 -> CYRILLIC CAPITAL LETTER DZE + '\u0406' # 0xA6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0407' # 0xA7 -> CYRILLIC CAPITAL LETTER YI + '\u0408' # 0xA8 -> CYRILLIC CAPITAL LETTER JE + '\u0409' # 0xA9 -> CYRILLIC CAPITAL LETTER LJE + '\u040a' # 0xAA -> CYRILLIC CAPITAL LETTER NJE + '\u040b' # 0xAB -> CYRILLIC CAPITAL LETTER TSHE + '\u040c' # 0xAC -> CYRILLIC CAPITAL LETTER KJE + '\xad' # 0xAD -> SOFT HYPHEN + '\u040e' # 0xAE -> CYRILLIC CAPITAL LETTER SHORT U + '\u040f' # 0xAF -> CYRILLIC CAPITAL LETTER DZHE + '\u0410' # 0xB0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xB1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xB2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xB3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xB4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xB5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xB6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xB7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xB8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xB9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xBA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xBB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xBC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xBD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xBE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xBF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xC0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xC1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xC2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xC3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xC4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xC5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xC6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xC7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xC8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xC9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xCA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xCB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xCC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xCD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xCE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xCF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xD0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xD1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xD2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xD3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xD4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xD5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xD7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xD8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xD9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xDA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xDB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xDC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xDD -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xDE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xDF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xE0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xE1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xE2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xE3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xE4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xE5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xE6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xE7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xE8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xE9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xEA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xEB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xEC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xED -> CYRILLIC SMALL LETTER E + '\u044e' # 0xEE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xEF -> CYRILLIC SMALL LETTER YA + '\u2116' # 0xF0 -> NUMERO SIGN + '\u0451' # 0xF1 -> CYRILLIC SMALL LETTER IO + '\u0452' # 0xF2 -> CYRILLIC SMALL LETTER DJE + '\u0453' # 0xF3 -> CYRILLIC SMALL LETTER GJE + '\u0454' # 0xF4 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0455' # 0xF5 -> CYRILLIC SMALL LETTER DZE + '\u0456' # 0xF6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0457' # 0xF7 -> CYRILLIC SMALL LETTER YI + '\u0458' # 0xF8 -> CYRILLIC SMALL LETTER JE + '\u0459' # 0xF9 -> CYRILLIC SMALL LETTER LJE + '\u045a' # 0xFA -> CYRILLIC SMALL LETTER NJE + '\u045b' # 0xFB -> CYRILLIC SMALL LETTER TSHE + '\u045c' # 0xFC -> CYRILLIC SMALL LETTER KJE + '\xa7' # 0xFD -> SECTION SIGN + '\u045e' # 0xFE -> CYRILLIC SMALL LETTER SHORT U + '\u045f' # 0xFF -> CYRILLIC SMALL LETTER DZHE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_6.py b/Lib/encodings/iso8859_6.py new file mode 100644 index 0000000..b02ade6 --- /dev/null +++ b/Lib/encodings/iso8859_6.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_6 generated from 'MAPPINGS/ISO8859/8859-6.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-6', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\ufffe' + '\ufffe' + '\ufffe' + '\xa4' # 0xA4 -> CURRENCY SIGN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u060c' # 0xAC -> ARABIC COMMA + '\xad' # 0xAD -> SOFT HYPHEN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u061b' # 0xBB -> ARABIC SEMICOLON + '\ufffe' + '\ufffe' + '\ufffe' + '\u061f' # 0xBF -> ARABIC QUESTION MARK + '\ufffe' + '\u0621' # 0xC1 -> ARABIC LETTER HAMZA + '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0xC7 -> ARABIC LETTER ALEF + '\u0628' # 0xC8 -> ARABIC LETTER BEH + '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xCA -> ARABIC LETTER TEH + '\u062b' # 0xCB -> ARABIC LETTER THEH + '\u062c' # 0xCC -> ARABIC LETTER JEEM + '\u062d' # 0xCD -> ARABIC LETTER HAH + '\u062e' # 0xCE -> ARABIC LETTER KHAH + '\u062f' # 0xCF -> ARABIC LETTER DAL + '\u0630' # 0xD0 -> ARABIC LETTER THAL + '\u0631' # 0xD1 -> ARABIC LETTER REH + '\u0632' # 0xD2 -> ARABIC LETTER ZAIN + '\u0633' # 0xD3 -> ARABIC LETTER SEEN + '\u0634' # 0xD4 -> ARABIC LETTER SHEEN + '\u0635' # 0xD5 -> ARABIC LETTER SAD + '\u0636' # 0xD6 -> ARABIC LETTER DAD + '\u0637' # 0xD7 -> ARABIC LETTER TAH + '\u0638' # 0xD8 -> ARABIC LETTER ZAH + '\u0639' # 0xD9 -> ARABIC LETTER AIN + '\u063a' # 0xDA -> ARABIC LETTER GHAIN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u0640' # 0xE0 -> ARABIC TATWEEL + '\u0641' # 0xE1 -> ARABIC LETTER FEH + '\u0642' # 0xE2 -> ARABIC LETTER QAF + '\u0643' # 0xE3 -> ARABIC LETTER KAF + '\u0644' # 0xE4 -> ARABIC LETTER LAM + '\u0645' # 0xE5 -> ARABIC LETTER MEEM + '\u0646' # 0xE6 -> ARABIC LETTER NOON + '\u0647' # 0xE7 -> ARABIC LETTER HEH + '\u0648' # 0xE8 -> ARABIC LETTER WAW + '\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xEA -> ARABIC LETTER YEH + '\u064b' # 0xEB -> ARABIC FATHATAN + '\u064c' # 0xEC -> ARABIC DAMMATAN + '\u064d' # 0xED -> ARABIC KASRATAN + '\u064e' # 0xEE -> ARABIC FATHA + '\u064f' # 0xEF -> ARABIC DAMMA + '\u0650' # 0xF0 -> ARABIC KASRA + '\u0651' # 0xF1 -> ARABIC SHADDA + '\u0652' # 0xF2 -> ARABIC SUKUN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_7.py b/Lib/encodings/iso8859_7.py new file mode 100644 index 0000000..d7b39cb --- /dev/null +++ b/Lib/encodings/iso8859_7.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_7 generated from 'MAPPINGS/ISO8859/8859-7.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-7', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u2018' # 0xA1 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xA2 -> RIGHT SINGLE QUOTATION MARK + '\xa3' # 0xA3 -> POUND SIGN + '\u20ac' # 0xA4 -> EURO SIGN + '\u20af' # 0xA5 -> DRACHMA SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u037a' # 0xAA -> GREEK YPOGEGRAMMENI + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\ufffe' + '\u2015' # 0xAF -> HORIZONTAL BAR + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u0384' # 0xB4 -> GREEK TONOS + '\u0385' # 0xB5 -> GREEK DIALYTIKA TONOS + '\u0386' # 0xB6 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA + '\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA + '\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA + '\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0xCC -> GREEK CAPITAL LETTER MU + '\u039d' # 0xCD -> GREEK CAPITAL LETTER NU + '\u039e' # 0xCE -> GREEK CAPITAL LETTER XI + '\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON + '\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO + '\ufffe' + '\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA + '\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA + '\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + '\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA + '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + '\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA + '\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA + '\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA + '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + '\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0xEC -> GREEK SMALL LETTER MU + '\u03bd' # 0xED -> GREEK SMALL LETTER NU + '\u03be' # 0xEE -> GREEK SMALL LETTER XI + '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + '\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO + '\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA + '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + '\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI + '\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI + '\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI + '\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA + '\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_8.py b/Lib/encodings/iso8859_8.py new file mode 100644 index 0000000..8184902 --- /dev/null +++ b/Lib/encodings/iso8859_8.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_8 generated from 'MAPPINGS/ISO8859/8859-8.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-8', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\ufffe' + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xd7' # 0xAA -> MULTIPLICATION SIGN + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xf7' # 0xBA -> DIVISION SIGN + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u2017' # 0xDF -> DOUBLE LOW LINE + '\u05d0' # 0xE0 -> HEBREW LETTER ALEF + '\u05d1' # 0xE1 -> HEBREW LETTER BET + '\u05d2' # 0xE2 -> HEBREW LETTER GIMEL + '\u05d3' # 0xE3 -> HEBREW LETTER DALET + '\u05d4' # 0xE4 -> HEBREW LETTER HE + '\u05d5' # 0xE5 -> HEBREW LETTER VAV + '\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN + '\u05d7' # 0xE7 -> HEBREW LETTER HET + '\u05d8' # 0xE8 -> HEBREW LETTER TET + '\u05d9' # 0xE9 -> HEBREW LETTER YOD + '\u05da' # 0xEA -> HEBREW LETTER FINAL KAF + '\u05db' # 0xEB -> HEBREW LETTER KAF + '\u05dc' # 0xEC -> HEBREW LETTER LAMED + '\u05dd' # 0xED -> HEBREW LETTER FINAL MEM + '\u05de' # 0xEE -> HEBREW LETTER MEM + '\u05df' # 0xEF -> HEBREW LETTER FINAL NUN + '\u05e0' # 0xF0 -> HEBREW LETTER NUN + '\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH + '\u05e2' # 0xF2 -> HEBREW LETTER AYIN + '\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE + '\u05e4' # 0xF4 -> HEBREW LETTER PE + '\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0xF6 -> HEBREW LETTER TSADI + '\u05e7' # 0xF7 -> HEBREW LETTER QOF + '\u05e8' # 0xF8 -> HEBREW LETTER RESH + '\u05e9' # 0xF9 -> HEBREW LETTER SHIN + '\u05ea' # 0xFA -> HEBREW LETTER TAV + '\ufffe' + '\ufffe' + '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/iso8859_9.py b/Lib/encodings/iso8859_9.py new file mode 100644 index 0000000..e539fdd --- /dev/null +++ b/Lib/encodings/iso8859_9.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_9 generated from 'MAPPINGS/ISO8859/8859-9.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-9', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I + '\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/johab.py b/Lib/encodings/johab.py new file mode 100644 index 0000000..512aeeb --- /dev/null +++ b/Lib/encodings/johab.py @@ -0,0 +1,39 @@ +# +# johab.py: Python Unicode Codec for JOHAB +# +# Written by Hye-Shik Chang +# + +import _codecs_kr, codecs +import _multibytecodec as mbc + +codec = _codecs_kr.getcodec('johab') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='johab', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/koi8_r.py b/Lib/encodings/koi8_r.py new file mode 100644 index 0000000..41ddde8 --- /dev/null +++ b/Lib/encodings/koi8_r.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec koi8_r generated from 'MAPPINGS/VENDORS/MISC/KOI8-R.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-r', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL + '\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u2580' # 0x8B -> UPPER HALF BLOCK + '\u2584' # 0x8C -> LOWER HALF BLOCK + '\u2588' # 0x8D -> FULL BLOCK + '\u258c' # 0x8E -> LEFT HALF BLOCK + '\u2590' # 0x8F -> RIGHT HALF BLOCK + '\u2591' # 0x90 -> LIGHT SHADE + '\u2592' # 0x91 -> MEDIUM SHADE + '\u2593' # 0x92 -> DARK SHADE + '\u2320' # 0x93 -> TOP HALF INTEGRAL + '\u25a0' # 0x94 -> BLACK SQUARE + '\u2219' # 0x95 -> BULLET OPERATOR + '\u221a' # 0x96 -> SQUARE ROOT + '\u2248' # 0x97 -> ALMOST EQUAL TO + '\u2264' # 0x98 -> LESS-THAN OR EQUAL TO + '\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO + '\xa0' # 0x9A -> NO-BREAK SPACE + '\u2321' # 0x9B -> BOTTOM HALF INTEGRAL + '\xb0' # 0x9C -> DEGREE SIGN + '\xb2' # 0x9D -> SUPERSCRIPT TWO + '\xb7' # 0x9E -> MIDDLE DOT + '\xf7' # 0x9F -> DIVISION SIGN + '\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL + '\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + '\u2553' # 0xA4 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2555' # 0xA6 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2556' # 0xA7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u255c' # 0xAD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + '\u2562' # 0xB4 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2564' # 0xB6 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u256b' # 0xBD -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa9' # 0xBF -> COPYRIGHT SIGN + '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/koi8_t.py b/Lib/encodings/koi8_t.py new file mode 100644 index 0000000..b5415ba --- /dev/null +++ b/Lib/encodings/koi8_t.py @@ -0,0 +1,308 @@ +""" Python Character Mapping Codec koi8_t +""" +# http://ru.wikipedia.org/wiki/КОИ-8 +# http://www.opensource.apple.com/source/libiconv/libiconv-4/libiconv/tests/KOI8-T.TXT + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-t', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u049b' # 0x80 -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u0493' # 0x81 -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0492' # 0x83 -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\u04b3' # 0x8A -> CYRILLIC SMALL LETTER HA WITH DESCENDER + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u04b2' # 0x8C -> CYRILLIC CAPITAL LETTER HA WITH DESCENDER + '\u04b7' # 0x8D -> CYRILLIC SMALL LETTER CHE WITH DESCENDER + '\u04b6' # 0x8E -> CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + '\ufffe' # 0x8F -> UNDEFINED + '\u049a' # 0x90 -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\ufffe' # 0xA0 -> UNDEFINED + '\u04ef' # 0xA1 -> CYRILLIC SMALL LETTER U WITH MACRON + '\u04ee' # 0xA2 -> CYRILLIC CAPITAL LETTER U WITH MACRON + '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u04e3' # 0xA5 -> CYRILLIC SMALL LETTER I WITH MACRON + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\ufffe' # 0xA8 -> UNDEFINED + '\ufffe' # 0xA9 -> UNDEFINED + '\ufffe' # 0xAA -> UNDEFINED + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\ufffe' # 0xAF -> UNDEFINED + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + '\ufffe' # 0xB4 -> UNDEFINED + '\u04e2' # 0xB5 -> CYRILLIC CAPITAL LETTER I WITH MACRON + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\ufffe' # 0xB8 -> UNDEFINED + '\u2116' # 0xB9 -> NUMERO SIGN + '\ufffe' # 0xBA -> UNDEFINED + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\ufffe' # 0xBC -> UNDEFINED + '\ufffe' # 0xBD -> UNDEFINED + '\ufffe' # 0xBE -> UNDEFINED + '\xa9' # 0xBF -> COPYRIGHT SIGN + '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/koi8_u.py b/Lib/encodings/koi8_u.py new file mode 100644 index 0000000..f9e3fae --- /dev/null +++ b/Lib/encodings/koi8_u.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec koi8_u generated from 'python-mappings/KOI8-U.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-u', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL + '\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u2580' # 0x8B -> UPPER HALF BLOCK + '\u2584' # 0x8C -> LOWER HALF BLOCK + '\u2588' # 0x8D -> FULL BLOCK + '\u258c' # 0x8E -> LEFT HALF BLOCK + '\u2590' # 0x8F -> RIGHT HALF BLOCK + '\u2591' # 0x90 -> LIGHT SHADE + '\u2592' # 0x91 -> MEDIUM SHADE + '\u2593' # 0x92 -> DARK SHADE + '\u2320' # 0x93 -> TOP HALF INTEGRAL + '\u25a0' # 0x94 -> BLACK SQUARE + '\u2219' # 0x95 -> BULLET OPERATOR + '\u221a' # 0x96 -> SQUARE ROOT + '\u2248' # 0x97 -> ALMOST EQUAL TO + '\u2264' # 0x98 -> LESS-THAN OR EQUAL TO + '\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO + '\xa0' # 0x9A -> NO-BREAK SPACE + '\u2321' # 0x9B -> BOTTOM HALF INTEGRAL + '\xb0' # 0x9C -> DEGREE SIGN + '\xb2' # 0x9D -> SUPERSCRIPT TWO + '\xb7' # 0x9E -> MIDDLE DOT + '\xf7' # 0x9F -> DIVISION SIGN + '\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL + '\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + '\u0454' # 0xA4 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u0456' # 0xA6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0457' # 0xA7 -> CYRILLIC SMALL LETTER YI (UKRAINIAN) + '\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u0491' # 0xAD -> CYRILLIC SMALL LETTER UKRAINIAN GHE WITH UPTURN + '\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + '\u0404' # 0xB4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u0406' # 0xB6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0407' # 0xB7 -> CYRILLIC CAPITAL LETTER YI (UKRAINIAN) + '\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u0490' # 0xBD -> CYRILLIC CAPITAL LETTER UKRAINIAN GHE WITH UPTURN + '\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa9' # 0xBF -> COPYRIGHT SIGN + '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/kz1048.py b/Lib/encodings/kz1048.py new file mode 100644 index 0000000..712aee6 --- /dev/null +++ b/Lib/encodings/kz1048.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec kz1048 generated from 'MAPPINGS/VENDORS/MISC/KZ1048.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='kz1048', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE + '\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u20ac' # 0x88 -> EURO SIGN + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE + '\u049a' # 0x8D -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u04ba' # 0x8E -> CYRILLIC CAPITAL LETTER SHHA + '\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE + '\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE + '\u049b' # 0x9D -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u04bb' # 0x9E -> CYRILLIC SMALL LETTER SHHA + '\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u04b0' # 0xA1 -> CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + '\u04b1' # 0xA2 -> CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + '\u04d8' # 0xA3 -> CYRILLIC CAPITAL LETTER SCHWA + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u04e8' # 0xA5 -> CYRILLIC CAPITAL LETTER BARRED O + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0492' # 0xAA -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u04ae' # 0xAF -> CYRILLIC CAPITAL LETTER STRAIGHT U + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u04e9' # 0xB4 -> CYRILLIC SMALL LETTER BARRED O + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + '\u2116' # 0xB9 -> NUMERO SIGN + '\u0493' # 0xBA -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u04d9' # 0xBC -> CYRILLIC SMALL LETTER SCHWA + '\u04a2' # 0xBD -> CYRILLIC CAPITAL LETTER EN WITH DESCENDER + '\u04a3' # 0xBE -> CYRILLIC SMALL LETTER EN WITH DESCENDER + '\u04af' # 0xBF -> CYRILLIC SMALL LETTER STRAIGHT U + '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/latin_1.py b/Lib/encodings/latin_1.py new file mode 100644 index 0000000..370160c --- /dev/null +++ b/Lib/encodings/latin_1.py @@ -0,0 +1,50 @@ +""" Python 'latin-1' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.latin_1_encode + decode = codecs.latin_1_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.latin_1_encode(input,self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.latin_1_decode(input,self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +class StreamConverter(StreamWriter,StreamReader): + + encode = codecs.latin_1_decode + decode = codecs.latin_1_encode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-1', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/mac_arabic.py b/Lib/encodings/mac_arabic.py new file mode 100644 index 0000000..72847e8 --- /dev/null +++ b/Lib/encodings/mac_arabic.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/APPLE/ARABIC.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-arabic', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x0081: 0x00a0, # NO-BREAK SPACE, right-left + 0x0082: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0083: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0084: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x0085: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x0086: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x0087: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x0088: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0089: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x008a: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x008b: 0x06ba, # ARABIC LETTER NOON GHUNNA + 0x008c: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x008d: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x008e: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x008f: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x0090: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0091: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x0092: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x0093: 0x2026, # HORIZONTAL ELLIPSIS, right-left + 0x0094: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x0095: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x0096: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x0097: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x0098: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x0099: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x009a: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x009b: 0x00f7, # DIVISION SIGN, right-left + 0x009c: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x009d: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x009e: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x009f: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00a0: 0x0020, # SPACE, right-left + 0x00a1: 0x0021, # EXCLAMATION MARK, right-left + 0x00a2: 0x0022, # QUOTATION MARK, right-left + 0x00a3: 0x0023, # NUMBER SIGN, right-left + 0x00a4: 0x0024, # DOLLAR SIGN, right-left + 0x00a5: 0x066a, # ARABIC PERCENT SIGN + 0x00a6: 0x0026, # AMPERSAND, right-left + 0x00a7: 0x0027, # APOSTROPHE, right-left + 0x00a8: 0x0028, # LEFT PARENTHESIS, right-left + 0x00a9: 0x0029, # RIGHT PARENTHESIS, right-left + 0x00aa: 0x002a, # ASTERISK, right-left + 0x00ab: 0x002b, # PLUS SIGN, right-left + 0x00ac: 0x060c, # ARABIC COMMA + 0x00ad: 0x002d, # HYPHEN-MINUS, right-left + 0x00ae: 0x002e, # FULL STOP, right-left + 0x00af: 0x002f, # SOLIDUS, right-left + 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO, right-left (need override) + 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE, right-left (need override) + 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO, right-left (need override) + 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE, right-left (need override) + 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR, right-left (need override) + 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE, right-left (need override) + 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX, right-left (need override) + 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) + 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) + 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE, right-left (need override) + 0x00ba: 0x003a, # COLON, right-left + 0x00bb: 0x061b, # ARABIC SEMICOLON + 0x00bc: 0x003c, # LESS-THAN SIGN, right-left + 0x00bd: 0x003d, # EQUALS SIGN, right-left + 0x00be: 0x003e, # GREATER-THAN SIGN, right-left + 0x00bf: 0x061f, # ARABIC QUESTION MARK + 0x00c0: 0x274a, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + 0x00c1: 0x0621, # ARABIC LETTER HAMZA + 0x00c2: 0x0622, # ARABIC LETTER ALEF WITH MADDA ABOVE + 0x00c3: 0x0623, # ARABIC LETTER ALEF WITH HAMZA ABOVE + 0x00c4: 0x0624, # ARABIC LETTER WAW WITH HAMZA ABOVE + 0x00c5: 0x0625, # ARABIC LETTER ALEF WITH HAMZA BELOW + 0x00c6: 0x0626, # ARABIC LETTER YEH WITH HAMZA ABOVE + 0x00c7: 0x0627, # ARABIC LETTER ALEF + 0x00c8: 0x0628, # ARABIC LETTER BEH + 0x00c9: 0x0629, # ARABIC LETTER TEH MARBUTA + 0x00ca: 0x062a, # ARABIC LETTER TEH + 0x00cb: 0x062b, # ARABIC LETTER THEH + 0x00cc: 0x062c, # ARABIC LETTER JEEM + 0x00cd: 0x062d, # ARABIC LETTER HAH + 0x00ce: 0x062e, # ARABIC LETTER KHAH + 0x00cf: 0x062f, # ARABIC LETTER DAL + 0x00d0: 0x0630, # ARABIC LETTER THAL + 0x00d1: 0x0631, # ARABIC LETTER REH + 0x00d2: 0x0632, # ARABIC LETTER ZAIN + 0x00d3: 0x0633, # ARABIC LETTER SEEN + 0x00d4: 0x0634, # ARABIC LETTER SHEEN + 0x00d5: 0x0635, # ARABIC LETTER SAD + 0x00d6: 0x0636, # ARABIC LETTER DAD + 0x00d7: 0x0637, # ARABIC LETTER TAH + 0x00d8: 0x0638, # ARABIC LETTER ZAH + 0x00d9: 0x0639, # ARABIC LETTER AIN + 0x00da: 0x063a, # ARABIC LETTER GHAIN + 0x00db: 0x005b, # LEFT SQUARE BRACKET, right-left + 0x00dc: 0x005c, # REVERSE SOLIDUS, right-left + 0x00dd: 0x005d, # RIGHT SQUARE BRACKET, right-left + 0x00de: 0x005e, # CIRCUMFLEX ACCENT, right-left + 0x00df: 0x005f, # LOW LINE, right-left + 0x00e0: 0x0640, # ARABIC TATWEEL + 0x00e1: 0x0641, # ARABIC LETTER FEH + 0x00e2: 0x0642, # ARABIC LETTER QAF + 0x00e3: 0x0643, # ARABIC LETTER KAF + 0x00e4: 0x0644, # ARABIC LETTER LAM + 0x00e5: 0x0645, # ARABIC LETTER MEEM + 0x00e6: 0x0646, # ARABIC LETTER NOON + 0x00e7: 0x0647, # ARABIC LETTER HEH + 0x00e8: 0x0648, # ARABIC LETTER WAW + 0x00e9: 0x0649, # ARABIC LETTER ALEF MAKSURA + 0x00ea: 0x064a, # ARABIC LETTER YEH + 0x00eb: 0x064b, # ARABIC FATHATAN + 0x00ec: 0x064c, # ARABIC DAMMATAN + 0x00ed: 0x064d, # ARABIC KASRATAN + 0x00ee: 0x064e, # ARABIC FATHA + 0x00ef: 0x064f, # ARABIC DAMMA + 0x00f0: 0x0650, # ARABIC KASRA + 0x00f1: 0x0651, # ARABIC SHADDA + 0x00f2: 0x0652, # ARABIC SUKUN + 0x00f3: 0x067e, # ARABIC LETTER PEH + 0x00f4: 0x0679, # ARABIC LETTER TTEH + 0x00f5: 0x0686, # ARABIC LETTER TCHEH + 0x00f6: 0x06d5, # ARABIC LETTER AE + 0x00f7: 0x06a4, # ARABIC LETTER VEH + 0x00f8: 0x06af, # ARABIC LETTER GAF + 0x00f9: 0x0688, # ARABIC LETTER DDAL + 0x00fa: 0x0691, # ARABIC LETTER RREH + 0x00fb: 0x007b, # LEFT CURLY BRACKET, right-left + 0x00fc: 0x007c, # VERTICAL LINE, right-left + 0x00fd: 0x007d, # RIGHT CURLY BRACKET, right-left + 0x00fe: 0x0698, # ARABIC LETTER JEH + 0x00ff: 0x06d2, # ARABIC LETTER YEH BARREE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> CONTROL CHARACTER + '\x01' # 0x0001 -> CONTROL CHARACTER + '\x02' # 0x0002 -> CONTROL CHARACTER + '\x03' # 0x0003 -> CONTROL CHARACTER + '\x04' # 0x0004 -> CONTROL CHARACTER + '\x05' # 0x0005 -> CONTROL CHARACTER + '\x06' # 0x0006 -> CONTROL CHARACTER + '\x07' # 0x0007 -> CONTROL CHARACTER + '\x08' # 0x0008 -> CONTROL CHARACTER + '\t' # 0x0009 -> CONTROL CHARACTER + '\n' # 0x000a -> CONTROL CHARACTER + '\x0b' # 0x000b -> CONTROL CHARACTER + '\x0c' # 0x000c -> CONTROL CHARACTER + '\r' # 0x000d -> CONTROL CHARACTER + '\x0e' # 0x000e -> CONTROL CHARACTER + '\x0f' # 0x000f -> CONTROL CHARACTER + '\x10' # 0x0010 -> CONTROL CHARACTER + '\x11' # 0x0011 -> CONTROL CHARACTER + '\x12' # 0x0012 -> CONTROL CHARACTER + '\x13' # 0x0013 -> CONTROL CHARACTER + '\x14' # 0x0014 -> CONTROL CHARACTER + '\x15' # 0x0015 -> CONTROL CHARACTER + '\x16' # 0x0016 -> CONTROL CHARACTER + '\x17' # 0x0017 -> CONTROL CHARACTER + '\x18' # 0x0018 -> CONTROL CHARACTER + '\x19' # 0x0019 -> CONTROL CHARACTER + '\x1a' # 0x001a -> CONTROL CHARACTER + '\x1b' # 0x001b -> CONTROL CHARACTER + '\x1c' # 0x001c -> CONTROL CHARACTER + '\x1d' # 0x001d -> CONTROL CHARACTER + '\x1e' # 0x001e -> CONTROL CHARACTER + '\x1f' # 0x001f -> CONTROL CHARACTER + ' ' # 0x0020 -> SPACE, left-right + '!' # 0x0021 -> EXCLAMATION MARK, left-right + '"' # 0x0022 -> QUOTATION MARK, left-right + '#' # 0x0023 -> NUMBER SIGN, left-right + '$' # 0x0024 -> DOLLAR SIGN, left-right + '%' # 0x0025 -> PERCENT SIGN, left-right + '&' # 0x0026 -> AMPERSAND, left-right + "'" # 0x0027 -> APOSTROPHE, left-right + '(' # 0x0028 -> LEFT PARENTHESIS, left-right + ')' # 0x0029 -> RIGHT PARENTHESIS, left-right + '*' # 0x002a -> ASTERISK, left-right + '+' # 0x002b -> PLUS SIGN, left-right + ',' # 0x002c -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + '-' # 0x002d -> HYPHEN-MINUS, left-right + '.' # 0x002e -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + '/' # 0x002f -> SOLIDUS, left-right + '0' # 0x0030 -> DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE + '2' # 0x0032 -> DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO + '3' # 0x0033 -> DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE + ':' # 0x003a -> COLON, left-right + ';' # 0x003b -> SEMICOLON, left-right + '<' # 0x003c -> LESS-THAN SIGN, left-right + '=' # 0x003d -> EQUALS SIGN, left-right + '>' # 0x003e -> GREATER-THAN SIGN, left-right + '?' # 0x003f -> QUESTION MARK, left-right + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET, left-right + '\\' # 0x005c -> REVERSE SOLIDUS, left-right + ']' # 0x005d -> RIGHT SQUARE BRACKET, left-right + '^' # 0x005e -> CIRCUMFLEX ACCENT, left-right + '_' # 0x005f -> LOW LINE, left-right + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET, left-right + '|' # 0x007c -> VERTICAL LINE, left-right + '}' # 0x007d -> RIGHT CURLY BRACKET, left-right + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> CONTROL CHARACTER + '\xc4' # 0x0080 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xa0' # 0x0081 -> NO-BREAK SPACE, right-left + '\xc7' # 0x0082 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x0083 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x0084 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x0085 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x0086 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x0087 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x0088 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x0089 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x008a -> LATIN SMALL LETTER A WITH DIAERESIS + '\u06ba' # 0x008b -> ARABIC LETTER NOON GHUNNA + '\xab' # 0x008c -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xe7' # 0x008d -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x008e -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x008f -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x0090 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0091 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x0092 -> LATIN SMALL LETTER I WITH ACUTE + '\u2026' # 0x0093 -> HORIZONTAL ELLIPSIS, right-left + '\xee' # 0x0094 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x0095 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x0096 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x0097 -> LATIN SMALL LETTER O WITH ACUTE + '\xbb' # 0x0098 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xf4' # 0x0099 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x009a -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0x009b -> DIVISION SIGN, right-left + '\xfa' # 0x009c -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x009d -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x009e -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x009f -> LATIN SMALL LETTER U WITH DIAERESIS + ' ' # 0x00a0 -> SPACE, right-left + '!' # 0x00a1 -> EXCLAMATION MARK, right-left + '"' # 0x00a2 -> QUOTATION MARK, right-left + '#' # 0x00a3 -> NUMBER SIGN, right-left + '$' # 0x00a4 -> DOLLAR SIGN, right-left + '\u066a' # 0x00a5 -> ARABIC PERCENT SIGN + '&' # 0x00a6 -> AMPERSAND, right-left + "'" # 0x00a7 -> APOSTROPHE, right-left + '(' # 0x00a8 -> LEFT PARENTHESIS, right-left + ')' # 0x00a9 -> RIGHT PARENTHESIS, right-left + '*' # 0x00aa -> ASTERISK, right-left + '+' # 0x00ab -> PLUS SIGN, right-left + '\u060c' # 0x00ac -> ARABIC COMMA + '-' # 0x00ad -> HYPHEN-MINUS, right-left + '.' # 0x00ae -> FULL STOP, right-left + '/' # 0x00af -> SOLIDUS, right-left + '\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO, right-left (need override) + '\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE, right-left (need override) + '\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO, right-left (need override) + '\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE, right-left (need override) + '\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR, right-left (need override) + '\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE, right-left (need override) + '\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX, right-left (need override) + '\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN, right-left (need override) + '\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT, right-left (need override) + '\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE, right-left (need override) + ':' # 0x00ba -> COLON, right-left + '\u061b' # 0x00bb -> ARABIC SEMICOLON + '<' # 0x00bc -> LESS-THAN SIGN, right-left + '=' # 0x00bd -> EQUALS SIGN, right-left + '>' # 0x00be -> GREATER-THAN SIGN, right-left + '\u061f' # 0x00bf -> ARABIC QUESTION MARK + '\u274a' # 0x00c0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + '\u0621' # 0x00c1 -> ARABIC LETTER HAMZA + '\u0622' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0x00c5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0x00c7 -> ARABIC LETTER ALEF + '\u0628' # 0x00c8 -> ARABIC LETTER BEH + '\u0629' # 0x00c9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0x00ca -> ARABIC LETTER TEH + '\u062b' # 0x00cb -> ARABIC LETTER THEH + '\u062c' # 0x00cc -> ARABIC LETTER JEEM + '\u062d' # 0x00cd -> ARABIC LETTER HAH + '\u062e' # 0x00ce -> ARABIC LETTER KHAH + '\u062f' # 0x00cf -> ARABIC LETTER DAL + '\u0630' # 0x00d0 -> ARABIC LETTER THAL + '\u0631' # 0x00d1 -> ARABIC LETTER REH + '\u0632' # 0x00d2 -> ARABIC LETTER ZAIN + '\u0633' # 0x00d3 -> ARABIC LETTER SEEN + '\u0634' # 0x00d4 -> ARABIC LETTER SHEEN + '\u0635' # 0x00d5 -> ARABIC LETTER SAD + '\u0636' # 0x00d6 -> ARABIC LETTER DAD + '\u0637' # 0x00d7 -> ARABIC LETTER TAH + '\u0638' # 0x00d8 -> ARABIC LETTER ZAH + '\u0639' # 0x00d9 -> ARABIC LETTER AIN + '\u063a' # 0x00da -> ARABIC LETTER GHAIN + '[' # 0x00db -> LEFT SQUARE BRACKET, right-left + '\\' # 0x00dc -> REVERSE SOLIDUS, right-left + ']' # 0x00dd -> RIGHT SQUARE BRACKET, right-left + '^' # 0x00de -> CIRCUMFLEX ACCENT, right-left + '_' # 0x00df -> LOW LINE, right-left + '\u0640' # 0x00e0 -> ARABIC TATWEEL + '\u0641' # 0x00e1 -> ARABIC LETTER FEH + '\u0642' # 0x00e2 -> ARABIC LETTER QAF + '\u0643' # 0x00e3 -> ARABIC LETTER KAF + '\u0644' # 0x00e4 -> ARABIC LETTER LAM + '\u0645' # 0x00e5 -> ARABIC LETTER MEEM + '\u0646' # 0x00e6 -> ARABIC LETTER NOON + '\u0647' # 0x00e7 -> ARABIC LETTER HEH + '\u0648' # 0x00e8 -> ARABIC LETTER WAW + '\u0649' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0x00ea -> ARABIC LETTER YEH + '\u064b' # 0x00eb -> ARABIC FATHATAN + '\u064c' # 0x00ec -> ARABIC DAMMATAN + '\u064d' # 0x00ed -> ARABIC KASRATAN + '\u064e' # 0x00ee -> ARABIC FATHA + '\u064f' # 0x00ef -> ARABIC DAMMA + '\u0650' # 0x00f0 -> ARABIC KASRA + '\u0651' # 0x00f1 -> ARABIC SHADDA + '\u0652' # 0x00f2 -> ARABIC SUKUN + '\u067e' # 0x00f3 -> ARABIC LETTER PEH + '\u0679' # 0x00f4 -> ARABIC LETTER TTEH + '\u0686' # 0x00f5 -> ARABIC LETTER TCHEH + '\u06d5' # 0x00f6 -> ARABIC LETTER AE + '\u06a4' # 0x00f7 -> ARABIC LETTER VEH + '\u06af' # 0x00f8 -> ARABIC LETTER GAF + '\u0688' # 0x00f9 -> ARABIC LETTER DDAL + '\u0691' # 0x00fa -> ARABIC LETTER RREH + '{' # 0x00fb -> LEFT CURLY BRACKET, right-left + '|' # 0x00fc -> VERTICAL LINE, right-left + '}' # 0x00fd -> RIGHT CURLY BRACKET, right-left + '\u0698' # 0x00fe -> ARABIC LETTER JEH + '\u06d2' # 0x00ff -> ARABIC LETTER YEH BARREE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # CONTROL CHARACTER + 0x0001: 0x0001, # CONTROL CHARACTER + 0x0002: 0x0002, # CONTROL CHARACTER + 0x0003: 0x0003, # CONTROL CHARACTER + 0x0004: 0x0004, # CONTROL CHARACTER + 0x0005: 0x0005, # CONTROL CHARACTER + 0x0006: 0x0006, # CONTROL CHARACTER + 0x0007: 0x0007, # CONTROL CHARACTER + 0x0008: 0x0008, # CONTROL CHARACTER + 0x0009: 0x0009, # CONTROL CHARACTER + 0x000a: 0x000a, # CONTROL CHARACTER + 0x000b: 0x000b, # CONTROL CHARACTER + 0x000c: 0x000c, # CONTROL CHARACTER + 0x000d: 0x000d, # CONTROL CHARACTER + 0x000e: 0x000e, # CONTROL CHARACTER + 0x000f: 0x000f, # CONTROL CHARACTER + 0x0010: 0x0010, # CONTROL CHARACTER + 0x0011: 0x0011, # CONTROL CHARACTER + 0x0012: 0x0012, # CONTROL CHARACTER + 0x0013: 0x0013, # CONTROL CHARACTER + 0x0014: 0x0014, # CONTROL CHARACTER + 0x0015: 0x0015, # CONTROL CHARACTER + 0x0016: 0x0016, # CONTROL CHARACTER + 0x0017: 0x0017, # CONTROL CHARACTER + 0x0018: 0x0018, # CONTROL CHARACTER + 0x0019: 0x0019, # CONTROL CHARACTER + 0x001a: 0x001a, # CONTROL CHARACTER + 0x001b: 0x001b, # CONTROL CHARACTER + 0x001c: 0x001c, # CONTROL CHARACTER + 0x001d: 0x001d, # CONTROL CHARACTER + 0x001e: 0x001e, # CONTROL CHARACTER + 0x001f: 0x001f, # CONTROL CHARACTER + 0x0020: 0x0020, # SPACE, left-right + 0x0020: 0x00a0, # SPACE, right-left + 0x0021: 0x0021, # EXCLAMATION MARK, left-right + 0x0021: 0x00a1, # EXCLAMATION MARK, right-left + 0x0022: 0x0022, # QUOTATION MARK, left-right + 0x0022: 0x00a2, # QUOTATION MARK, right-left + 0x0023: 0x0023, # NUMBER SIGN, left-right + 0x0023: 0x00a3, # NUMBER SIGN, right-left + 0x0024: 0x0024, # DOLLAR SIGN, left-right + 0x0024: 0x00a4, # DOLLAR SIGN, right-left + 0x0025: 0x0025, # PERCENT SIGN, left-right + 0x0026: 0x0026, # AMPERSAND, left-right + 0x0026: 0x00a6, # AMPERSAND, right-left + 0x0027: 0x0027, # APOSTROPHE, left-right + 0x0027: 0x00a7, # APOSTROPHE, right-left + 0x0028: 0x0028, # LEFT PARENTHESIS, left-right + 0x0028: 0x00a8, # LEFT PARENTHESIS, right-left + 0x0029: 0x0029, # RIGHT PARENTHESIS, left-right + 0x0029: 0x00a9, # RIGHT PARENTHESIS, right-left + 0x002a: 0x002a, # ASTERISK, left-right + 0x002a: 0x00aa, # ASTERISK, right-left + 0x002b: 0x002b, # PLUS SIGN, left-right + 0x002b: 0x00ab, # PLUS SIGN, right-left + 0x002c: 0x002c, # COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + 0x002d: 0x002d, # HYPHEN-MINUS, left-right + 0x002d: 0x00ad, # HYPHEN-MINUS, right-left + 0x002e: 0x002e, # FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + 0x002e: 0x00ae, # FULL STOP, right-left + 0x002f: 0x002f, # SOLIDUS, left-right + 0x002f: 0x00af, # SOLIDUS, right-left + 0x0030: 0x0030, # DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE + 0x003a: 0x003a, # COLON, left-right + 0x003a: 0x00ba, # COLON, right-left + 0x003b: 0x003b, # SEMICOLON, left-right + 0x003c: 0x003c, # LESS-THAN SIGN, left-right + 0x003c: 0x00bc, # LESS-THAN SIGN, right-left + 0x003d: 0x003d, # EQUALS SIGN, left-right + 0x003d: 0x00bd, # EQUALS SIGN, right-left + 0x003e: 0x003e, # GREATER-THAN SIGN, left-right + 0x003e: 0x00be, # GREATER-THAN SIGN, right-left + 0x003f: 0x003f, # QUESTION MARK, left-right + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET, left-right + 0x005b: 0x00db, # LEFT SQUARE BRACKET, right-left + 0x005c: 0x005c, # REVERSE SOLIDUS, left-right + 0x005c: 0x00dc, # REVERSE SOLIDUS, right-left + 0x005d: 0x005d, # RIGHT SQUARE BRACKET, left-right + 0x005d: 0x00dd, # RIGHT SQUARE BRACKET, right-left + 0x005e: 0x005e, # CIRCUMFLEX ACCENT, left-right + 0x005e: 0x00de, # CIRCUMFLEX ACCENT, right-left + 0x005f: 0x005f, # LOW LINE, left-right + 0x005f: 0x00df, # LOW LINE, right-left + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET, left-right + 0x007b: 0x00fb, # LEFT CURLY BRACKET, right-left + 0x007c: 0x007c, # VERTICAL LINE, left-right + 0x007c: 0x00fc, # VERTICAL LINE, right-left + 0x007d: 0x007d, # RIGHT CURLY BRACKET, left-right + 0x007d: 0x00fd, # RIGHT CURLY BRACKET, right-left + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # CONTROL CHARACTER + 0x00a0: 0x0081, # NO-BREAK SPACE, right-left + 0x00ab: 0x008c, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x00bb: 0x0098, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x00c4: 0x0080, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c7: 0x0082, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0083, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x0084, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0085, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00dc: 0x0086, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00e0: 0x0088, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x0087, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0089, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x008a, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e7: 0x008d, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008f, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x008e, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0090, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0091, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x0092, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x0094, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x0095, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x0096, # LATIN SMALL LETTER N WITH TILDE + 0x00f3: 0x0097, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0099, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x009a, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x009b, # DIVISION SIGN, right-left + 0x00f9: 0x009d, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x009c, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x009e, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x009f, # LATIN SMALL LETTER U WITH DIAERESIS + 0x060c: 0x00ac, # ARABIC COMMA + 0x061b: 0x00bb, # ARABIC SEMICOLON + 0x061f: 0x00bf, # ARABIC QUESTION MARK + 0x0621: 0x00c1, # ARABIC LETTER HAMZA + 0x0622: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE + 0x0623: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE + 0x0624: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE + 0x0625: 0x00c5, # ARABIC LETTER ALEF WITH HAMZA BELOW + 0x0626: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE + 0x0627: 0x00c7, # ARABIC LETTER ALEF + 0x0628: 0x00c8, # ARABIC LETTER BEH + 0x0629: 0x00c9, # ARABIC LETTER TEH MARBUTA + 0x062a: 0x00ca, # ARABIC LETTER TEH + 0x062b: 0x00cb, # ARABIC LETTER THEH + 0x062c: 0x00cc, # ARABIC LETTER JEEM + 0x062d: 0x00cd, # ARABIC LETTER HAH + 0x062e: 0x00ce, # ARABIC LETTER KHAH + 0x062f: 0x00cf, # ARABIC LETTER DAL + 0x0630: 0x00d0, # ARABIC LETTER THAL + 0x0631: 0x00d1, # ARABIC LETTER REH + 0x0632: 0x00d2, # ARABIC LETTER ZAIN + 0x0633: 0x00d3, # ARABIC LETTER SEEN + 0x0634: 0x00d4, # ARABIC LETTER SHEEN + 0x0635: 0x00d5, # ARABIC LETTER SAD + 0x0636: 0x00d6, # ARABIC LETTER DAD + 0x0637: 0x00d7, # ARABIC LETTER TAH + 0x0638: 0x00d8, # ARABIC LETTER ZAH + 0x0639: 0x00d9, # ARABIC LETTER AIN + 0x063a: 0x00da, # ARABIC LETTER GHAIN + 0x0640: 0x00e0, # ARABIC TATWEEL + 0x0641: 0x00e1, # ARABIC LETTER FEH + 0x0642: 0x00e2, # ARABIC LETTER QAF + 0x0643: 0x00e3, # ARABIC LETTER KAF + 0x0644: 0x00e4, # ARABIC LETTER LAM + 0x0645: 0x00e5, # ARABIC LETTER MEEM + 0x0646: 0x00e6, # ARABIC LETTER NOON + 0x0647: 0x00e7, # ARABIC LETTER HEH + 0x0648: 0x00e8, # ARABIC LETTER WAW + 0x0649: 0x00e9, # ARABIC LETTER ALEF MAKSURA + 0x064a: 0x00ea, # ARABIC LETTER YEH + 0x064b: 0x00eb, # ARABIC FATHATAN + 0x064c: 0x00ec, # ARABIC DAMMATAN + 0x064d: 0x00ed, # ARABIC KASRATAN + 0x064e: 0x00ee, # ARABIC FATHA + 0x064f: 0x00ef, # ARABIC DAMMA + 0x0650: 0x00f0, # ARABIC KASRA + 0x0651: 0x00f1, # ARABIC SHADDA + 0x0652: 0x00f2, # ARABIC SUKUN + 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO, right-left (need override) + 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE, right-left (need override) + 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO, right-left (need override) + 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE, right-left (need override) + 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR, right-left (need override) + 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE, right-left (need override) + 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX, right-left (need override) + 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) + 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) + 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE, right-left (need override) + 0x066a: 0x00a5, # ARABIC PERCENT SIGN + 0x0679: 0x00f4, # ARABIC LETTER TTEH + 0x067e: 0x00f3, # ARABIC LETTER PEH + 0x0686: 0x00f5, # ARABIC LETTER TCHEH + 0x0688: 0x00f9, # ARABIC LETTER DDAL + 0x0691: 0x00fa, # ARABIC LETTER RREH + 0x0698: 0x00fe, # ARABIC LETTER JEH + 0x06a4: 0x00f7, # ARABIC LETTER VEH + 0x06af: 0x00f8, # ARABIC LETTER GAF + 0x06ba: 0x008b, # ARABIC LETTER NOON GHUNNA + 0x06d2: 0x00ff, # ARABIC LETTER YEH BARREE + 0x06d5: 0x00f6, # ARABIC LETTER AE + 0x2026: 0x0093, # HORIZONTAL ELLIPSIS, right-left + 0x274a: 0x00c0, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left +} diff --git a/Lib/encodings/mac_centeuro.py b/Lib/encodings/mac_centeuro.py new file mode 100644 index 0000000..5785a0e --- /dev/null +++ b/Lib/encodings/mac_centeuro.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_centeuro generated from 'MAPPINGS/VENDORS/APPLE/CENTEURO.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-centeuro', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0100' # 0x81 -> LATIN CAPITAL LETTER A WITH MACRON + '\u0101' # 0x82 -> LATIN SMALL LETTER A WITH MACRON + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0104' # 0x84 -> LATIN CAPITAL LETTER A WITH OGONEK + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\u0105' # 0x88 -> LATIN SMALL LETTER A WITH OGONEK + '\u010c' # 0x89 -> LATIN CAPITAL LETTER C WITH CARON + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\u010d' # 0x8B -> LATIN SMALL LETTER C WITH CARON + '\u0106' # 0x8C -> LATIN CAPITAL LETTER C WITH ACUTE + '\u0107' # 0x8D -> LATIN SMALL LETTER C WITH ACUTE + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE + '\u017a' # 0x90 -> LATIN SMALL LETTER Z WITH ACUTE + '\u010e' # 0x91 -> LATIN CAPITAL LETTER D WITH CARON + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\u010f' # 0x93 -> LATIN SMALL LETTER D WITH CARON + '\u0112' # 0x94 -> LATIN CAPITAL LETTER E WITH MACRON + '\u0113' # 0x95 -> LATIN SMALL LETTER E WITH MACRON + '\u0116' # 0x96 -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\u0117' # 0x98 -> LATIN SMALL LETTER E WITH DOT ABOVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\u011a' # 0x9D -> LATIN CAPITAL LETTER E WITH CARON + '\u011b' # 0x9E -> LATIN SMALL LETTER E WITH CARON + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\u0118' # 0xA2 -> LATIN CAPITAL LETTER E WITH OGONEK + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\u0119' # 0xAB -> LATIN SMALL LETTER E WITH OGONEK + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\u0123' # 0xAE -> LATIN SMALL LETTER G WITH CEDILLA + '\u012e' # 0xAF -> LATIN CAPITAL LETTER I WITH OGONEK + '\u012f' # 0xB0 -> LATIN SMALL LETTER I WITH OGONEK + '\u012a' # 0xB1 -> LATIN CAPITAL LETTER I WITH MACRON + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON + '\u0136' # 0xB5 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u0142' # 0xB8 -> LATIN SMALL LETTER L WITH STROKE + '\u013b' # 0xB9 -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u013c' # 0xBA -> LATIN SMALL LETTER L WITH CEDILLA + '\u013d' # 0xBB -> LATIN CAPITAL LETTER L WITH CARON + '\u013e' # 0xBC -> LATIN SMALL LETTER L WITH CARON + '\u0139' # 0xBD -> LATIN CAPITAL LETTER L WITH ACUTE + '\u013a' # 0xBE -> LATIN SMALL LETTER L WITH ACUTE + '\u0145' # 0xBF -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u0146' # 0xC0 -> LATIN SMALL LETTER N WITH CEDILLA + '\u0143' # 0xC1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0144' # 0xC4 -> LATIN SMALL LETTER N WITH ACUTE + '\u0147' # 0xC5 -> LATIN CAPITAL LETTER N WITH CARON + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\u0148' # 0xCB -> LATIN SMALL LETTER N WITH CARON + '\u0150' # 0xCC -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0151' # 0xCE -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\u014c' # 0xCF -> LATIN CAPITAL LETTER O WITH MACRON + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\u014d' # 0xD8 -> LATIN SMALL LETTER O WITH MACRON + '\u0154' # 0xD9 -> LATIN CAPITAL LETTER R WITH ACUTE + '\u0155' # 0xDA -> LATIN SMALL LETTER R WITH ACUTE + '\u0158' # 0xDB -> LATIN CAPITAL LETTER R WITH CARON + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0159' # 0xDE -> LATIN SMALL LETTER R WITH CARON + '\u0156' # 0xDF -> LATIN CAPITAL LETTER R WITH CEDILLA + '\u0157' # 0xE0 -> LATIN SMALL LETTER R WITH CEDILLA + '\u0160' # 0xE1 -> LATIN CAPITAL LETTER S WITH CARON + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u0161' # 0xE4 -> LATIN SMALL LETTER S WITH CARON + '\u015a' # 0xE5 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u015b' # 0xE6 -> LATIN SMALL LETTER S WITH ACUTE + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\u0164' # 0xE8 -> LATIN CAPITAL LETTER T WITH CARON + '\u0165' # 0xE9 -> LATIN SMALL LETTER T WITH CARON + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\u017d' # 0xEB -> LATIN CAPITAL LETTER Z WITH CARON + '\u017e' # 0xEC -> LATIN SMALL LETTER Z WITH CARON + '\u016a' # 0xED -> LATIN CAPITAL LETTER U WITH MACRON + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u016b' # 0xF0 -> LATIN SMALL LETTER U WITH MACRON + '\u016e' # 0xF1 -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\u016f' # 0xF3 -> LATIN SMALL LETTER U WITH RING ABOVE + '\u0170' # 0xF4 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\u0171' # 0xF5 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\u0172' # 0xF6 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u0173' # 0xF7 -> LATIN SMALL LETTER U WITH OGONEK + '\xdd' # 0xF8 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xfd' # 0xF9 -> LATIN SMALL LETTER Y WITH ACUTE + '\u0137' # 0xFA -> LATIN SMALL LETTER K WITH CEDILLA + '\u017b' # 0xFB -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u0141' # 0xFC -> LATIN CAPITAL LETTER L WITH STROKE + '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u0122' # 0xFE -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_croatian.py b/Lib/encodings/mac_croatian.py new file mode 100644 index 0000000..4a92fe6 --- /dev/null +++ b/Lib/encodings/mac_croatian.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_croatian generated from 'MAPPINGS/VENDORS/APPLE/CROATIAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-croatian', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\u2206' # 0xB4 -> INCREMENT + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\uf8ff' # 0xD8 -> Apple logo + '\xa9' # 0xD9 -> COPYRIGHT SIGN + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\xc6' # 0xDE -> LATIN CAPITAL LETTER AE + '\xbb' # 0xDF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2013' # 0xE0 -> EN DASH + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u03c0' # 0xF9 -> GREEK SMALL LETTER PI + '\xcb' # 0xFA -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\xca' # 0xFD -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xe6' # 0xFE -> LATIN SMALL LETTER AE + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_cyrillic.py b/Lib/encodings/mac_cyrillic.py new file mode 100644 index 0000000..d20272a --- /dev/null +++ b/Lib/encodings/mac_cyrillic.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_cyrillic generated from 'MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-cyrillic', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\u0410' # 0x80 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0x81 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0x82 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0x83 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0x84 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0x85 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0x86 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0x87 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0x88 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0x89 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0x8A -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0x8B -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0x8C -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0x8D -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0x8E -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0x8F -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0x90 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0x91 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0x92 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0x93 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0x94 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0x95 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0x96 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0x97 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0x98 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0x99 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0x9A -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0x9B -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0x9C -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0x9D -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0x9E -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0x9F -> CYRILLIC CAPITAL LETTER YA + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\u0490' # 0xA2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\u0406' # 0xA7 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\u0402' # 0xAB -> CYRILLIC CAPITAL LETTER DJE + '\u0452' # 0xAC -> CYRILLIC SMALL LETTER DJE + '\u2260' # 0xAD -> NOT EQUAL TO + '\u0403' # 0xAE -> CYRILLIC CAPITAL LETTER GJE + '\u0453' # 0xAF -> CYRILLIC SMALL LETTER GJE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\u0456' # 0xB4 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\xb5' # 0xB5 -> MICRO SIGN + '\u0491' # 0xB6 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + '\u0408' # 0xB7 -> CYRILLIC CAPITAL LETTER JE + '\u0404' # 0xB8 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0454' # 0xB9 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0407' # 0xBA -> CYRILLIC CAPITAL LETTER YI + '\u0457' # 0xBB -> CYRILLIC SMALL LETTER YI + '\u0409' # 0xBC -> CYRILLIC CAPITAL LETTER LJE + '\u0459' # 0xBD -> CYRILLIC SMALL LETTER LJE + '\u040a' # 0xBE -> CYRILLIC CAPITAL LETTER NJE + '\u045a' # 0xBF -> CYRILLIC SMALL LETTER NJE + '\u0458' # 0xC0 -> CYRILLIC SMALL LETTER JE + '\u0405' # 0xC1 -> CYRILLIC CAPITAL LETTER DZE + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\u040b' # 0xCB -> CYRILLIC CAPITAL LETTER TSHE + '\u045b' # 0xCC -> CYRILLIC SMALL LETTER TSHE + '\u040c' # 0xCD -> CYRILLIC CAPITAL LETTER KJE + '\u045c' # 0xCE -> CYRILLIC SMALL LETTER KJE + '\u0455' # 0xCF -> CYRILLIC SMALL LETTER DZE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u201e' # 0xD7 -> DOUBLE LOW-9 QUOTATION MARK + '\u040e' # 0xD8 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045e' # 0xD9 -> CYRILLIC SMALL LETTER SHORT U + '\u040f' # 0xDA -> CYRILLIC CAPITAL LETTER DZHE + '\u045f' # 0xDB -> CYRILLIC SMALL LETTER DZHE + '\u2116' # 0xDC -> NUMERO SIGN + '\u0401' # 0xDD -> CYRILLIC CAPITAL LETTER IO + '\u0451' # 0xDE -> CYRILLIC SMALL LETTER IO + '\u044f' # 0xDF -> CYRILLIC SMALL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u20ac' # 0xFF -> EURO SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_farsi.py b/Lib/encodings/mac_farsi.py new file mode 100644 index 0000000..e357d43 --- /dev/null +++ b/Lib/encodings/mac_farsi.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_farsi generated from 'MAPPINGS/VENDORS/APPLE/FARSI.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-farsi', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE, left-right + '!' # 0x21 -> EXCLAMATION MARK, left-right + '"' # 0x22 -> QUOTATION MARK, left-right + '#' # 0x23 -> NUMBER SIGN, left-right + '$' # 0x24 -> DOLLAR SIGN, left-right + '%' # 0x25 -> PERCENT SIGN, left-right + '&' # 0x26 -> AMPERSAND, left-right + "'" # 0x27 -> APOSTROPHE, left-right + '(' # 0x28 -> LEFT PARENTHESIS, left-right + ')' # 0x29 -> RIGHT PARENTHESIS, left-right + '*' # 0x2A -> ASTERISK, left-right + '+' # 0x2B -> PLUS SIGN, left-right + ',' # 0x2C -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + '-' # 0x2D -> HYPHEN-MINUS, left-right + '.' # 0x2E -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + '/' # 0x2F -> SOLIDUS, left-right + '0' # 0x30 -> DIGIT ZERO; in Arabic-script context, displayed as 0x06F0 EXTENDED ARABIC-INDIC DIGIT ZERO + '1' # 0x31 -> DIGIT ONE; in Arabic-script context, displayed as 0x06F1 EXTENDED ARABIC-INDIC DIGIT ONE + '2' # 0x32 -> DIGIT TWO; in Arabic-script context, displayed as 0x06F2 EXTENDED ARABIC-INDIC DIGIT TWO + '3' # 0x33 -> DIGIT THREE; in Arabic-script context, displayed as 0x06F3 EXTENDED ARABIC-INDIC DIGIT THREE + '4' # 0x34 -> DIGIT FOUR; in Arabic-script context, displayed as 0x06F4 EXTENDED ARABIC-INDIC DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE; in Arabic-script context, displayed as 0x06F5 EXTENDED ARABIC-INDIC DIGIT FIVE + '6' # 0x36 -> DIGIT SIX; in Arabic-script context, displayed as 0x06F6 EXTENDED ARABIC-INDIC DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE; in Arabic-script context, displayed as 0x06F9 EXTENDED ARABIC-INDIC DIGIT NINE + ':' # 0x3A -> COLON, left-right + ';' # 0x3B -> SEMICOLON, left-right + '<' # 0x3C -> LESS-THAN SIGN, left-right + '=' # 0x3D -> EQUALS SIGN, left-right + '>' # 0x3E -> GREATER-THAN SIGN, left-right + '?' # 0x3F -> QUESTION MARK, left-right + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET, left-right + '\\' # 0x5C -> REVERSE SOLIDUS, left-right + ']' # 0x5D -> RIGHT SQUARE BRACKET, left-right + '^' # 0x5E -> CIRCUMFLEX ACCENT, left-right + '_' # 0x5F -> LOW LINE, left-right + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET, left-right + '|' # 0x7C -> VERTICAL LINE, left-right + '}' # 0x7D -> RIGHT CURLY BRACKET, left-right + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xa0' # 0x81 -> NO-BREAK SPACE, right-left + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\u06ba' # 0x8B -> ARABIC LETTER NOON GHUNNA + '\xab' # 0x8C -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\u2026' # 0x93 -> HORIZONTAL ELLIPSIS, right-left + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xbb' # 0x98 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0x9B -> DIVISION SIGN, right-left + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + ' ' # 0xA0 -> SPACE, right-left + '!' # 0xA1 -> EXCLAMATION MARK, right-left + '"' # 0xA2 -> QUOTATION MARK, right-left + '#' # 0xA3 -> NUMBER SIGN, right-left + '$' # 0xA4 -> DOLLAR SIGN, right-left + '\u066a' # 0xA5 -> ARABIC PERCENT SIGN + '&' # 0xA6 -> AMPERSAND, right-left + "'" # 0xA7 -> APOSTROPHE, right-left + '(' # 0xA8 -> LEFT PARENTHESIS, right-left + ')' # 0xA9 -> RIGHT PARENTHESIS, right-left + '*' # 0xAA -> ASTERISK, right-left + '+' # 0xAB -> PLUS SIGN, right-left + '\u060c' # 0xAC -> ARABIC COMMA + '-' # 0xAD -> HYPHEN-MINUS, right-left + '.' # 0xAE -> FULL STOP, right-left + '/' # 0xAF -> SOLIDUS, right-left + '\u06f0' # 0xB0 -> EXTENDED ARABIC-INDIC DIGIT ZERO, right-left (need override) + '\u06f1' # 0xB1 -> EXTENDED ARABIC-INDIC DIGIT ONE, right-left (need override) + '\u06f2' # 0xB2 -> EXTENDED ARABIC-INDIC DIGIT TWO, right-left (need override) + '\u06f3' # 0xB3 -> EXTENDED ARABIC-INDIC DIGIT THREE, right-left (need override) + '\u06f4' # 0xB4 -> EXTENDED ARABIC-INDIC DIGIT FOUR, right-left (need override) + '\u06f5' # 0xB5 -> EXTENDED ARABIC-INDIC DIGIT FIVE, right-left (need override) + '\u06f6' # 0xB6 -> EXTENDED ARABIC-INDIC DIGIT SIX, right-left (need override) + '\u06f7' # 0xB7 -> EXTENDED ARABIC-INDIC DIGIT SEVEN, right-left (need override) + '\u06f8' # 0xB8 -> EXTENDED ARABIC-INDIC DIGIT EIGHT, right-left (need override) + '\u06f9' # 0xB9 -> EXTENDED ARABIC-INDIC DIGIT NINE, right-left (need override) + ':' # 0xBA -> COLON, right-left + '\u061b' # 0xBB -> ARABIC SEMICOLON + '<' # 0xBC -> LESS-THAN SIGN, right-left + '=' # 0xBD -> EQUALS SIGN, right-left + '>' # 0xBE -> GREATER-THAN SIGN, right-left + '\u061f' # 0xBF -> ARABIC QUESTION MARK + '\u274a' # 0xC0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + '\u0621' # 0xC1 -> ARABIC LETTER HAMZA + '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0xC7 -> ARABIC LETTER ALEF + '\u0628' # 0xC8 -> ARABIC LETTER BEH + '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xCA -> ARABIC LETTER TEH + '\u062b' # 0xCB -> ARABIC LETTER THEH + '\u062c' # 0xCC -> ARABIC LETTER JEEM + '\u062d' # 0xCD -> ARABIC LETTER HAH + '\u062e' # 0xCE -> ARABIC LETTER KHAH + '\u062f' # 0xCF -> ARABIC LETTER DAL + '\u0630' # 0xD0 -> ARABIC LETTER THAL + '\u0631' # 0xD1 -> ARABIC LETTER REH + '\u0632' # 0xD2 -> ARABIC LETTER ZAIN + '\u0633' # 0xD3 -> ARABIC LETTER SEEN + '\u0634' # 0xD4 -> ARABIC LETTER SHEEN + '\u0635' # 0xD5 -> ARABIC LETTER SAD + '\u0636' # 0xD6 -> ARABIC LETTER DAD + '\u0637' # 0xD7 -> ARABIC LETTER TAH + '\u0638' # 0xD8 -> ARABIC LETTER ZAH + '\u0639' # 0xD9 -> ARABIC LETTER AIN + '\u063a' # 0xDA -> ARABIC LETTER GHAIN + '[' # 0xDB -> LEFT SQUARE BRACKET, right-left + '\\' # 0xDC -> REVERSE SOLIDUS, right-left + ']' # 0xDD -> RIGHT SQUARE BRACKET, right-left + '^' # 0xDE -> CIRCUMFLEX ACCENT, right-left + '_' # 0xDF -> LOW LINE, right-left + '\u0640' # 0xE0 -> ARABIC TATWEEL + '\u0641' # 0xE1 -> ARABIC LETTER FEH + '\u0642' # 0xE2 -> ARABIC LETTER QAF + '\u0643' # 0xE3 -> ARABIC LETTER KAF + '\u0644' # 0xE4 -> ARABIC LETTER LAM + '\u0645' # 0xE5 -> ARABIC LETTER MEEM + '\u0646' # 0xE6 -> ARABIC LETTER NOON + '\u0647' # 0xE7 -> ARABIC LETTER HEH + '\u0648' # 0xE8 -> ARABIC LETTER WAW + '\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xEA -> ARABIC LETTER YEH + '\u064b' # 0xEB -> ARABIC FATHATAN + '\u064c' # 0xEC -> ARABIC DAMMATAN + '\u064d' # 0xED -> ARABIC KASRATAN + '\u064e' # 0xEE -> ARABIC FATHA + '\u064f' # 0xEF -> ARABIC DAMMA + '\u0650' # 0xF0 -> ARABIC KASRA + '\u0651' # 0xF1 -> ARABIC SHADDA + '\u0652' # 0xF2 -> ARABIC SUKUN + '\u067e' # 0xF3 -> ARABIC LETTER PEH + '\u0679' # 0xF4 -> ARABIC LETTER TTEH + '\u0686' # 0xF5 -> ARABIC LETTER TCHEH + '\u06d5' # 0xF6 -> ARABIC LETTER AE + '\u06a4' # 0xF7 -> ARABIC LETTER VEH + '\u06af' # 0xF8 -> ARABIC LETTER GAF + '\u0688' # 0xF9 -> ARABIC LETTER DDAL + '\u0691' # 0xFA -> ARABIC LETTER RREH + '{' # 0xFB -> LEFT CURLY BRACKET, right-left + '|' # 0xFC -> VERTICAL LINE, right-left + '}' # 0xFD -> RIGHT CURLY BRACKET, right-left + '\u0698' # 0xFE -> ARABIC LETTER JEH + '\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_greek.py b/Lib/encodings/mac_greek.py new file mode 100644 index 0000000..d3d0c4f --- /dev/null +++ b/Lib/encodings/mac_greek.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_greek generated from 'MAPPINGS/VENDORS/APPLE/GREEK.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-greek', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xb9' # 0x81 -> SUPERSCRIPT ONE + '\xb2' # 0x82 -> SUPERSCRIPT TWO + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xb3' # 0x84 -> SUPERSCRIPT THREE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0385' # 0x87 -> GREEK DIALYTIKA TONOS + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\u0384' # 0x8B -> GREEK TONOS + '\xa8' # 0x8C -> DIAERESIS + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xa3' # 0x92 -> POUND SIGN + '\u2122' # 0x93 -> TRADE MARK SIGN + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\u2022' # 0x96 -> BULLET + '\xbd' # 0x97 -> VULGAR FRACTION ONE HALF + '\u2030' # 0x98 -> PER MILLE SIGN + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xa6' # 0x9B -> BROKEN BAR + '\u20ac' # 0x9C -> EURO SIGN # before Mac OS 9.2.2, was SOFT HYPHEN + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\u0393' # 0xA1 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0xA2 -> GREEK CAPITAL LETTER DELTA + '\u0398' # 0xA3 -> GREEK CAPITAL LETTER THETA + '\u039b' # 0xA4 -> GREEK CAPITAL LETTER LAMDA + '\u039e' # 0xA5 -> GREEK CAPITAL LETTER XI + '\u03a0' # 0xA6 -> GREEK CAPITAL LETTER PI + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u03a3' # 0xAA -> GREEK CAPITAL LETTER SIGMA + '\u03aa' # 0xAB -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\xa7' # 0xAC -> SECTION SIGN + '\u2260' # 0xAD -> NOT EQUAL TO + '\xb0' # 0xAE -> DEGREE SIGN + '\xb7' # 0xAF -> MIDDLE DOT + '\u0391' # 0xB0 -> GREEK CAPITAL LETTER ALPHA + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\u0392' # 0xB5 -> GREEK CAPITAL LETTER BETA + '\u0395' # 0xB6 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0xB7 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0xB8 -> GREEK CAPITAL LETTER ETA + '\u0399' # 0xB9 -> GREEK CAPITAL LETTER IOTA + '\u039a' # 0xBA -> GREEK CAPITAL LETTER KAPPA + '\u039c' # 0xBB -> GREEK CAPITAL LETTER MU + '\u03a6' # 0xBC -> GREEK CAPITAL LETTER PHI + '\u03ab' # 0xBD -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\u03a8' # 0xBE -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0xBF -> GREEK CAPITAL LETTER OMEGA + '\u03ac' # 0xC0 -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u039d' # 0xC1 -> GREEK CAPITAL LETTER NU + '\xac' # 0xC2 -> NOT SIGN + '\u039f' # 0xC3 -> GREEK CAPITAL LETTER OMICRON + '\u03a1' # 0xC4 -> GREEK CAPITAL LETTER RHO + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u03a4' # 0xC6 -> GREEK CAPITAL LETTER TAU + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\u03a5' # 0xCB -> GREEK CAPITAL LETTER UPSILON + '\u03a7' # 0xCC -> GREEK CAPITAL LETTER CHI + '\u0386' # 0xCD -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\u0388' # 0xCE -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2015' # 0xD1 -> HORIZONTAL BAR + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u0389' # 0xD7 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0xD8 -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\u038c' # 0xD9 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\u038e' # 0xDA -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u03ad' # 0xDB -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xDC -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0xDD -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03cc' # 0xDE -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u038f' # 0xDF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\u03cd' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + '\u03c8' # 0xE3 -> GREEK SMALL LETTER PSI + '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + '\u03c6' # 0xE6 -> GREEK SMALL LETTER PHI + '\u03b3' # 0xE7 -> GREEK SMALL LETTER GAMMA + '\u03b7' # 0xE8 -> GREEK SMALL LETTER ETA + '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + '\u03be' # 0xEA -> GREEK SMALL LETTER XI + '\u03ba' # 0xEB -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0xEC -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0xED -> GREEK SMALL LETTER MU + '\u03bd' # 0xEE -> GREEK SMALL LETTER NU + '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + '\u03ce' # 0xF1 -> GREEK SMALL LETTER OMEGA WITH TONOS + '\u03c1' # 0xF2 -> GREEK SMALL LETTER RHO + '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + '\u03b8' # 0xF5 -> GREEK SMALL LETTER THETA + '\u03c9' # 0xF6 -> GREEK SMALL LETTER OMEGA + '\u03c2' # 0xF7 -> GREEK SMALL LETTER FINAL SIGMA + '\u03c7' # 0xF8 -> GREEK SMALL LETTER CHI + '\u03c5' # 0xF9 -> GREEK SMALL LETTER UPSILON + '\u03b6' # 0xFA -> GREEK SMALL LETTER ZETA + '\u03ca' # 0xFB -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03cb' # 0xFC -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u0390' # 0xFD -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u03b0' # 0xFE -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\xad' # 0xFF -> SOFT HYPHEN # before Mac OS 9.2.2, was undefined +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_iceland.py b/Lib/encodings/mac_iceland.py new file mode 100644 index 0000000..add10f4 --- /dev/null +++ b/Lib/encodings/mac_iceland.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_iceland generated from 'MAPPINGS/VENDORS/APPLE/ICELAND.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-iceland', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\xdd' # 0xA0 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\xe6' # 0xBE -> LATIN SMALL LETTER AE + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\xd0' # 0xDC -> LATIN CAPITAL LETTER ETH + '\xf0' # 0xDD -> LATIN SMALL LETTER ETH + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + '\xfe' # 0xDF -> LATIN SMALL LETTER THORN + '\xfd' # 0xE0 -> LATIN SMALL LETTER Y WITH ACUTE + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_latin2.py b/Lib/encodings/mac_latin2.py new file mode 100644 index 0000000..da9d4b1 --- /dev/null +++ b/Lib/encodings/mac_latin2.py @@ -0,0 +1,312 @@ +""" Python Character Mapping Codec mac_latin2 generated from 'MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT' with gencodec.py. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. +(c) Copyright 2000 Guido van Rossum. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-latin2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0100' # 0x81 -> LATIN CAPITAL LETTER A WITH MACRON + '\u0101' # 0x82 -> LATIN SMALL LETTER A WITH MACRON + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0104' # 0x84 -> LATIN CAPITAL LETTER A WITH OGONEK + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\u0105' # 0x88 -> LATIN SMALL LETTER A WITH OGONEK + '\u010c' # 0x89 -> LATIN CAPITAL LETTER C WITH CARON + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\u010d' # 0x8B -> LATIN SMALL LETTER C WITH CARON + '\u0106' # 0x8C -> LATIN CAPITAL LETTER C WITH ACUTE + '\u0107' # 0x8D -> LATIN SMALL LETTER C WITH ACUTE + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE + '\u017a' # 0x90 -> LATIN SMALL LETTER Z WITH ACUTE + '\u010e' # 0x91 -> LATIN CAPITAL LETTER D WITH CARON + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\u010f' # 0x93 -> LATIN SMALL LETTER D WITH CARON + '\u0112' # 0x94 -> LATIN CAPITAL LETTER E WITH MACRON + '\u0113' # 0x95 -> LATIN SMALL LETTER E WITH MACRON + '\u0116' # 0x96 -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\u0117' # 0x98 -> LATIN SMALL LETTER E WITH DOT ABOVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\u011a' # 0x9D -> LATIN CAPITAL LETTER E WITH CARON + '\u011b' # 0x9E -> LATIN SMALL LETTER E WITH CARON + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\u0118' # 0xA2 -> LATIN CAPITAL LETTER E WITH OGONEK + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\u0119' # 0xAB -> LATIN SMALL LETTER E WITH OGONEK + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\u0123' # 0xAE -> LATIN SMALL LETTER G WITH CEDILLA + '\u012e' # 0xAF -> LATIN CAPITAL LETTER I WITH OGONEK + '\u012f' # 0xB0 -> LATIN SMALL LETTER I WITH OGONEK + '\u012a' # 0xB1 -> LATIN CAPITAL LETTER I WITH MACRON + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON + '\u0136' # 0xB5 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u0142' # 0xB8 -> LATIN SMALL LETTER L WITH STROKE + '\u013b' # 0xB9 -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u013c' # 0xBA -> LATIN SMALL LETTER L WITH CEDILLA + '\u013d' # 0xBB -> LATIN CAPITAL LETTER L WITH CARON + '\u013e' # 0xBC -> LATIN SMALL LETTER L WITH CARON + '\u0139' # 0xBD -> LATIN CAPITAL LETTER L WITH ACUTE + '\u013a' # 0xBE -> LATIN SMALL LETTER L WITH ACUTE + '\u0145' # 0xBF -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u0146' # 0xC0 -> LATIN SMALL LETTER N WITH CEDILLA + '\u0143' # 0xC1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0144' # 0xC4 -> LATIN SMALL LETTER N WITH ACUTE + '\u0147' # 0xC5 -> LATIN CAPITAL LETTER N WITH CARON + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\u0148' # 0xCB -> LATIN SMALL LETTER N WITH CARON + '\u0150' # 0xCC -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0151' # 0xCE -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\u014c' # 0xCF -> LATIN CAPITAL LETTER O WITH MACRON + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\u014d' # 0xD8 -> LATIN SMALL LETTER O WITH MACRON + '\u0154' # 0xD9 -> LATIN CAPITAL LETTER R WITH ACUTE + '\u0155' # 0xDA -> LATIN SMALL LETTER R WITH ACUTE + '\u0158' # 0xDB -> LATIN CAPITAL LETTER R WITH CARON + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0159' # 0xDE -> LATIN SMALL LETTER R WITH CARON + '\u0156' # 0xDF -> LATIN CAPITAL LETTER R WITH CEDILLA + '\u0157' # 0xE0 -> LATIN SMALL LETTER R WITH CEDILLA + '\u0160' # 0xE1 -> LATIN CAPITAL LETTER S WITH CARON + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u0161' # 0xE4 -> LATIN SMALL LETTER S WITH CARON + '\u015a' # 0xE5 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u015b' # 0xE6 -> LATIN SMALL LETTER S WITH ACUTE + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\u0164' # 0xE8 -> LATIN CAPITAL LETTER T WITH CARON + '\u0165' # 0xE9 -> LATIN SMALL LETTER T WITH CARON + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\u017d' # 0xEB -> LATIN CAPITAL LETTER Z WITH CARON + '\u017e' # 0xEC -> LATIN SMALL LETTER Z WITH CARON + '\u016a' # 0xED -> LATIN CAPITAL LETTER U WITH MACRON + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u016b' # 0xF0 -> LATIN SMALL LETTER U WITH MACRON + '\u016e' # 0xF1 -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\u016f' # 0xF3 -> LATIN SMALL LETTER U WITH RING ABOVE + '\u0170' # 0xF4 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\u0171' # 0xF5 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\u0172' # 0xF6 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u0173' # 0xF7 -> LATIN SMALL LETTER U WITH OGONEK + '\xdd' # 0xF8 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xfd' # 0xF9 -> LATIN SMALL LETTER Y WITH ACUTE + '\u0137' # 0xFA -> LATIN SMALL LETTER K WITH CEDILLA + '\u017b' # 0xFB -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u0141' # 0xFC -> LATIN CAPITAL LETTER L WITH STROKE + '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u0122' # 0xFE -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_roman.py b/Lib/encodings/mac_roman.py new file mode 100644 index 0000000..b74b002 --- /dev/null +++ b/Lib/encodings/mac_roman.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_roman generated from 'MAPPINGS/VENDORS/APPLE/ROMAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-roman', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\xe6' # 0xBE -> LATIN SMALL LETTER AE + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufb01' # 0xDE -> LATIN SMALL LIGATURE FI + '\ufb02' # 0xDF -> LATIN SMALL LIGATURE FL + '\u2021' # 0xE0 -> DOUBLE DAGGER + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_romanian.py b/Lib/encodings/mac_romanian.py new file mode 100644 index 0000000..d141b4c --- /dev/null +++ b/Lib/encodings/mac_romanian.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_romanian generated from 'MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-romanian', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\u0102' # 0xAE -> LATIN CAPITAL LETTER A WITH BREVE + '\u0218' # 0xAF -> LATIN CAPITAL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\u0103' # 0xBE -> LATIN SMALL LETTER A WITH BREVE + '\u0219' # 0xBF -> LATIN SMALL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later + '\u021b' # 0xDF -> LATIN SMALL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later + '\u2021' # 0xE0 -> DOUBLE DAGGER + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mac_turkish.py b/Lib/encodings/mac_turkish.py new file mode 100644 index 0000000..044d4cb --- /dev/null +++ b/Lib/encodings/mac_turkish.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_turkish generated from 'MAPPINGS/VENDORS/APPLE/TURKISH.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-turkish', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\xe6' # 0xBE -> LATIN SMALL LETTER AE + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u011e' # 0xDA -> LATIN CAPITAL LETTER G WITH BREVE + '\u011f' # 0xDB -> LATIN SMALL LETTER G WITH BREVE + '\u0130' # 0xDC -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u0131' # 0xDD -> LATIN SMALL LETTER DOTLESS I + '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u015f' # 0xDF -> LATIN SMALL LETTER S WITH CEDILLA + '\u2021' # 0xE0 -> DOUBLE DAGGER + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\uf8a0' # 0xF5 -> undefined1 + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/mbcs.py b/Lib/encodings/mbcs.py new file mode 100644 index 0000000..baf46cb --- /dev/null +++ b/Lib/encodings/mbcs.py @@ -0,0 +1,47 @@ +""" Python 'mbcs' Codec for Windows + + +Cloned by Mark Hammond (mhammond@skippinet.com.au) from ascii.py, +which was written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +# Import them explicitly to cause an ImportError +# on non-Windows systems +from codecs import mbcs_encode, mbcs_decode +# for IncrementalDecoder, IncrementalEncoder, ... +import codecs + +### Codec APIs + +encode = mbcs_encode + +def decode(input, errors='strict'): + return mbcs_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return mbcs_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = mbcs_decode + +class StreamWriter(codecs.StreamWriter): + encode = mbcs_encode + +class StreamReader(codecs.StreamReader): + decode = mbcs_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mbcs', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/oem.py b/Lib/encodings/oem.py new file mode 100644 index 0000000..2c3426b --- /dev/null +++ b/Lib/encodings/oem.py @@ -0,0 +1,41 @@ +""" Python 'oem' Codec for Windows + +""" +# Import them explicitly to cause an ImportError +# on non-Windows systems +from codecs import oem_encode, oem_decode +# for IncrementalDecoder, IncrementalEncoder, ... +import codecs + +### Codec APIs + +encode = oem_encode + +def decode(input, errors='strict'): + return oem_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return oem_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = oem_decode + +class StreamWriter(codecs.StreamWriter): + encode = oem_encode + +class StreamReader(codecs.StreamReader): + decode = oem_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='oem', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/palmos.py b/Lib/encodings/palmos.py new file mode 100644 index 0000000..c506d65 --- /dev/null +++ b/Lib/encodings/palmos.py @@ -0,0 +1,308 @@ +""" Python Character Mapping Codec for PalmOS 3.5. + +Written by Sjoerd Mullender (sjoerd@acm.org); based on iso8859_15.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='palmos', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\x81' # 0x81 -> + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\u2666' # 0x8D -> BLACK DIAMOND SUIT + '\u2663' # 0x8E -> BLACK CLUB SUIT + '\u2665' # 0x8F -> BLACK HEART SUIT + '\u2660' # 0x90 -> BLACK SPADE SUIT + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\x9b' # 0x9B -> + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/ptcp154.py b/Lib/encodings/ptcp154.py new file mode 100644 index 0000000..656b79d --- /dev/null +++ b/Lib/encodings/ptcp154.py @@ -0,0 +1,312 @@ +""" Python Character Mapping Codec generated from 'PTCP154.txt' with gencodec.py. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. +(c) Copyright 2000 Guido van Rossum. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='ptcp154', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE (DEL) + '\u0496' # 0x80 -> CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER + '\u0492' # 0x81 -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\u04ee' # 0x82 -> CYRILLIC CAPITAL LETTER U WITH MACRON + '\u0493' # 0x83 -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u04b6' # 0x86 -> CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + '\u04ae' # 0x87 -> CYRILLIC CAPITAL LETTER STRAIGHT U + '\u04b2' # 0x88 -> CYRILLIC CAPITAL LETTER HA WITH DESCENDER + '\u04af' # 0x89 -> CYRILLIC SMALL LETTER STRAIGHT U + '\u04a0' # 0x8A -> CYRILLIC CAPITAL LETTER BASHKIR KA + '\u04e2' # 0x8B -> CYRILLIC CAPITAL LETTER I WITH MACRON + '\u04a2' # 0x8C -> CYRILLIC CAPITAL LETTER EN WITH DESCENDER + '\u049a' # 0x8D -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u04ba' # 0x8E -> CYRILLIC CAPITAL LETTER SHHA + '\u04b8' # 0x8F -> CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE + '\u0497' # 0x90 -> CYRILLIC SMALL LETTER ZHE WITH DESCENDER + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u04b3' # 0x98 -> CYRILLIC SMALL LETTER HA WITH DESCENDER + '\u04b7' # 0x99 -> CYRILLIC SMALL LETTER CHE WITH DESCENDER + '\u04a1' # 0x9A -> CYRILLIC SMALL LETTER BASHKIR KA + '\u04e3' # 0x9B -> CYRILLIC SMALL LETTER I WITH MACRON + '\u04a3' # 0x9C -> CYRILLIC SMALL LETTER EN WITH DESCENDER + '\u049b' # 0x9D -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u04bb' # 0x9E -> CYRILLIC SMALL LETTER SHHA + '\u04b9' # 0x9F -> CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u040e' # 0xA1 -> CYRILLIC CAPITAL LETTER SHORT U (Byelorussian) + '\u045e' # 0xA2 -> CYRILLIC SMALL LETTER SHORT U (Byelorussian) + '\u0408' # 0xA3 -> CYRILLIC CAPITAL LETTER JE + '\u04e8' # 0xA4 -> CYRILLIC CAPITAL LETTER BARRED O + '\u0498' # 0xA5 -> CYRILLIC CAPITAL LETTER ZE WITH DESCENDER + '\u04b0' # 0xA6 -> CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + '\xa7' # 0xA7 -> SECTION SIGN + '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u04d8' # 0xAA -> CYRILLIC CAPITAL LETTER SCHWA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\u04ef' # 0xAD -> CYRILLIC SMALL LETTER U WITH MACRON + '\xae' # 0xAE -> REGISTERED SIGN + '\u049c' # 0xAF -> CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE + '\xb0' # 0xB0 -> DEGREE SIGN + '\u04b1' # 0xB1 -> CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0499' # 0xB4 -> CYRILLIC SMALL LETTER ZE WITH DESCENDER + '\u04e9' # 0xB5 -> CYRILLIC SMALL LETTER BARRED O + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + '\u2116' # 0xB9 -> NUMERO SIGN + '\u04d9' # 0xBA -> CYRILLIC SMALL LETTER SCHWA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0458' # 0xBC -> CYRILLIC SMALL LETTER JE + '\u04aa' # 0xBD -> CYRILLIC CAPITAL LETTER ES WITH DESCENDER + '\u04ab' # 0xBE -> CYRILLIC SMALL LETTER ES WITH DESCENDER + '\u049d' # 0xBF -> CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE + '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/punycode.py b/Lib/encodings/punycode.py new file mode 100644 index 0000000..66c5101 --- /dev/null +++ b/Lib/encodings/punycode.py @@ -0,0 +1,237 @@ +""" Codec for the Punicode encoding, as specified in RFC 3492 + +Written by Martin v. Löwis. +""" + +import codecs + +##################### Encoding ##################################### + +def segregate(str): + """3.1 Basic code point segregation""" + base = bytearray() + extended = set() + for c in str: + if ord(c) < 128: + base.append(ord(c)) + else: + extended.add(c) + extended = sorted(extended) + return bytes(base), extended + +def selective_len(str, max): + """Return the length of str, considering only characters below max.""" + res = 0 + for c in str: + if ord(c) < max: + res += 1 + return res + +def selective_find(str, char, index, pos): + """Return a pair (index, pos), indicating the next occurrence of + char in str. index is the position of the character considering + only ordinals up to and including char, and pos is the position in + the full string. index/pos is the starting position in the full + string.""" + + l = len(str) + while 1: + pos += 1 + if pos == l: + return (-1, -1) + c = str[pos] + if c == char: + return index+1, pos + elif c < char: + index += 1 + +def insertion_unsort(str, extended): + """3.2 Insertion unsort coding""" + oldchar = 0x80 + result = [] + oldindex = -1 + for c in extended: + index = pos = -1 + char = ord(c) + curlen = selective_len(str, char) + delta = (curlen+1) * (char - oldchar) + while 1: + index,pos = selective_find(str,c,index,pos) + if index == -1: + break + delta += index - oldindex + result.append(delta-1) + oldindex = index + delta = 0 + oldchar = char + + return result + +def T(j, bias): + # Punycode parameters: tmin = 1, tmax = 26, base = 36 + res = 36 * (j + 1) - bias + if res < 1: return 1 + if res > 26: return 26 + return res + +digits = b"abcdefghijklmnopqrstuvwxyz0123456789" +def generate_generalized_integer(N, bias): + """3.3 Generalized variable-length integers""" + result = bytearray() + j = 0 + while 1: + t = T(j, bias) + if N < t: + result.append(digits[N]) + return bytes(result) + result.append(digits[t + ((N - t) % (36 - t))]) + N = (N - t) // (36 - t) + j += 1 + +def adapt(delta, first, numchars): + if first: + delta //= 700 + else: + delta //= 2 + delta += delta // numchars + # ((base - tmin) * tmax) // 2 == 455 + divisions = 0 + while delta > 455: + delta = delta // 35 # base - tmin + divisions += 36 + bias = divisions + (36 * delta // (delta + 38)) + return bias + + +def generate_integers(baselen, deltas): + """3.4 Bias adaptation""" + # Punycode parameters: initial bias = 72, damp = 700, skew = 38 + result = bytearray() + bias = 72 + for points, delta in enumerate(deltas): + s = generate_generalized_integer(delta, bias) + result.extend(s) + bias = adapt(delta, points==0, baselen+points+1) + return bytes(result) + +def punycode_encode(text): + base, extended = segregate(text) + deltas = insertion_unsort(text, extended) + extended = generate_integers(len(base), deltas) + if base: + return base + b"-" + extended + return extended + +##################### Decoding ##################################### + +def decode_generalized_number(extended, extpos, bias, errors): + """3.3 Generalized variable-length integers""" + result = 0 + w = 1 + j = 0 + while 1: + try: + char = ord(extended[extpos]) + except IndexError: + if errors == "strict": + raise UnicodeError("incomplete punicode string") + return extpos + 1, None + extpos += 1 + if 0x41 <= char <= 0x5A: # A-Z + digit = char - 0x41 + elif 0x30 <= char <= 0x39: + digit = char - 22 # 0x30-26 + elif errors == "strict": + raise UnicodeError("Invalid extended code point '%s'" + % extended[extpos]) + else: + return extpos, None + t = T(j, bias) + result += digit * w + if digit < t: + return extpos, result + w = w * (36 - t) + j += 1 + + +def insertion_sort(base, extended, errors): + """3.2 Insertion unsort coding""" + char = 0x80 + pos = -1 + bias = 72 + extpos = 0 + while extpos < len(extended): + newpos, delta = decode_generalized_number(extended, extpos, + bias, errors) + if delta is None: + # There was an error in decoding. We can't continue because + # synchronization is lost. + return base + pos += delta+1 + char += pos // (len(base) + 1) + if char > 0x10FFFF: + if errors == "strict": + raise UnicodeError("Invalid character U+%x" % char) + char = ord('?') + pos = pos % (len(base) + 1) + base = base[:pos] + chr(char) + base[pos:] + bias = adapt(delta, (extpos == 0), len(base)) + extpos = newpos + return base + +def punycode_decode(text, errors): + if isinstance(text, str): + text = text.encode("ascii") + if isinstance(text, memoryview): + text = bytes(text) + pos = text.rfind(b"-") + if pos == -1: + base = "" + extended = str(text, "ascii").upper() + else: + base = str(text[:pos], "ascii", errors) + extended = str(text[pos+1:], "ascii").upper() + return insertion_sort(base, extended, errors) + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + res = punycode_encode(input) + return res, len(input) + + def decode(self, input, errors='strict'): + if errors not in ('strict', 'replace', 'ignore'): + raise UnicodeError("Unsupported error handling "+errors) + res = punycode_decode(input, errors) + return res, len(input) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return punycode_encode(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + if self.errors not in ('strict', 'replace', 'ignore'): + raise UnicodeError("Unsupported error handling "+self.errors) + return punycode_decode(input, self.errors) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='punycode', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/quopri_codec.py b/Lib/encodings/quopri_codec.py new file mode 100644 index 0000000..496cb76 --- /dev/null +++ b/Lib/encodings/quopri_codec.py @@ -0,0 +1,56 @@ +"""Codec for quoted-printable encoding. + +This codec de/encodes from bytes to bytes. +""" + +import codecs +import quopri +from io import BytesIO + +def quopri_encode(input, errors='strict'): + assert errors == 'strict' + f = BytesIO(input) + g = BytesIO() + quopri.encode(f, g, quotetabs=True) + return (g.getvalue(), len(input)) + +def quopri_decode(input, errors='strict'): + assert errors == 'strict' + f = BytesIO(input) + g = BytesIO() + quopri.decode(f, g) + return (g.getvalue(), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return quopri_encode(input, errors) + def decode(self, input, errors='strict'): + return quopri_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return quopri_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return quopri_decode(input, self.errors)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +# encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='quopri', + encode=quopri_encode, + decode=quopri_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=False, + ) diff --git a/Lib/encodings/raw_unicode_escape.py b/Lib/encodings/raw_unicode_escape.py new file mode 100644 index 0000000..2b919b4 --- /dev/null +++ b/Lib/encodings/raw_unicode_escape.py @@ -0,0 +1,45 @@ +""" Python 'raw-unicode-escape' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.raw_unicode_escape_encode + decode = codecs.raw_unicode_escape_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.raw_unicode_escape_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.raw_unicode_escape_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='raw-unicode-escape', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/rot_13.py b/Lib/encodings/rot_13.py new file mode 100644 index 0000000..5627bfb --- /dev/null +++ b/Lib/encodings/rot_13.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +""" Python Character Mapping Codec for ROT13. + +This codec de/encodes from str to str. + +Written by Marc-Andre Lemburg (mal@lemburg.com). +""" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return (str.translate(input, rot13_map), len(input)) + + def decode(self, input, errors='strict'): + return (str.translate(input, rot13_map), len(input)) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return str.translate(input, rot13_map) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return str.translate(input, rot13_map) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='rot-13', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=False, + ) + +### Map + +rot13_map = codecs.make_identity_dict(range(256)) +rot13_map.update({ + 0x0041: 0x004e, + 0x0042: 0x004f, + 0x0043: 0x0050, + 0x0044: 0x0051, + 0x0045: 0x0052, + 0x0046: 0x0053, + 0x0047: 0x0054, + 0x0048: 0x0055, + 0x0049: 0x0056, + 0x004a: 0x0057, + 0x004b: 0x0058, + 0x004c: 0x0059, + 0x004d: 0x005a, + 0x004e: 0x0041, + 0x004f: 0x0042, + 0x0050: 0x0043, + 0x0051: 0x0044, + 0x0052: 0x0045, + 0x0053: 0x0046, + 0x0054: 0x0047, + 0x0055: 0x0048, + 0x0056: 0x0049, + 0x0057: 0x004a, + 0x0058: 0x004b, + 0x0059: 0x004c, + 0x005a: 0x004d, + 0x0061: 0x006e, + 0x0062: 0x006f, + 0x0063: 0x0070, + 0x0064: 0x0071, + 0x0065: 0x0072, + 0x0066: 0x0073, + 0x0067: 0x0074, + 0x0068: 0x0075, + 0x0069: 0x0076, + 0x006a: 0x0077, + 0x006b: 0x0078, + 0x006c: 0x0079, + 0x006d: 0x007a, + 0x006e: 0x0061, + 0x006f: 0x0062, + 0x0070: 0x0063, + 0x0071: 0x0064, + 0x0072: 0x0065, + 0x0073: 0x0066, + 0x0074: 0x0067, + 0x0075: 0x0068, + 0x0076: 0x0069, + 0x0077: 0x006a, + 0x0078: 0x006b, + 0x0079: 0x006c, + 0x007a: 0x006d, +}) + +### Filter API + +def rot13(infile, outfile): + outfile.write(codecs.encode(infile.read(), 'rot-13')) + +if __name__ == '__main__': + import sys + rot13(sys.stdin, sys.stdout) diff --git a/Lib/encodings/shift_jis.py b/Lib/encodings/shift_jis.py new file mode 100644 index 0000000..8338117 --- /dev/null +++ b/Lib/encodings/shift_jis.py @@ -0,0 +1,39 @@ +# +# shift_jis.py: Python Unicode Codec for SHIFT_JIS +# +# Written by Hye-Shik Chang +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('shift_jis') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='shift_jis', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/shift_jis_2004.py b/Lib/encodings/shift_jis_2004.py new file mode 100644 index 0000000..161b1e8 --- /dev/null +++ b/Lib/encodings/shift_jis_2004.py @@ -0,0 +1,39 @@ +# +# shift_jis_2004.py: Python Unicode Codec for SHIFT_JIS_2004 +# +# Written by Hye-Shik Chang +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('shift_jis_2004') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='shift_jis_2004', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/shift_jisx0213.py b/Lib/encodings/shift_jisx0213.py new file mode 100644 index 0000000..cb653f5 --- /dev/null +++ b/Lib/encodings/shift_jisx0213.py @@ -0,0 +1,39 @@ +# +# shift_jisx0213.py: Python Unicode Codec for SHIFT_JISX0213 +# +# Written by Hye-Shik Chang +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('shift_jisx0213') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='shift_jisx0213', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/tis_620.py b/Lib/encodings/tis_620.py new file mode 100644 index 0000000..e288386 --- /dev/null +++ b/Lib/encodings/tis_620.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec tis_620 generated from 'python-mappings/TIS-620.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='tis-620', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\ufffe' + '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + '\u0e0b' # 0xAB -> THAI CHARACTER SO SO + '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + '\u0e0d' # 0xAD -> THAI CHARACTER YO YING + '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + '\u0e19' # 0xB9 -> THAI CHARACTER NO NU + '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + '\u0e1d' # 0xBD -> THAI CHARACTER FO FA + '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + '\u0e21' # 0xC1 -> THAI CHARACTER MO MA + '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + '\u0e24' # 0xC4 -> THAI CHARACTER RU + '\u0e25' # 0xC5 -> THAI CHARACTER LO LING + '\u0e26' # 0xC6 -> THAI CHARACTER LU + '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + '\u0e2d' # 0xCD -> THAI CHARACTER O ANG + '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + '\u0e30' # 0xD0 -> THAI CHARACTER SARA A + '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + '\u0e34' # 0xD4 -> THAI CHARACTER SARA I + '\u0e35' # 0xD5 -> THAI CHARACTER SARA II + '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + '\u0e38' # 0xD8 -> THAI CHARACTER SARA U + '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + '\u0e40' # 0xE0 -> THAI CHARACTER SARA E + '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + '\u0e42' # 0xE2 -> THAI CHARACTER SARA O + '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + '\u0e50' # 0xF0 -> THAI DIGIT ZERO + '\u0e51' # 0xF1 -> THAI DIGIT ONE + '\u0e52' # 0xF2 -> THAI DIGIT TWO + '\u0e53' # 0xF3 -> THAI DIGIT THREE + '\u0e54' # 0xF4 -> THAI DIGIT FOUR + '\u0e55' # 0xF5 -> THAI DIGIT FIVE + '\u0e56' # 0xF6 -> THAI DIGIT SIX + '\u0e57' # 0xF7 -> THAI DIGIT SEVEN + '\u0e58' # 0xF8 -> THAI DIGIT EIGHT + '\u0e59' # 0xF9 -> THAI DIGIT NINE + '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/undefined.py b/Lib/encodings/undefined.py new file mode 100644 index 0000000..4690288 --- /dev/null +++ b/Lib/encodings/undefined.py @@ -0,0 +1,49 @@ +""" Python 'undefined' Codec + + This codec will always raise a ValueError exception when being + used. It is intended for use by the site.py file to switch off + automatic string to Unicode coercion. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + raise UnicodeError("undefined encoding") + + def decode(self,input,errors='strict'): + raise UnicodeError("undefined encoding") + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + raise UnicodeError("undefined encoding") + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + raise UnicodeError("undefined encoding") + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='undefined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/unicode_escape.py b/Lib/encodings/unicode_escape.py new file mode 100644 index 0000000..817f932 --- /dev/null +++ b/Lib/encodings/unicode_escape.py @@ -0,0 +1,45 @@ +""" Python 'unicode-escape' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.unicode_escape_encode + decode = codecs.unicode_escape_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.unicode_escape_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.unicode_escape_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='unicode-escape', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/unicode_internal.py b/Lib/encodings/unicode_internal.py new file mode 100644 index 0000000..df3e775 --- /dev/null +++ b/Lib/encodings/unicode_internal.py @@ -0,0 +1,45 @@ +""" Python 'unicode-internal' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.unicode_internal_encode + decode = codecs.unicode_internal_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.unicode_internal_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.unicode_internal_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='unicode-internal', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/Lib/encodings/utf_16.py b/Lib/encodings/utf_16.py new file mode 100644 index 0000000..c612482 --- /dev/null +++ b/Lib/encodings/utf_16.py @@ -0,0 +1,155 @@ +""" Python 'utf-16' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs, sys + +### Codec APIs + +encode = codecs.utf_16_encode + +def decode(input, errors='strict'): + return codecs.utf_16_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + codecs.IncrementalEncoder.__init__(self, errors) + self.encoder = None + + def encode(self, input, final=False): + if self.encoder is None: + result = codecs.utf_16_encode(input, self.errors)[0] + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_le_encode + else: + self.encoder = codecs.utf_16_be_encode + return result + return self.encoder(input, self.errors)[0] + + def reset(self): + codecs.IncrementalEncoder.reset(self) + self.encoder = None + + def getstate(self): + # state info we return to the caller: + # 0: stream is in natural order for this platform + # 2: endianness hasn't been determined yet + # (we're never writing in unnatural order) + return (2 if self.encoder is None else 0) + + def setstate(self, state): + if state: + self.encoder = None + else: + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_le_encode + else: + self.encoder = codecs.utf_16_be_encode + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def __init__(self, errors='strict'): + codecs.BufferedIncrementalDecoder.__init__(self, errors) + self.decoder = None + + def _buffer_decode(self, input, errors, final): + if self.decoder is None: + (output, consumed, byteorder) = \ + codecs.utf_16_ex_decode(input, errors, 0, final) + if byteorder == -1: + self.decoder = codecs.utf_16_le_decode + elif byteorder == 1: + self.decoder = codecs.utf_16_be_decode + elif consumed >= 2: + raise UnicodeError("UTF-16 stream does not start with BOM") + return (output, consumed) + return self.decoder(input, self.errors, final) + + def reset(self): + codecs.BufferedIncrementalDecoder.reset(self) + self.decoder = None + + def getstate(self): + # additional state info from the base class must be None here, + # as it isn't passed along to the caller + state = codecs.BufferedIncrementalDecoder.getstate(self)[0] + # additional state info we pass to the caller: + # 0: stream is in natural order for this platform + # 1: stream is in unnatural order + # 2: endianness hasn't been determined yet + if self.decoder is None: + return (state, 2) + addstate = int((sys.byteorder == "big") != + (self.decoder is codecs.utf_16_be_decode)) + return (state, addstate) + + def setstate(self, state): + # state[1] will be ignored by BufferedIncrementalDecoder.setstate() + codecs.BufferedIncrementalDecoder.setstate(self, state) + state = state[1] + if state == 0: + self.decoder = (codecs.utf_16_be_decode + if sys.byteorder == "big" + else codecs.utf_16_le_decode) + elif state == 1: + self.decoder = (codecs.utf_16_le_decode + if sys.byteorder == "big" + else codecs.utf_16_be_decode) + else: + self.decoder = None + +class StreamWriter(codecs.StreamWriter): + def __init__(self, stream, errors='strict'): + codecs.StreamWriter.__init__(self, stream, errors) + self.encoder = None + + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None + + def encode(self, input, errors='strict'): + if self.encoder is None: + result = codecs.utf_16_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_le_encode + else: + self.encoder = codecs.utf_16_be_encode + return result + else: + return self.encoder(input, errors) + +class StreamReader(codecs.StreamReader): + + def reset(self): + codecs.StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + (object, consumed, byteorder) = \ + codecs.utf_16_ex_decode(input, errors, 0, False) + if byteorder == -1: + self.decode = codecs.utf_16_le_decode + elif byteorder == 1: + self.decode = codecs.utf_16_be_decode + elif consumed>=2: + raise UnicodeError("UTF-16 stream does not start with BOM") + return (object, consumed) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-16', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_16_be.py b/Lib/encodings/utf_16_be.py new file mode 100644 index 0000000..86b458e --- /dev/null +++ b/Lib/encodings/utf_16_be.py @@ -0,0 +1,42 @@ +""" Python 'utf-16-be' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +encode = codecs.utf_16_be_encode + +def decode(input, errors='strict'): + return codecs.utf_16_be_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_16_be_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_16_be_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_16_be_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_16_be_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-16-be', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_16_le.py b/Lib/encodings/utf_16_le.py new file mode 100644 index 0000000..ec45414 --- /dev/null +++ b/Lib/encodings/utf_16_le.py @@ -0,0 +1,42 @@ +""" Python 'utf-16-le' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +encode = codecs.utf_16_le_encode + +def decode(input, errors='strict'): + return codecs.utf_16_le_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_16_le_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_16_le_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_16_le_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_16_le_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-16-le', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_32.py b/Lib/encodings/utf_32.py new file mode 100644 index 0000000..cdf84d1 --- /dev/null +++ b/Lib/encodings/utf_32.py @@ -0,0 +1,150 @@ +""" +Python 'utf-32' Codec +""" +import codecs, sys + +### Codec APIs + +encode = codecs.utf_32_encode + +def decode(input, errors='strict'): + return codecs.utf_32_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + codecs.IncrementalEncoder.__init__(self, errors) + self.encoder = None + + def encode(self, input, final=False): + if self.encoder is None: + result = codecs.utf_32_encode(input, self.errors)[0] + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_le_encode + else: + self.encoder = codecs.utf_32_be_encode + return result + return self.encoder(input, self.errors)[0] + + def reset(self): + codecs.IncrementalEncoder.reset(self) + self.encoder = None + + def getstate(self): + # state info we return to the caller: + # 0: stream is in natural order for this platform + # 2: endianness hasn't been determined yet + # (we're never writing in unnatural order) + return (2 if self.encoder is None else 0) + + def setstate(self, state): + if state: + self.encoder = None + else: + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_le_encode + else: + self.encoder = codecs.utf_32_be_encode + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def __init__(self, errors='strict'): + codecs.BufferedIncrementalDecoder.__init__(self, errors) + self.decoder = None + + def _buffer_decode(self, input, errors, final): + if self.decoder is None: + (output, consumed, byteorder) = \ + codecs.utf_32_ex_decode(input, errors, 0, final) + if byteorder == -1: + self.decoder = codecs.utf_32_le_decode + elif byteorder == 1: + self.decoder = codecs.utf_32_be_decode + elif consumed >= 4: + raise UnicodeError("UTF-32 stream does not start with BOM") + return (output, consumed) + return self.decoder(input, self.errors, final) + + def reset(self): + codecs.BufferedIncrementalDecoder.reset(self) + self.decoder = None + + def getstate(self): + # additional state info from the base class must be None here, + # as it isn't passed along to the caller + state = codecs.BufferedIncrementalDecoder.getstate(self)[0] + # additional state info we pass to the caller: + # 0: stream is in natural order for this platform + # 1: stream is in unnatural order + # 2: endianness hasn't been determined yet + if self.decoder is None: + return (state, 2) + addstate = int((sys.byteorder == "big") != + (self.decoder is codecs.utf_32_be_decode)) + return (state, addstate) + + def setstate(self, state): + # state[1] will be ignored by BufferedIncrementalDecoder.setstate() + codecs.BufferedIncrementalDecoder.setstate(self, state) + state = state[1] + if state == 0: + self.decoder = (codecs.utf_32_be_decode + if sys.byteorder == "big" + else codecs.utf_32_le_decode) + elif state == 1: + self.decoder = (codecs.utf_32_le_decode + if sys.byteorder == "big" + else codecs.utf_32_be_decode) + else: + self.decoder = None + +class StreamWriter(codecs.StreamWriter): + def __init__(self, stream, errors='strict'): + self.encoder = None + codecs.StreamWriter.__init__(self, stream, errors) + + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None + + def encode(self, input, errors='strict'): + if self.encoder is None: + result = codecs.utf_32_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_le_encode + else: + self.encoder = codecs.utf_32_be_encode + return result + else: + return self.encoder(input, errors) + +class StreamReader(codecs.StreamReader): + + def reset(self): + codecs.StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + (object, consumed, byteorder) = \ + codecs.utf_32_ex_decode(input, errors, 0, False) + if byteorder == -1: + self.decode = codecs.utf_32_le_decode + elif byteorder == 1: + self.decode = codecs.utf_32_be_decode + elif consumed>=4: + raise UnicodeError("UTF-32 stream does not start with BOM") + return (object, consumed) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-32', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_32_be.py b/Lib/encodings/utf_32_be.py new file mode 100644 index 0000000..fe272b5 --- /dev/null +++ b/Lib/encodings/utf_32_be.py @@ -0,0 +1,37 @@ +""" +Python 'utf-32-be' Codec +""" +import codecs + +### Codec APIs + +encode = codecs.utf_32_be_encode + +def decode(input, errors='strict'): + return codecs.utf_32_be_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_32_be_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_32_be_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_32_be_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_32_be_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-32-be', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_32_le.py b/Lib/encodings/utf_32_le.py new file mode 100644 index 0000000..9e48210 --- /dev/null +++ b/Lib/encodings/utf_32_le.py @@ -0,0 +1,37 @@ +""" +Python 'utf-32-le' Codec +""" +import codecs + +### Codec APIs + +encode = codecs.utf_32_le_encode + +def decode(input, errors='strict'): + return codecs.utf_32_le_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_32_le_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_32_le_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_32_le_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_32_le_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-32-le', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_7.py b/Lib/encodings/utf_7.py new file mode 100644 index 0000000..8e0567f --- /dev/null +++ b/Lib/encodings/utf_7.py @@ -0,0 +1,38 @@ +""" Python 'utf-7' Codec + +Written by Brian Quinlan (brian@sweetapp.com). +""" +import codecs + +### Codec APIs + +encode = codecs.utf_7_encode + +def decode(input, errors='strict'): + return codecs.utf_7_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_7_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_7_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_7_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_7_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-7', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_8.py b/Lib/encodings/utf_8.py new file mode 100644 index 0000000..1bf6336 --- /dev/null +++ b/Lib/encodings/utf_8.py @@ -0,0 +1,42 @@ +""" Python 'utf-8' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +encode = codecs.utf_8_encode + +def decode(input, errors='strict'): + return codecs.utf_8_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_8_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_8_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_8_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_8_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-8', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/utf_8_sig.py b/Lib/encodings/utf_8_sig.py new file mode 100644 index 0000000..1bb4792 --- /dev/null +++ b/Lib/encodings/utf_8_sig.py @@ -0,0 +1,130 @@ +""" Python 'utf-8-sig' Codec +This work similar to UTF-8 with the following changes: + +* On encoding/writing a UTF-8 encoded BOM will be prepended/written as the + first three bytes. + +* On decoding/reading if the first three bytes are a UTF-8 encoded BOM, these + bytes will be skipped. +""" +import codecs + +### Codec APIs + +def encode(input, errors='strict'): + return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], + len(input)) + +def decode(input, errors='strict'): + prefix = 0 + if input[:3] == codecs.BOM_UTF8: + input = input[3:] + prefix = 3 + (output, consumed) = codecs.utf_8_decode(input, errors, True) + return (output, consumed+prefix) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + codecs.IncrementalEncoder.__init__(self, errors) + self.first = 1 + + def encode(self, input, final=False): + if self.first: + self.first = 0 + return codecs.BOM_UTF8 + \ + codecs.utf_8_encode(input, self.errors)[0] + else: + return codecs.utf_8_encode(input, self.errors)[0] + + def reset(self): + codecs.IncrementalEncoder.reset(self) + self.first = 1 + + def getstate(self): + return self.first + + def setstate(self, state): + self.first = state + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def __init__(self, errors='strict'): + codecs.BufferedIncrementalDecoder.__init__(self, errors) + self.first = 1 + + def _buffer_decode(self, input, errors, final): + if self.first: + if len(input) < 3: + if codecs.BOM_UTF8.startswith(input): + # not enough data to decide if this really is a BOM + # => try again on the next call + return ("", 0) + else: + self.first = 0 + else: + self.first = 0 + if input[:3] == codecs.BOM_UTF8: + (output, consumed) = \ + codecs.utf_8_decode(input[3:], errors, final) + return (output, consumed+3) + return codecs.utf_8_decode(input, errors, final) + + def reset(self): + codecs.BufferedIncrementalDecoder.reset(self) + self.first = 1 + + def getstate(self): + state = codecs.BufferedIncrementalDecoder.getstate(self) + # state[1] must be 0 here, as it isn't passed along to the caller + return (state[0], self.first) + + def setstate(self, state): + # state[1] will be ignored by BufferedIncrementalDecoder.setstate() + codecs.BufferedIncrementalDecoder.setstate(self, state) + self.first = state[1] + +class StreamWriter(codecs.StreamWriter): + def reset(self): + codecs.StreamWriter.reset(self) + try: + del self.encode + except AttributeError: + pass + + def encode(self, input, errors='strict'): + self.encode = codecs.utf_8_encode + return encode(input, errors) + +class StreamReader(codecs.StreamReader): + def reset(self): + codecs.StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + if len(input) < 3: + if codecs.BOM_UTF8.startswith(input): + # not enough data to decide if this is a BOM + # => try again on the next call + return ("", 0) + elif input[:3] == codecs.BOM_UTF8: + self.decode = codecs.utf_8_decode + (output, consumed) = codecs.utf_8_decode(input[3:],errors) + return (output, consumed+3) + # (else) no BOM present + self.decode = codecs.utf_8_decode + return codecs.utf_8_decode(input, errors) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-8-sig', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py new file mode 100644 index 0000000..2a5728f --- /dev/null +++ b/Lib/encodings/uu_codec.py @@ -0,0 +1,99 @@ +"""Python 'uu_codec' Codec - UU content transfer encoding. + +This codec de/encodes from bytes to bytes. + +Written by Marc-Andre Lemburg (mal@lemburg.com). Some details were +adapted from uu.py which was written by Lance Ellinghouse and +modified by Jack Jansen and Fredrik Lundh. +""" + +import codecs +import binascii +from io import BytesIO + +### Codec APIs + +def uu_encode(input, errors='strict', filename='', mode=0o666): + assert errors == 'strict' + infile = BytesIO(input) + outfile = BytesIO() + read = infile.read + write = outfile.write + + # Encode + write(('begin %o %s\n' % (mode & 0o777, filename)).encode('ascii')) + chunk = read(45) + while chunk: + write(binascii.b2a_uu(chunk)) + chunk = read(45) + write(b' \nend\n') + + return (outfile.getvalue(), len(input)) + +def uu_decode(input, errors='strict'): + assert errors == 'strict' + infile = BytesIO(input) + outfile = BytesIO() + readline = infile.readline + write = outfile.write + + # Find start of encoded data + while 1: + s = readline() + if not s: + raise ValueError('Missing "begin" line in input data') + if s[:5] == b'begin': + break + + # Decode + while True: + s = readline() + if not s or s == b'end\n': + break + try: + data = binascii.a2b_uu(s) + except binascii.Error as v: + # Workaround for broken uuencoders by /Fredrik Lundh + nbytes = (((s[0]-32) & 63) * 4 + 5) // 3 + data = binascii.a2b_uu(s[:nbytes]) + #sys.stderr.write("Warning: %s\n" % str(v)) + write(data) + if not s: + raise ValueError('Truncated input data') + + return (outfile.getvalue(), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return uu_encode(input, errors) + + def decode(self, input, errors='strict'): + return uu_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return uu_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return uu_decode(input, self.errors)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='uu', + encode=uu_encode, + decode=uu_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + _is_text_encoding=False, + ) diff --git a/Lib/encodings/zlib_codec.py b/Lib/encodings/zlib_codec.py new file mode 100644 index 0000000..95908a4 --- /dev/null +++ b/Lib/encodings/zlib_codec.py @@ -0,0 +1,77 @@ +"""Python 'zlib_codec' Codec - zlib compression encoding. + +This codec de/encodes from bytes to bytes. + +Written by Marc-Andre Lemburg (mal@lemburg.com). +""" + +import codecs +import zlib # this codec needs the optional zlib module ! + +### Codec APIs + +def zlib_encode(input, errors='strict'): + assert errors == 'strict' + return (zlib.compress(input), len(input)) + +def zlib_decode(input, errors='strict'): + assert errors == 'strict' + return (zlib.decompress(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return zlib_encode(input, errors) + def decode(self, input, errors='strict'): + return zlib_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.compressobj = zlib.compressobj() + + def encode(self, input, final=False): + if final: + c = self.compressobj.compress(input) + return c + self.compressobj.flush() + else: + return self.compressobj.compress(input) + + def reset(self): + self.compressobj = zlib.compressobj() + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.decompressobj = zlib.decompressobj() + + def decode(self, input, final=False): + if final: + c = self.decompressobj.decompress(input) + return c + self.decompressobj.flush() + else: + return self.decompressobj.decompress(input) + + def reset(self): + self.decompressobj = zlib.decompressobj() + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='zlib', + encode=zlib_encode, + decode=zlib_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + _is_text_encoding=False, + ) diff --git a/Lib/enum.py b/Lib/enum.py new file mode 100644 index 0000000..576de03 --- /dev/null +++ b/Lib/enum.py @@ -0,0 +1,901 @@ +import sys +from types import MappingProxyType, DynamicClassAttribute + +# try _collections first to reduce startup cost +try: + from _collections import OrderedDict +except ImportError: + from collections import OrderedDict + + +__all__ = [ + 'EnumMeta', + 'Enum', 'IntEnum', 'Flag', 'IntFlag', + 'auto', 'unique', + ] + + +def _is_descriptor(obj): + """Returns True if obj is a descriptor, False otherwise.""" + return ( + hasattr(obj, '__get__') or + hasattr(obj, '__set__') or + hasattr(obj, '__delete__')) + + +def _is_dunder(name): + """Returns True if a __dunder__ name, False otherwise.""" + return (name[:2] == name[-2:] == '__' and + name[2:3] != '_' and + name[-3:-2] != '_' and + len(name) > 4) + + +def _is_sunder(name): + """Returns True if a _sunder_ name, False otherwise.""" + return (name[0] == name[-1] == '_' and + name[1:2] != '_' and + name[-2:-1] != '_' and + len(name) > 2) + +def _make_class_unpicklable(cls): + """Make the given class un-picklable.""" + def _break_on_call_reduce(self, proto): + raise TypeError('%r cannot be pickled' % self) + cls.__reduce_ex__ = _break_on_call_reduce + cls.__module__ = '' + +_auto_null = object() +class auto: + """ + Instances are replaced with an appropriate value in Enum class suites. + """ + value = _auto_null + + +class _EnumDict(dict): + """Track enum member order and ensure member names are not reused. + + EnumMeta will use the names found in self._member_names as the + enumeration member names. + + """ + def __init__(self): + super().__init__() + self._member_names = [] + self._last_values = [] + self._ignore = [] + + def __setitem__(self, key, value): + """Changes anything not dundered or not a descriptor. + + If an enum member name is used twice, an error is raised; duplicate + values are not checked for. + + Single underscore (sunder) names are reserved. + + """ + if _is_sunder(key): + if key not in ( + '_order_', '_create_pseudo_member_', + '_generate_next_value_', '_missing_', '_ignore_', + ): + raise ValueError('_names_ are reserved for future Enum use') + if key == '_generate_next_value_': + setattr(self, '_generate_next_value', value) + elif key == '_ignore_': + if isinstance(value, str): + value = value.replace(',',' ').split() + else: + value = list(value) + self._ignore = value + already = set(value) & set(self._member_names) + if already: + raise ValueError('_ignore_ cannot specify already set names: %r' % (already, )) + elif _is_dunder(key): + if key == '__order__': + key = '_order_' + elif key in self._member_names: + # descriptor overwriting an enum? + raise TypeError('Attempted to reuse key: %r' % key) + elif key in self._ignore: + pass + elif not _is_descriptor(value): + if key in self: + # enum overwriting a descriptor? + raise TypeError('%r already defined as: %r' % (key, self[key])) + if isinstance(value, auto): + if value.value == _auto_null: + value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:]) + value = value.value + self._member_names.append(key) + self._last_values.append(value) + super().__setitem__(key, value) + + +# Dummy value for Enum as EnumMeta explicitly checks for it, but of course +# until EnumMeta finishes running the first time the Enum class doesn't exist. +# This is also why there are checks in EnumMeta like `if Enum is not None` +Enum = None + + +class EnumMeta(type): + """Metaclass for Enum""" + @classmethod + def __prepare__(metacls, cls, bases): + # create the namespace dict + enum_dict = _EnumDict() + # inherit previous flags and _generate_next_value_ function + member_type, first_enum = metacls._get_mixins_(bases) + if first_enum is not None: + enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None) + return enum_dict + + def __new__(metacls, cls, bases, classdict): + # an Enum class is final once enumeration items have been defined; it + # cannot be mixed with other types (int, float, etc.) if it has an + # inherited __new__ unless a new __new__ is defined (or the resulting + # class will fail). + # + # remove any keys listed in _ignore_ + classdict.setdefault('_ignore_', []).append('_ignore_') + ignore = classdict['_ignore_'] + for key in ignore: + classdict.pop(key, None) + member_type, first_enum = metacls._get_mixins_(bases) + __new__, save_new, use_args = metacls._find_new_(classdict, member_type, + first_enum) + + # save enum items into separate mapping so they don't get baked into + # the new class + enum_members = {k: classdict[k] for k in classdict._member_names} + for name in classdict._member_names: + del classdict[name] + + # adjust the sunders + _order_ = classdict.pop('_order_', None) + + # check for illegal enum names (any others?) + invalid_names = set(enum_members) & {'mro', } + if invalid_names: + raise ValueError('Invalid enum member name: {0}'.format( + ','.join(invalid_names))) + + # create a default docstring if one has not been provided + if '__doc__' not in classdict: + classdict['__doc__'] = 'An enumeration.' + + # create our new Enum type + enum_class = super().__new__(metacls, cls, bases, classdict) + enum_class._member_names_ = [] # names in definition order + enum_class._member_map_ = OrderedDict() # name->value map + enum_class._member_type_ = member_type + + # save attributes from super classes so we know if we can take + # the shortcut of storing members in the class dict + base_attributes = {a for b in enum_class.mro() for a in b.__dict__} + + # Reverse value->name map for hashable values. + enum_class._value2member_map_ = {} + + # If a custom type is mixed into the Enum, and it does not know how + # to pickle itself, pickle.dumps will succeed but pickle.loads will + # fail. Rather than have the error show up later and possibly far + # from the source, sabotage the pickle protocol for this class so + # that pickle.dumps also fails. + # + # However, if the new class implements its own __reduce_ex__, do not + # sabotage -- it's on them to make sure it works correctly. We use + # __reduce_ex__ instead of any of the others as it is preferred by + # pickle over __reduce__, and it handles all pickle protocols. + if '__reduce_ex__' not in classdict: + if member_type is not object: + methods = ('__getnewargs_ex__', '__getnewargs__', + '__reduce_ex__', '__reduce__') + if not any(m in member_type.__dict__ for m in methods): + _make_class_unpicklable(enum_class) + + # instantiate them, checking for duplicates as we go + # we instantiate first instead of checking for duplicates first in case + # a custom __new__ is doing something funky with the values -- such as + # auto-numbering ;) + for member_name in classdict._member_names: + value = enum_members[member_name] + if not isinstance(value, tuple): + args = (value, ) + else: + args = value + if member_type is tuple: # special case for tuple enums + args = (args, ) # wrap it one more time + if not use_args: + enum_member = __new__(enum_class) + if not hasattr(enum_member, '_value_'): + enum_member._value_ = value + else: + enum_member = __new__(enum_class, *args) + if not hasattr(enum_member, '_value_'): + if member_type is object: + enum_member._value_ = value + else: + enum_member._value_ = member_type(*args) + value = enum_member._value_ + enum_member._name_ = member_name + enum_member.__objclass__ = enum_class + enum_member.__init__(*args) + # If another member with the same value was already defined, the + # new member becomes an alias to the existing one. + for name, canonical_member in enum_class._member_map_.items(): + if canonical_member._value_ == enum_member._value_: + enum_member = canonical_member + break + else: + # Aliases don't appear in member names (only in __members__). + enum_class._member_names_.append(member_name) + # performance boost for any member that would not shadow + # a DynamicClassAttribute + if member_name not in base_attributes: + setattr(enum_class, member_name, enum_member) + # now add to _member_map_ + enum_class._member_map_[member_name] = enum_member + try: + # This may fail if value is not hashable. We can't add the value + # to the map, and by-value lookups for this value will be + # linear. + enum_class._value2member_map_[value] = enum_member + except TypeError: + pass + + # double check that repr and friends are not the mixin's or various + # things break (such as pickle) + for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): + class_method = getattr(enum_class, name) + obj_method = getattr(member_type, name, None) + enum_method = getattr(first_enum, name, None) + if obj_method is not None and obj_method is class_method: + setattr(enum_class, name, enum_method) + + # replace any other __new__ with our own (as long as Enum is not None, + # anyway) -- again, this is to support pickle + if Enum is not None: + # if the user defined their own __new__, save it before it gets + # clobbered in case they subclass later + if save_new: + enum_class.__new_member__ = __new__ + enum_class.__new__ = Enum.__new__ + + # py3 support for definition order (helps keep py2/py3 code in sync) + if _order_ is not None: + if isinstance(_order_, str): + _order_ = _order_.replace(',', ' ').split() + if _order_ != enum_class._member_names_: + raise TypeError('member order does not match _order_') + + return enum_class + + def __bool__(self): + """ + classes/types should always be True. + """ + return True + + def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1): + """Either returns an existing member, or creates a new enum class. + + This method is used both when an enum class is given a value to match + to an enumeration member (i.e. Color(3)) and for the functional API + (i.e. Color = Enum('Color', names='RED GREEN BLUE')). + + When used for the functional API: + + `value` will be the name of the new class. + + `names` should be either a string of white-space/comma delimited names + (values will start at `start`), or an iterator/mapping of name, value pairs. + + `module` should be set to the module this class is being created in; + if it is not set, an attempt to find that module will be made, but if + it fails the class will not be picklable. + + `qualname` should be set to the actual location this class can be found + at in its module; by default it is set to the global scope. If this is + not correct, unpickling will fail in some circumstances. + + `type`, if set, will be mixed in as the first base class. + + """ + if names is None: # simple value lookup + return cls.__new__(cls, value) + # otherwise, functional API: we're creating a new Enum type + return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start) + + def __contains__(cls, member): + if not isinstance(member, Enum): + import warnings + warnings.warn( + "using non-Enums in containment checks will raise " + "TypeError in Python 3.8", + DeprecationWarning, 2) + return isinstance(member, cls) and member._name_ in cls._member_map_ + + def __delattr__(cls, attr): + # nicer error message when someone tries to delete an attribute + # (see issue19025). + if attr in cls._member_map_: + raise AttributeError( + "%s: cannot delete Enum member." % cls.__name__) + super().__delattr__(attr) + + def __dir__(self): + return (['__class__', '__doc__', '__members__', '__module__'] + + self._member_names_) + + def __getattr__(cls, name): + """Return the enum member matching `name` + + We use __getattr__ instead of descriptors or inserting into the enum + class' __dict__ in order to support `name` and `value` being both + properties for enum members (which live in the class' __dict__) and + enum members themselves. + + """ + if _is_dunder(name): + raise AttributeError(name) + try: + return cls._member_map_[name] + except KeyError: + raise AttributeError(name) from None + + def __getitem__(cls, name): + return cls._member_map_[name] + + def __iter__(cls): + return (cls._member_map_[name] for name in cls._member_names_) + + def __len__(cls): + return len(cls._member_names_) + + @property + def __members__(cls): + """Returns a mapping of member name->value. + + This mapping lists all enum members, including aliases. Note that this + is a read-only view of the internal mapping. + + """ + return MappingProxyType(cls._member_map_) + + def __repr__(cls): + return "" % cls.__name__ + + def __reversed__(cls): + return (cls._member_map_[name] for name in reversed(cls._member_names_)) + + def __setattr__(cls, name, value): + """Block attempts to reassign Enum members. + + A simple assignment to the class namespace only changes one of the + several possible ways to get an Enum member from the Enum class, + resulting in an inconsistent Enumeration. + + """ + member_map = cls.__dict__.get('_member_map_', {}) + if name in member_map: + raise AttributeError('Cannot reassign members.') + super().__setattr__(name, value) + + def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1): + """Convenience method to create a new Enum class. + + `names` can be: + + * A string containing member names, separated either with spaces or + commas. Values are incremented by 1 from `start`. + * An iterable of member names. Values are incremented by 1 from `start`. + * An iterable of (member name, value) pairs. + * A mapping of member name -> value pairs. + + """ + metacls = cls.__class__ + bases = (cls, ) if type is None else (type, cls) + _, first_enum = cls._get_mixins_(bases) + classdict = metacls.__prepare__(class_name, bases) + + # special processing needed for names? + if isinstance(names, str): + names = names.replace(',', ' ').split() + if isinstance(names, (tuple, list)) and names and isinstance(names[0], str): + original_names, names = names, [] + last_values = [] + for count, name in enumerate(original_names): + value = first_enum._generate_next_value_(name, start, count, last_values[:]) + last_values.append(value) + names.append((name, value)) + + # Here, names is either an iterable of (name, value) or a mapping. + for item in names: + if isinstance(item, str): + member_name, member_value = item, names[item] + else: + member_name, member_value = item + classdict[member_name] = member_value + enum_class = metacls.__new__(metacls, class_name, bases, classdict) + + # TODO: replace the frame hack if a blessed way to know the calling + # module is ever developed + if module is None: + try: + module = sys._getframe(2).f_globals['__name__'] + except (AttributeError, ValueError) as exc: + pass + if module is None: + _make_class_unpicklable(enum_class) + else: + enum_class.__module__ = module + if qualname is not None: + enum_class.__qualname__ = qualname + + return enum_class + + @staticmethod + def _get_mixins_(bases): + """Returns the type for creating enum members, and the first inherited + enum class. + + bases: the tuple of bases that was given to __new__ + + """ + if not bases: + return object, Enum + + # double check that we are not subclassing a class with existing + # enumeration members; while we're at it, see if any other data + # type has been mixed in so we can use the correct __new__ + member_type = first_enum = None + for base in bases: + if (base is not Enum and + issubclass(base, Enum) and + base._member_names_): + raise TypeError("Cannot extend enumerations") + # base is now the last base in bases + if not issubclass(base, Enum): + raise TypeError("new enumerations must be created as " + "`ClassName([mixin_type,] enum_type)`") + + # get correct mix-in type (either mix-in type of Enum subclass, or + # first base if last base is Enum) + if not issubclass(bases[0], Enum): + member_type = bases[0] # first data type + first_enum = bases[-1] # enum type + else: + for base in bases[0].__mro__: + # most common: (IntEnum, int, Enum, object) + # possible: (, , + # , , + # ) + if issubclass(base, Enum): + if first_enum is None: + first_enum = base + else: + if member_type is None: + member_type = base + + return member_type, first_enum + + @staticmethod + def _find_new_(classdict, member_type, first_enum): + """Returns the __new__ to be used for creating the enum members. + + classdict: the class dictionary given to __new__ + member_type: the data type whose __new__ will be used by default + first_enum: enumeration to check for an overriding __new__ + + """ + # now find the correct __new__, checking to see of one was defined + # by the user; also check earlier enum classes in case a __new__ was + # saved as __new_member__ + __new__ = classdict.get('__new__', None) + + # should __new__ be saved as __new_member__ later? + save_new = __new__ is not None + + if __new__ is None: + # check all possibles for __new_member__ before falling back to + # __new__ + for method in ('__new_member__', '__new__'): + for possible in (member_type, first_enum): + target = getattr(possible, method, None) + if target not in { + None, + None.__new__, + object.__new__, + Enum.__new__, + }: + __new__ = target + break + if __new__ is not None: + break + else: + __new__ = object.__new__ + + # if a non-object.__new__ is used then whatever value/tuple was + # assigned to the enum member name will be passed to __new__ and to the + # new enum member's __init__ + if __new__ is object.__new__: + use_args = False + else: + use_args = True + + return __new__, save_new, use_args + + +class Enum(metaclass=EnumMeta): + """Generic enumeration. + + Derive from this class to define new enumerations. + + """ + def __new__(cls, value): + # all enum instances are actually created during class construction + # without calling this method; this method is called by the metaclass' + # __call__ (i.e. Color(3) ), and by pickle + if type(value) is cls: + # For lookups like Color(Color.RED) + return value + # by-value search for a matching enum member + # see if it's in the reverse mapping (for hashable values) + try: + if value in cls._value2member_map_: + return cls._value2member_map_[value] + except TypeError: + # not there, now do long search -- O(n) behavior + for member in cls._member_map_.values(): + if member._value_ == value: + return member + # still not found -- try _missing_ hook + return cls._missing_(value) + + def _generate_next_value_(name, start, count, last_values): + for last_value in reversed(last_values): + try: + return last_value + 1 + except TypeError: + pass + else: + return start + + @classmethod + def _missing_(cls, value): + raise ValueError("%r is not a valid %s" % (value, cls.__name__)) + + def __repr__(self): + return "<%s.%s: %r>" % ( + self.__class__.__name__, self._name_, self._value_) + + def __str__(self): + return "%s.%s" % (self.__class__.__name__, self._name_) + + def __dir__(self): + added_behavior = [ + m + for cls in self.__class__.mro() + for m in cls.__dict__ + if m[0] != '_' and m not in self._member_map_ + ] + return (['__class__', '__doc__', '__module__'] + added_behavior) + + def __format__(self, format_spec): + # mixed-in Enums should use the mixed-in type's __format__, otherwise + # we can get strange results with the Enum name showing up instead of + # the value + + # pure Enum branch + if self._member_type_ is object: + cls = str + val = str(self) + # mix-in branch + else: + cls = self._member_type_ + val = self._value_ + return cls.__format__(val, format_spec) + + def __hash__(self): + return hash(self._name_) + + def __reduce_ex__(self, proto): + return self.__class__, (self._value_, ) + + # DynamicClassAttribute is used to provide access to the `name` and + # `value` properties of enum members while keeping some measure of + # protection from modification, while still allowing for an enumeration + # to have members named `name` and `value`. This works because enumeration + # members are not set directly on the enum class -- __getattr__ is + # used to look them up. + + @DynamicClassAttribute + def name(self): + """The name of the Enum member.""" + return self._name_ + + @DynamicClassAttribute + def value(self): + """The value of the Enum member.""" + return self._value_ + + @classmethod + def _convert(cls, name, module, filter, source=None): + """ + Create a new Enum subclass that replaces a collection of global constants + """ + # convert all constants from source (or module) that pass filter() to + # a new Enum called name, and export the enum and its members back to + # module; + # also, replace the __reduce_ex__ method so unpickling works in + # previous Python versions + module_globals = vars(sys.modules[module]) + if source: + source = vars(source) + else: + source = module_globals + # We use an OrderedDict of sorted source keys so that the + # _value2member_map is populated in the same order every time + # for a consistent reverse mapping of number to name when there + # are multiple names for the same number rather than varying + # between runs due to hash randomization of the module dictionary. + members = [ + (name, source[name]) + for name in source.keys() + if filter(name)] + try: + # sort by value + members.sort(key=lambda t: (t[1], t[0])) + except TypeError: + # unless some values aren't comparable, in which case sort by name + members.sort(key=lambda t: t[0]) + cls = cls(name, members, module=module) + cls.__reduce_ex__ = _reduce_ex_by_name + module_globals.update(cls.__members__) + module_globals[name] = cls + return cls + + +class IntEnum(int, Enum): + """Enum where members are also (and must be) ints""" + + +def _reduce_ex_by_name(self, proto): + return self.name + +class Flag(Enum): + """Support for flags""" + + def _generate_next_value_(name, start, count, last_values): + """ + Generate the next value when not given. + + name: the name of the member + start: the initital start value or None + count: the number of existing members + last_value: the last value assigned or None + """ + if not count: + return start if start is not None else 1 + for last_value in reversed(last_values): + try: + high_bit = _high_bit(last_value) + break + except Exception: + raise TypeError('Invalid Flag value: %r' % last_value) from None + return 2 ** (high_bit+1) + + @classmethod + def _missing_(cls, value): + original_value = value + if value < 0: + value = ~value + possible_member = cls._create_pseudo_member_(value) + if original_value < 0: + possible_member = ~possible_member + return possible_member + + @classmethod + def _create_pseudo_member_(cls, value): + """ + Create a composite member iff value contains only members. + """ + pseudo_member = cls._value2member_map_.get(value, None) + if pseudo_member is None: + # verify all bits are accounted for + _, extra_flags = _decompose(cls, value) + if extra_flags: + raise ValueError("%r is not a valid %s" % (value, cls.__name__)) + # construct a singleton enum pseudo-member + pseudo_member = object.__new__(cls) + pseudo_member._name_ = None + pseudo_member._value_ = value + # use setdefault in case another thread already created a composite + # with this value + pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member) + return pseudo_member + + def __contains__(self, other): + if not isinstance(other, self.__class__): + import warnings + warnings.warn( + "using non-Flags in containment checks will raise " + "TypeError in Python 3.8", + DeprecationWarning, 2) + return False + return other._value_ & self._value_ == other._value_ + + def __repr__(self): + cls = self.__class__ + if self._name_ is not None: + return '<%s.%s: %r>' % (cls.__name__, self._name_, self._value_) + members, uncovered = _decompose(cls, self._value_) + return '<%s.%s: %r>' % ( + cls.__name__, + '|'.join([str(m._name_ or m._value_) for m in members]), + self._value_, + ) + + def __str__(self): + cls = self.__class__ + if self._name_ is not None: + return '%s.%s' % (cls.__name__, self._name_) + members, uncovered = _decompose(cls, self._value_) + if len(members) == 1 and members[0]._name_ is None: + return '%s.%r' % (cls.__name__, members[0]._value_) + else: + return '%s.%s' % ( + cls.__name__, + '|'.join([str(m._name_ or m._value_) for m in members]), + ) + + def __bool__(self): + return bool(self._value_) + + def __or__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.__class__(self._value_ | other._value_) + + def __and__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.__class__(self._value_ & other._value_) + + def __xor__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.__class__(self._value_ ^ other._value_) + + def __invert__(self): + members, uncovered = _decompose(self.__class__, self._value_) + inverted = self.__class__(0) + for m in self.__class__: + if m not in members and not (m._value_ & self._value_): + inverted = inverted | m + return self.__class__(inverted) + + +class IntFlag(int, Flag): + """Support for integer-based Flags""" + + @classmethod + def _missing_(cls, value): + if not isinstance(value, int): + raise ValueError("%r is not a valid %s" % (value, cls.__name__)) + new_member = cls._create_pseudo_member_(value) + return new_member + + @classmethod + def _create_pseudo_member_(cls, value): + pseudo_member = cls._value2member_map_.get(value, None) + if pseudo_member is None: + need_to_create = [value] + # get unaccounted for bits + _, extra_flags = _decompose(cls, value) + # timer = 10 + while extra_flags: + # timer -= 1 + bit = _high_bit(extra_flags) + flag_value = 2 ** bit + if (flag_value not in cls._value2member_map_ and + flag_value not in need_to_create + ): + need_to_create.append(flag_value) + if extra_flags == -flag_value: + extra_flags = 0 + else: + extra_flags ^= flag_value + for value in reversed(need_to_create): + # construct singleton pseudo-members + pseudo_member = int.__new__(cls, value) + pseudo_member._name_ = None + pseudo_member._value_ = value + # use setdefault in case another thread already created a composite + # with this value + pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member) + return pseudo_member + + def __or__(self, other): + if not isinstance(other, (self.__class__, int)): + return NotImplemented + result = self.__class__(self._value_ | self.__class__(other)._value_) + return result + + def __and__(self, other): + if not isinstance(other, (self.__class__, int)): + return NotImplemented + return self.__class__(self._value_ & self.__class__(other)._value_) + + def __xor__(self, other): + if not isinstance(other, (self.__class__, int)): + return NotImplemented + return self.__class__(self._value_ ^ self.__class__(other)._value_) + + __ror__ = __or__ + __rand__ = __and__ + __rxor__ = __xor__ + + def __invert__(self): + result = self.__class__(~self._value_) + return result + + +def _high_bit(value): + """returns index of highest bit, or -1 if value is zero or negative""" + return value.bit_length() - 1 + +def unique(enumeration): + """Class decorator for enumerations ensuring unique member values.""" + duplicates = [] + for name, member in enumeration.__members__.items(): + if name != member.name: + duplicates.append((name, member.name)) + if duplicates: + alias_details = ', '.join( + ["%s -> %s" % (alias, name) for (alias, name) in duplicates]) + raise ValueError('duplicate values found in %r: %s' % + (enumeration, alias_details)) + return enumeration + +def _decompose(flag, value): + """Extract all members from the value.""" + # _decompose is only called if the value is not named + not_covered = value + negative = value < 0 + # issue29167: wrap accesses to _value2member_map_ in a list to avoid race + # conditions between iterating over it and having more pseudo- + # members added to it + if negative: + # only check for named flags + flags_to_check = [ + (m, v) + for v, m in list(flag._value2member_map_.items()) + if m.name is not None + ] + else: + # check for named flags and powers-of-two flags + flags_to_check = [ + (m, v) + for v, m in list(flag._value2member_map_.items()) + if m.name is not None or _power_of_two(v) + ] + members = [] + for member, member_value in flags_to_check: + if member_value and member_value & value == member_value: + members.append(member) + not_covered &= ~member_value + if not members and value in flag._value2member_map_: + members.append(flag._value2member_map_[value]) + members.sort(key=lambda m: m._value_, reverse=True) + if len(members) > 1 and members[0].value == value: + # we have the breakdown, don't need the value member itself + members.pop(0) + return members, not_covered + +def _power_of_two(value): + if value < 1: + return False + return value == 2 ** _high_bit(value) diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py new file mode 100644 index 0000000..b98e641 --- /dev/null +++ b/Lib/fnmatch.py @@ -0,0 +1,128 @@ +"""Filename matching with shell patterns. + +fnmatch(FILENAME, PATTERN) matches according to the local convention. +fnmatchcase(FILENAME, PATTERN) always takes case in account. + +The functions operate by translating the pattern into a regular +expression. They cache the compiled regular expressions for speed. + +The function translate(PATTERN) returns a regular expression +corresponding to PATTERN. (It does not compile it.) +""" +import os +import posixpath +import re +import functools + +__all__ = ["filter", "fnmatch", "fnmatchcase", "translate"] + +def fnmatch(name, pat): + """Test whether FILENAME matches PATTERN. + + Patterns are Unix shell style: + + * matches everything + ? matches any single character + [seq] matches any character in seq + [!seq] matches any char not in seq + + An initial period in FILENAME is not special. + Both FILENAME and PATTERN are first case-normalized + if the operating system requires it. + If you don't want this, use fnmatchcase(FILENAME, PATTERN). + """ + name = os.path.normcase(name) + pat = os.path.normcase(pat) + return fnmatchcase(name, pat) + +@functools.lru_cache(maxsize=256, typed=True) +def _compile_pattern(pat): + if isinstance(pat, bytes): + pat_str = str(pat, 'ISO-8859-1') + res_str = translate(pat_str) + res = bytes(res_str, 'ISO-8859-1') + else: + res = translate(pat) + return re.compile(res).match + +def filter(names, pat): + """Return the subset of the list NAMES that match PAT.""" + result = [] + pat = os.path.normcase(pat) + match = _compile_pattern(pat) + if os.path is posixpath: + # normcase on posix is NOP. Optimize it away from the loop. + for name in names: + if match(name): + result.append(name) + else: + for name in names: + if match(os.path.normcase(name)): + result.append(name) + return result + +def fnmatchcase(name, pat): + """Test whether FILENAME matches PATTERN, including case. + + This is a version of fnmatch() which doesn't case-normalize + its arguments. + """ + match = _compile_pattern(pat) + return match(name) is not None + + +def translate(pat): + """Translate a shell PATTERN to a regular expression. + + There is no way to quote meta-characters. + """ + + i, n = 0, len(pat) + res = '' + while i < n: + c = pat[i] + i = i+1 + if c == '*': + res = res + '.*' + elif c == '?': + res = res + '.' + elif c == '[': + j = i + if j < n and pat[j] == '!': + j = j+1 + if j < n and pat[j] == ']': + j = j+1 + while j < n and pat[j] != ']': + j = j+1 + if j >= n: + res = res + '\\[' + else: + stuff = pat[i:j] + if '--' not in stuff: + stuff = stuff.replace('\\', r'\\') + else: + chunks = [] + k = i+2 if pat[i] == '!' else i+1 + while True: + k = pat.find('-', k, j) + if k < 0: + break + chunks.append(pat[i:k]) + i = k+1 + k = k+3 + chunks.append(pat[i:j]) + # Escape backslashes and hyphens for set difference (--). + # Hyphens that create ranges shouldn't be escaped. + stuff = '-'.join(s.replace('\\', r'\\').replace('-', r'\-') + for s in chunks) + # Escape set operations (&&, ~~ and ||). + stuff = re.sub(r'([&~|])', r'\\\1', stuff) + i = j+1 + if stuff[0] == '!': + stuff = '^' + stuff[1:] + elif stuff[0] in ('^', '['): + stuff = '\\' + stuff + res = '%s[%s]' % (res, stuff) + else: + res = res + re.escape(c) + return r'(?s:%s)\Z' % res diff --git a/Lib/functools.py b/Lib/functools.py new file mode 100644 index 0000000..c8b79c2 --- /dev/null +++ b/Lib/functools.py @@ -0,0 +1,828 @@ +"""functools.py - Tools for working with functions and callable objects +""" +# Python module wrapper for _functools C module +# to allow utilities written in Python to be added +# to the functools module. +# Written by Nick Coghlan , +# Raymond Hettinger , +# and Åukasz Langa . +# Copyright (C) 2006-2013 Python Software Foundation. +# See C source code for _functools credits/copyright + +__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', + 'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial', + 'partialmethod', 'singledispatch'] + +try: + from _functools import reduce +except ImportError: + pass +from abc import get_cache_token +from collections import namedtuple +# import types, weakref # Deferred to single_dispatch() +from reprlib import recursive_repr +from _thread import RLock + + +################################################################################ +### update_wrapper() and wraps() decorator +################################################################################ + +# update_wrapper() and wraps() are tools to help write +# wrapper functions that can handle naive introspection + +WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__', + '__annotations__') +WRAPPER_UPDATES = ('__dict__',) +def update_wrapper(wrapper, + wrapped, + assigned = WRAPPER_ASSIGNMENTS, + updated = WRAPPER_UPDATES): + """Update a wrapper function to look like the wrapped function + + wrapper is the function to be updated + wrapped is the original function + assigned is a tuple naming the attributes assigned directly + from the wrapped function to the wrapper function (defaults to + functools.WRAPPER_ASSIGNMENTS) + updated is a tuple naming the attributes of the wrapper that + are updated with the corresponding attribute from the wrapped + function (defaults to functools.WRAPPER_UPDATES) + """ + for attr in assigned: + try: + value = getattr(wrapped, attr) + except AttributeError: + pass + else: + setattr(wrapper, attr, value) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + # Issue #17482: set __wrapped__ last so we don't inadvertently copy it + # from the wrapped function when updating __dict__ + wrapper.__wrapped__ = wrapped + # Return the wrapper so this can be used as a decorator via partial() + return wrapper + +def wraps(wrapped, + assigned = WRAPPER_ASSIGNMENTS, + updated = WRAPPER_UPDATES): + """Decorator factory to apply update_wrapper() to a wrapper function + + Returns a decorator that invokes update_wrapper() with the decorated + function as the wrapper argument and the arguments to wraps() as the + remaining arguments. Default arguments are as for update_wrapper(). + This is a convenience function to simplify applying partial() to + update_wrapper(). + """ + return partial(update_wrapper, wrapped=wrapped, + assigned=assigned, updated=updated) + + +################################################################################ +### total_ordering class decorator +################################################################################ + +# The total ordering functions all invoke the root magic method directly +# rather than using the corresponding operator. This avoids possible +# infinite recursion that could occur when the operator dispatch logic +# detects a NotImplemented result and then calls a reflected method. + +def _gt_from_lt(self, other, NotImplemented=NotImplemented): + 'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).' + op_result = self.__lt__(other) + if op_result is NotImplemented: + return op_result + return not op_result and self != other + +def _le_from_lt(self, other, NotImplemented=NotImplemented): + 'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).' + op_result = self.__lt__(other) + return op_result or self == other + +def _ge_from_lt(self, other, NotImplemented=NotImplemented): + 'Return a >= b. Computed by @total_ordering from (not a < b).' + op_result = self.__lt__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +def _ge_from_le(self, other, NotImplemented=NotImplemented): + 'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).' + op_result = self.__le__(other) + if op_result is NotImplemented: + return op_result + return not op_result or self == other + +def _lt_from_le(self, other, NotImplemented=NotImplemented): + 'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).' + op_result = self.__le__(other) + if op_result is NotImplemented: + return op_result + return op_result and self != other + +def _gt_from_le(self, other, NotImplemented=NotImplemented): + 'Return a > b. Computed by @total_ordering from (not a <= b).' + op_result = self.__le__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +def _lt_from_gt(self, other, NotImplemented=NotImplemented): + 'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).' + op_result = self.__gt__(other) + if op_result is NotImplemented: + return op_result + return not op_result and self != other + +def _ge_from_gt(self, other, NotImplemented=NotImplemented): + 'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).' + op_result = self.__gt__(other) + return op_result or self == other + +def _le_from_gt(self, other, NotImplemented=NotImplemented): + 'Return a <= b. Computed by @total_ordering from (not a > b).' + op_result = self.__gt__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +def _le_from_ge(self, other, NotImplemented=NotImplemented): + 'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).' + op_result = self.__ge__(other) + if op_result is NotImplemented: + return op_result + return not op_result or self == other + +def _gt_from_ge(self, other, NotImplemented=NotImplemented): + 'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).' + op_result = self.__ge__(other) + if op_result is NotImplemented: + return op_result + return op_result and self != other + +def _lt_from_ge(self, other, NotImplemented=NotImplemented): + 'Return a < b. Computed by @total_ordering from (not a >= b).' + op_result = self.__ge__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +_convert = { + '__lt__': [('__gt__', _gt_from_lt), + ('__le__', _le_from_lt), + ('__ge__', _ge_from_lt)], + '__le__': [('__ge__', _ge_from_le), + ('__lt__', _lt_from_le), + ('__gt__', _gt_from_le)], + '__gt__': [('__lt__', _lt_from_gt), + ('__ge__', _ge_from_gt), + ('__le__', _le_from_gt)], + '__ge__': [('__le__', _le_from_ge), + ('__gt__', _gt_from_ge), + ('__lt__', _lt_from_ge)] +} + +def total_ordering(cls): + """Class decorator that fills in missing ordering methods""" + # Find user-defined comparisons (not those inherited from object). + roots = {op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)} + if not roots: + raise ValueError('must define at least one ordering operation: < > <= >=') + root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__ + for opname, opfunc in _convert[root]: + if opname not in roots: + opfunc.__name__ = opname + setattr(cls, opname, opfunc) + return cls + + +################################################################################ +### cmp_to_key() function converter +################################################################################ + +def cmp_to_key(mycmp): + """Convert a cmp= function into a key= function""" + class K(object): + __slots__ = ['obj'] + def __init__(self, obj): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + def __le__(self, other): + return mycmp(self.obj, other.obj) <= 0 + def __ge__(self, other): + return mycmp(self.obj, other.obj) >= 0 + __hash__ = None + return K + +try: + from _functools import cmp_to_key +except ImportError: + pass + + +################################################################################ +### partial() argument application +################################################################################ + +# Purely functional, no descriptor behaviour +class partial: + """New function with partial application of the given arguments + and keywords. + """ + + __slots__ = "func", "args", "keywords", "__dict__", "__weakref__" + + def __new__(*args, **keywords): + if not args: + raise TypeError("descriptor '__new__' of partial needs an argument") + if len(args) < 2: + raise TypeError("type 'partial' takes at least one argument") + cls, func, *args = args + if not callable(func): + raise TypeError("the first argument must be callable") + args = tuple(args) + + if hasattr(func, "func"): + args = func.args + args + tmpkw = func.keywords.copy() + tmpkw.update(keywords) + keywords = tmpkw + del tmpkw + func = func.func + + self = super(partial, cls).__new__(cls) + + self.func = func + self.args = args + self.keywords = keywords + return self + + def __call__(*args, **keywords): + if not args: + raise TypeError("descriptor '__call__' of partial needs an argument") + self, *args = args + newkeywords = self.keywords.copy() + newkeywords.update(keywords) + return self.func(*self.args, *args, **newkeywords) + + @recursive_repr() + def __repr__(self): + qualname = type(self).__qualname__ + args = [repr(self.func)] + args.extend(repr(x) for x in self.args) + args.extend(f"{k}={v!r}" for (k, v) in self.keywords.items()) + if type(self).__module__ == "functools": + return f"functools.{qualname}({', '.join(args)})" + return f"{qualname}({', '.join(args)})" + + def __reduce__(self): + return type(self), (self.func,), (self.func, self.args, + self.keywords or None, self.__dict__ or None) + + def __setstate__(self, state): + if not isinstance(state, tuple): + raise TypeError("argument to __setstate__ must be a tuple") + if len(state) != 4: + raise TypeError(f"expected 4 items in state, got {len(state)}") + func, args, kwds, namespace = state + if (not callable(func) or not isinstance(args, tuple) or + (kwds is not None and not isinstance(kwds, dict)) or + (namespace is not None and not isinstance(namespace, dict))): + raise TypeError("invalid partial state") + + args = tuple(args) # just in case it's a subclass + if kwds is None: + kwds = {} + elif type(kwds) is not dict: # XXX does it need to be *exactly* dict? + kwds = dict(kwds) + if namespace is None: + namespace = {} + + self.__dict__ = namespace + self.func = func + self.args = args + self.keywords = kwds + +try: + from _functools import partial +except ImportError: + pass + +# Descriptor version +class partialmethod(object): + """Method descriptor with partial application of the given arguments + and keywords. + + Supports wrapping existing descriptors and handles non-descriptor + callables as instance methods. + """ + + def __init__(self, func, *args, **keywords): + if not callable(func) and not hasattr(func, "__get__"): + raise TypeError("{!r} is not callable or a descriptor" + .format(func)) + + # func could be a descriptor like classmethod which isn't callable, + # so we can't inherit from partial (it verifies func is callable) + if isinstance(func, partialmethod): + # flattening is mandatory in order to place cls/self before all + # other arguments + # it's also more efficient since only one function will be called + self.func = func.func + self.args = func.args + args + self.keywords = func.keywords.copy() + self.keywords.update(keywords) + else: + self.func = func + self.args = args + self.keywords = keywords + + def __repr__(self): + args = ", ".join(map(repr, self.args)) + keywords = ", ".join("{}={!r}".format(k, v) + for k, v in self.keywords.items()) + format_string = "{module}.{cls}({func}, {args}, {keywords})" + return format_string.format(module=self.__class__.__module__, + cls=self.__class__.__qualname__, + func=self.func, + args=args, + keywords=keywords) + + def _make_unbound_method(self): + def _method(*args, **keywords): + call_keywords = self.keywords.copy() + call_keywords.update(keywords) + cls_or_self, *rest = args + call_args = (cls_or_self,) + self.args + tuple(rest) + return self.func(*call_args, **call_keywords) + _method.__isabstractmethod__ = self.__isabstractmethod__ + _method._partialmethod = self + return _method + + def __get__(self, obj, cls): + get = getattr(self.func, "__get__", None) + result = None + if get is not None: + new_func = get(obj, cls) + if new_func is not self.func: + # Assume __get__ returning something new indicates the + # creation of an appropriate callable + result = partial(new_func, *self.args, **self.keywords) + try: + result.__self__ = new_func.__self__ + except AttributeError: + pass + if result is None: + # If the underlying descriptor didn't do anything, treat this + # like an instance method + result = self._make_unbound_method().__get__(obj, cls) + return result + + @property + def __isabstractmethod__(self): + return getattr(self.func, "__isabstractmethod__", False) + + +################################################################################ +### LRU Cache function decorator +################################################################################ + +_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"]) + +class _HashedSeq(list): + """ This class guarantees that hash() will be called no more than once + per element. This is important because the lru_cache() will hash + the key multiple times on a cache miss. + + """ + + __slots__ = 'hashvalue' + + def __init__(self, tup, hash=hash): + self[:] = tup + self.hashvalue = hash(tup) + + def __hash__(self): + return self.hashvalue + +def _make_key(args, kwds, typed, + kwd_mark = (object(),), + fasttypes = {int, str, frozenset, type(None)}, + tuple=tuple, type=type, len=len): + """Make a cache key from optionally typed positional and keyword arguments + + The key is constructed in a way that is flat as possible rather than + as a nested structure that would take more memory. + + If there is only a single argument and its data type is known to cache + its hash value, then that argument is returned without a wrapper. This + saves space and improves lookup speed. + + """ + # All of code below relies on kwds preserving the order input by the user. + # Formerly, we sorted() the kwds before looping. The new way is *much* + # faster; however, it means that f(x=1, y=2) will now be treated as a + # distinct call from f(y=2, x=1) which will be cached separately. + key = args + if kwds: + key += kwd_mark + for item in kwds.items(): + key += item + if typed: + key += tuple(type(v) for v in args) + if kwds: + key += tuple(type(v) for v in kwds.values()) + elif len(key) == 1 and type(key[0]) in fasttypes: + return key[0] + return _HashedSeq(key) + +def lru_cache(maxsize=128, typed=False): + """Least-recently-used cache decorator. + + If *maxsize* is set to None, the LRU features are disabled and the cache + can grow without bound. + + If *typed* is True, arguments of different types will be cached separately. + For example, f(3.0) and f(3) will be treated as distinct calls with + distinct results. + + Arguments to the cached function must be hashable. + + View the cache statistics named tuple (hits, misses, maxsize, currsize) + with f.cache_info(). Clear the cache and statistics with f.cache_clear(). + Access the underlying function with f.__wrapped__. + + See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used + + """ + + # Users should only access the lru_cache through its public API: + # cache_info, cache_clear, and f.__wrapped__ + # The internals of the lru_cache are encapsulated for thread safety and + # to allow the implementation to change (including a possible C version). + + # Early detection of an erroneous call to @lru_cache without any arguments + # resulting in the inner function being passed to maxsize instead of an + # integer or None. + if maxsize is not None and not isinstance(maxsize, int): + raise TypeError('Expected maxsize to be an integer or None') + + def decorating_function(user_function): + wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) + return update_wrapper(wrapper, user_function) + + return decorating_function + +def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo): + # Constants shared by all lru cache instances: + sentinel = object() # unique object used to signal cache misses + make_key = _make_key # build a key from the function arguments + PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields + + cache = {} + hits = misses = 0 + full = False + cache_get = cache.get # bound method to lookup a key or return None + cache_len = cache.__len__ # get cache size without calling len() + lock = RLock() # because linkedlist updates aren't threadsafe + root = [] # root of the circular doubly linked list + root[:] = [root, root, None, None] # initialize by pointing to self + + if maxsize == 0: + + def wrapper(*args, **kwds): + # No caching -- just a statistics update after a successful call + nonlocal misses + result = user_function(*args, **kwds) + misses += 1 + return result + + elif maxsize is None: + + def wrapper(*args, **kwds): + # Simple caching without ordering or size limit + nonlocal hits, misses + key = make_key(args, kwds, typed) + result = cache_get(key, sentinel) + if result is not sentinel: + hits += 1 + return result + result = user_function(*args, **kwds) + cache[key] = result + misses += 1 + return result + + else: + + def wrapper(*args, **kwds): + # Size limited caching that tracks accesses by recency + nonlocal root, hits, misses, full + key = make_key(args, kwds, typed) + with lock: + link = cache_get(key) + if link is not None: + # Move the link to the front of the circular queue + link_prev, link_next, _key, result = link + link_prev[NEXT] = link_next + link_next[PREV] = link_prev + last = root[PREV] + last[NEXT] = root[PREV] = link + link[PREV] = last + link[NEXT] = root + hits += 1 + return result + result = user_function(*args, **kwds) + with lock: + if key in cache: + # Getting here means that this same key was added to the + # cache while the lock was released. Since the link + # update is already done, we need only return the + # computed result and update the count of misses. + pass + elif full: + # Use the old root to store the new key and result. + oldroot = root + oldroot[KEY] = key + oldroot[RESULT] = result + # Empty the oldest link and make it the new root. + # Keep a reference to the old key and old result to + # prevent their ref counts from going to zero during the + # update. That will prevent potentially arbitrary object + # clean-up code (i.e. __del__) from running while we're + # still adjusting the links. + root = oldroot[NEXT] + oldkey = root[KEY] + oldresult = root[RESULT] + root[KEY] = root[RESULT] = None + # Now update the cache dictionary. + del cache[oldkey] + # Save the potentially reentrant cache[key] assignment + # for last, after the root and links have been put in + # a consistent state. + cache[key] = oldroot + else: + # Put result in a new link at the front of the queue. + last = root[PREV] + link = [last, root, key, result] + last[NEXT] = root[PREV] = cache[key] = link + # Use the cache_len bound method instead of the len() function + # which could potentially be wrapped in an lru_cache itself. + full = (cache_len() >= maxsize) + misses += 1 + return result + + def cache_info(): + """Report cache statistics""" + with lock: + return _CacheInfo(hits, misses, maxsize, cache_len()) + + def cache_clear(): + """Clear the cache and cache statistics""" + nonlocal hits, misses, full + with lock: + cache.clear() + root[:] = [root, root, None, None] + hits = misses = 0 + full = False + + wrapper.cache_info = cache_info + wrapper.cache_clear = cache_clear + return wrapper + +try: + from _functools import _lru_cache_wrapper +except ImportError: + pass + + +################################################################################ +### singledispatch() - single-dispatch generic function decorator +################################################################################ + +def _c3_merge(sequences): + """Merges MROs in *sequences* to a single MRO using the C3 algorithm. + + Adapted from http://www.python.org/download/releases/2.3/mro/. + + """ + result = [] + while True: + sequences = [s for s in sequences if s] # purge empty sequences + if not sequences: + return result + for s1 in sequences: # find merge candidates among seq heads + candidate = s1[0] + for s2 in sequences: + if candidate in s2[1:]: + candidate = None + break # reject the current head, it appears later + else: + break + if candidate is None: + raise RuntimeError("Inconsistent hierarchy") + result.append(candidate) + # remove the chosen candidate + for seq in sequences: + if seq[0] == candidate: + del seq[0] + +def _c3_mro(cls, abcs=None): + """Computes the method resolution order using extended C3 linearization. + + If no *abcs* are given, the algorithm works exactly like the built-in C3 + linearization used for method resolution. + + If given, *abcs* is a list of abstract base classes that should be inserted + into the resulting MRO. Unrelated ABCs are ignored and don't end up in the + result. The algorithm inserts ABCs where their functionality is introduced, + i.e. issubclass(cls, abc) returns True for the class itself but returns + False for all its direct base classes. Implicit ABCs for a given class + (either registered or inferred from the presence of a special method like + __len__) are inserted directly after the last ABC explicitly listed in the + MRO of said class. If two implicit ABCs end up next to each other in the + resulting MRO, their ordering depends on the order of types in *abcs*. + + """ + for i, base in enumerate(reversed(cls.__bases__)): + if hasattr(base, '__abstractmethods__'): + boundary = len(cls.__bases__) - i + break # Bases up to the last explicit ABC are considered first. + else: + boundary = 0 + abcs = list(abcs) if abcs else [] + explicit_bases = list(cls.__bases__[:boundary]) + abstract_bases = [] + other_bases = list(cls.__bases__[boundary:]) + for base in abcs: + if issubclass(cls, base) and not any( + issubclass(b, base) for b in cls.__bases__ + ): + # If *cls* is the class that introduces behaviour described by + # an ABC *base*, insert said ABC to its MRO. + abstract_bases.append(base) + for base in abstract_bases: + abcs.remove(base) + explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases] + abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases] + other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases] + return _c3_merge( + [[cls]] + + explicit_c3_mros + abstract_c3_mros + other_c3_mros + + [explicit_bases] + [abstract_bases] + [other_bases] + ) + +def _compose_mro(cls, types): + """Calculates the method resolution order for a given class *cls*. + + Includes relevant abstract base classes (with their respective bases) from + the *types* iterable. Uses a modified C3 linearization algorithm. + + """ + bases = set(cls.__mro__) + # Remove entries which are already present in the __mro__ or unrelated. + def is_related(typ): + return (typ not in bases and hasattr(typ, '__mro__') + and issubclass(cls, typ)) + types = [n for n in types if is_related(n)] + # Remove entries which are strict bases of other entries (they will end up + # in the MRO anyway. + def is_strict_base(typ): + for other in types: + if typ != other and typ in other.__mro__: + return True + return False + types = [n for n in types if not is_strict_base(n)] + # Subclasses of the ABCs in *types* which are also implemented by + # *cls* can be used to stabilize ABC ordering. + type_set = set(types) + mro = [] + for typ in types: + found = [] + for sub in typ.__subclasses__(): + if sub not in bases and issubclass(cls, sub): + found.append([s for s in sub.__mro__ if s in type_set]) + if not found: + mro.append(typ) + continue + # Favor subclasses with the biggest number of useful bases + found.sort(key=len, reverse=True) + for sub in found: + for subcls in sub: + if subcls not in mro: + mro.append(subcls) + return _c3_mro(cls, abcs=mro) + +def _find_impl(cls, registry): + """Returns the best matching implementation from *registry* for type *cls*. + + Where there is no registered implementation for a specific type, its method + resolution order is used to find a more generic implementation. + + Note: if *registry* does not contain an implementation for the base + *object* type, this function may return None. + + """ + mro = _compose_mro(cls, registry.keys()) + match = None + for t in mro: + if match is not None: + # If *match* is an implicit ABC but there is another unrelated, + # equally matching implicit ABC, refuse the temptation to guess. + if (t in registry and t not in cls.__mro__ + and match not in cls.__mro__ + and not issubclass(match, t)): + raise RuntimeError("Ambiguous dispatch: {} or {}".format( + match, t)) + break + if t in registry: + match = t + return registry.get(match) + +def singledispatch(func): + """Single-dispatch generic function decorator. + + Transforms a function into a generic function, which can have different + behaviours depending upon the type of its first argument. The decorated + function acts as the default implementation, and additional + implementations can be registered using the register() attribute of the + generic function. + """ + # There are many programs that use functools without singledispatch, so we + # trade-off making singledispatch marginally slower for the benefit of + # making start-up of such applications slightly faster. + import types, weakref + + registry = {} + dispatch_cache = weakref.WeakKeyDictionary() + cache_token = None + + def dispatch(cls): + """generic_func.dispatch(cls) -> + + Runs the dispatch algorithm to return the best available implementation + for the given *cls* registered on *generic_func*. + + """ + nonlocal cache_token + if cache_token is not None: + current_token = get_cache_token() + if cache_token != current_token: + dispatch_cache.clear() + cache_token = current_token + try: + impl = dispatch_cache[cls] + except KeyError: + try: + impl = registry[cls] + except KeyError: + impl = _find_impl(cls, registry) + dispatch_cache[cls] = impl + return impl + + def register(cls, func=None): + """generic_func.register(cls, func) -> func + + Registers a new implementation for the given *cls* on a *generic_func*. + + """ + nonlocal cache_token + if func is None: + if isinstance(cls, type): + return lambda f: register(cls, f) + ann = getattr(cls, '__annotations__', {}) + if not ann: + raise TypeError( + f"Invalid first argument to `register()`: {cls!r}. " + f"Use either `@register(some_class)` or plain `@register` " + f"on an annotated function." + ) + func = cls + + # only import typing if annotation parsing is necessary + from typing import get_type_hints + argname, cls = next(iter(get_type_hints(func).items())) + assert isinstance(cls, type), ( + f"Invalid annotation for {argname!r}. {cls!r} is not a class." + ) + registry[cls] = func + if cache_token is None and hasattr(cls, '__abstractmethods__'): + cache_token = get_cache_token() + dispatch_cache.clear() + return func + + def wrapper(*args, **kw): + return dispatch(args[0].__class__)(*args, **kw) + + registry[object] = func + wrapper.register = register + wrapper.dispatch = dispatch + wrapper.registry = types.MappingProxyType(registry) + wrapper._clear_cache = dispatch_cache.clear + update_wrapper(wrapper, func) + return wrapper diff --git a/Lib/genericpath.py b/Lib/genericpath.py new file mode 100644 index 0000000..303b3b3 --- /dev/null +++ b/Lib/genericpath.py @@ -0,0 +1,151 @@ +""" +Path operations common to more than one OS +Do not use directly. The OS specific modules import the appropriate +functions from this module themselves. +""" +import os +import stat + +__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime', + 'getsize', 'isdir', 'isfile', 'samefile', 'sameopenfile', + 'samestat'] + + +# Does a path exist? +# This is false for dangling symbolic links on systems that support them. +def exists(path): + """Test whether a path exists. Returns False for broken symbolic links""" + try: + os.stat(path) + except OSError: + return False + return True + + +# This follows symbolic links, so both islink() and isdir() can be true +# for the same path on systems that support symlinks +def isfile(path): + """Test whether a path is a regular file""" + try: + st = os.stat(path) + except OSError: + return False + return stat.S_ISREG(st.st_mode) + + +# Is a path a directory? +# This follows symbolic links, so both islink() and isdir() +# can be true for the same path on systems that support symlinks +def isdir(s): + """Return true if the pathname refers to an existing directory.""" + try: + st = os.stat(s) + except OSError: + return False + return stat.S_ISDIR(st.st_mode) + + +def getsize(filename): + """Return the size of a file, reported by os.stat().""" + return os.stat(filename).st_size + + +def getmtime(filename): + """Return the last modification time of a file, reported by os.stat().""" + return os.stat(filename).st_mtime + + +def getatime(filename): + """Return the last access time of a file, reported by os.stat().""" + return os.stat(filename).st_atime + + +def getctime(filename): + """Return the metadata change time of a file, reported by os.stat().""" + return os.stat(filename).st_ctime + + +# Return the longest prefix of all list elements. +def commonprefix(m): + "Given a list of pathnames, returns the longest common leading component" + if not m: return '' + # Some people pass in a list of pathname parts to operate in an OS-agnostic + # fashion; don't try to translate in that case as that's an abuse of the + # API and they are already doing what they need to be OS-agnostic and so + # they most likely won't be using an os.PathLike object in the sublists. + if not isinstance(m[0], (list, tuple)): + m = tuple(map(os.fspath, m)) + s1 = min(m) + s2 = max(m) + for i, c in enumerate(s1): + if c != s2[i]: + return s1[:i] + return s1 + +# Are two stat buffers (obtained from stat, fstat or lstat) +# describing the same file? +def samestat(s1, s2): + """Test whether two stat buffers reference the same file""" + return (s1.st_ino == s2.st_ino and + s1.st_dev == s2.st_dev) + + +# Are two filenames really pointing to the same file? +def samefile(f1, f2): + """Test whether two pathnames reference the same actual file""" + s1 = os.stat(f1) + s2 = os.stat(f2) + return samestat(s1, s2) + + +# Are two open files really referencing the same file? +# (Not necessarily the same file descriptor!) +def sameopenfile(fp1, fp2): + """Test whether two open file objects reference the same file""" + s1 = os.fstat(fp1) + s2 = os.fstat(fp2) + return samestat(s1, s2) + + +# Split a path in root and extension. +# The extension is everything starting at the last dot in the last +# pathname component; the root is everything before that. +# It is always true that root + ext == p. + +# Generic implementation of splitext, to be parametrized with +# the separators +def _splitext(p, sep, altsep, extsep): + """Split the extension from a pathname. + + Extension is everything from the last dot to the end, ignoring + leading dots. Returns "(root, ext)"; ext may be empty.""" + # NOTE: This code must work for text and bytes strings. + + sepIndex = p.rfind(sep) + if altsep: + altsepIndex = p.rfind(altsep) + sepIndex = max(sepIndex, altsepIndex) + + dotIndex = p.rfind(extsep) + if dotIndex > sepIndex: + # skip all leading dots + filenameIndex = sepIndex + 1 + while filenameIndex < dotIndex: + if p[filenameIndex:filenameIndex+1] != extsep: + return p[:dotIndex], p[dotIndex:] + filenameIndex += 1 + + return p, p[:0] + +def _check_arg_types(funcname, *args): + hasstr = hasbytes = False + for s in args: + if isinstance(s, str): + hasstr = True + elif isinstance(s, bytes): + hasbytes = True + else: + raise TypeError('%s() argument must be str or bytes, not %r' % + (funcname, s.__class__.__name__)) from None + if hasstr and hasbytes: + raise TypeError("Can't mix strings and bytes in path components") from None diff --git a/Lib/hashlib.py b/Lib/hashlib.py new file mode 100644 index 0000000..e30c610 --- /dev/null +++ b/Lib/hashlib.py @@ -0,0 +1,251 @@ +#. Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org) +# Licensed to PSF under a Contributor Agreement. +# + +__doc__ = """hashlib module - A common interface to many hash functions. + +new(name, data=b'', **kwargs) - returns a new hash object implementing the + given hash function; initializing the hash + using the given binary data. + +Named constructor functions are also available, these are faster +than using new(name): + +md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(), +sha3_224, sha3_256, sha3_384, sha3_512, shake_128, and shake_256. + +More algorithms may be available on your platform but the above are guaranteed +to exist. See the algorithms_guaranteed and algorithms_available attributes +to find out what algorithm names can be passed to new(). + +NOTE: If you want the adler32 or crc32 hash functions they are available in +the zlib module. + +Choose your hash function wisely. Some have known collision weaknesses. +sha384 and sha512 will be slow on 32 bit platforms. + +Hash objects have these methods: + - update(arg): Update the hash object with the bytes in arg. Repeated calls + are equivalent to a single call with the concatenation of all + the arguments. + - digest(): Return the digest of the bytes passed to the update() method + so far. + - hexdigest(): Like digest() except the digest is returned as a unicode + object of double length, containing only hexadecimal digits. + - copy(): Return a copy (clone) of the hash object. This can be used to + efficiently compute the digests of strings that share a common + initial substring. + +For example, to obtain the digest of the string 'Nobody inspects the +spammish repetition': + + >>> import hashlib + >>> m = hashlib.md5() + >>> m.update(b"Nobody inspects") + >>> m.update(b" the spammish repetition") + >>> m.digest() + b'\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9' + +More condensed: + + >>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest() + 'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2' + +""" + +# This tuple and __get_builtin_constructor() must be modified if a new +# always available algorithm is added. +__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', + 'blake2b', 'blake2s', + 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', + 'shake_128', 'shake_256') + + +algorithms_guaranteed = set(__always_supported) +algorithms_available = set(__always_supported) + +__all__ = __always_supported + ('new', 'algorithms_guaranteed', + 'algorithms_available', 'pbkdf2_hmac') + + +__builtin_constructor_cache = {} + +def __get_builtin_constructor(name): + cache = __builtin_constructor_cache + constructor = cache.get(name) + if constructor is not None: + return constructor + try: + if name in ('SHA1', 'sha1'): + import _sha1 + cache['SHA1'] = cache['sha1'] = _sha1.sha1 + elif name in ('MD5', 'md5'): + import _md5 + cache['MD5'] = cache['md5'] = _md5.md5 + elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'): + import _sha256 + cache['SHA224'] = cache['sha224'] = _sha256.sha224 + cache['SHA256'] = cache['sha256'] = _sha256.sha256 + elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'): + import _sha512 + cache['SHA384'] = cache['sha384'] = _sha512.sha384 + cache['SHA512'] = cache['sha512'] = _sha512.sha512 + elif name in ('blake2b', 'blake2s'): + import _blake2 + cache['blake2b'] = _blake2.blake2b + cache['blake2s'] = _blake2.blake2s + elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', + 'shake_128', 'shake_256'}: + import _sha3 + cache['sha3_224'] = _sha3.sha3_224 + cache['sha3_256'] = _sha3.sha3_256 + cache['sha3_384'] = _sha3.sha3_384 + cache['sha3_512'] = _sha3.sha3_512 + cache['shake_128'] = _sha3.shake_128 + cache['shake_256'] = _sha3.shake_256 + except ImportError: + pass # no extension module, this hash is unsupported. + + constructor = cache.get(name) + if constructor is not None: + return constructor + + raise ValueError('unsupported hash type ' + name) + + +def __get_openssl_constructor(name): + if name in {'blake2b', 'blake2s'}: + # Prefer our blake2 implementation. + return __get_builtin_constructor(name) + try: + f = getattr(_hashlib, 'openssl_' + name) + # Allow the C module to raise ValueError. The function will be + # defined but the hash not actually available thanks to OpenSSL. + f() + # Use the C function directly (very fast) + return f + except (AttributeError, ValueError): + return __get_builtin_constructor(name) + + +def __py_new(name, data=b'', **kwargs): + """new(name, data=b'', **kwargs) - Return a new hashing object using the + named algorithm; optionally initialized with data (which must be bytes). + """ + return __get_builtin_constructor(name)(data, **kwargs) + + +def __hash_new(name, data=b'', **kwargs): + """new(name, data=b'') - Return a new hashing object using the named algorithm; + optionally initialized with data (which must be bytes). + """ + if name in {'blake2b', 'blake2s'}: + # Prefer our blake2 implementation. + # OpenSSL 1.1.0 comes with a limited implementation of blake2b/s. + # It does neither support keyed blake2 nor advanced features like + # salt, personal, tree hashing or SSE. + return __get_builtin_constructor(name)(data, **kwargs) + try: + return _hashlib.new(name, data) + except ValueError: + # If the _hashlib module (OpenSSL) doesn't support the named + # hash, try using our builtin implementations. + # This allows for SHA224/256 and SHA384/512 support even though + # the OpenSSL library prior to 0.9.8 doesn't provide them. + return __get_builtin_constructor(name)(data) + + +try: + import _hashlib + new = __hash_new + __get_hash = __get_openssl_constructor + algorithms_available = algorithms_available.union( + _hashlib.openssl_md_meth_names) +except ImportError: + new = __py_new + __get_hash = __get_builtin_constructor + +try: + # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA + from _hashlib import pbkdf2_hmac +except ImportError: + _trans_5C = bytes((x ^ 0x5C) for x in range(256)) + _trans_36 = bytes((x ^ 0x36) for x in range(256)) + + def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None): + """Password based key derivation function 2 (PKCS #5 v2.0) + + This Python implementations based on the hmac module about as fast + as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster + for long passwords. + """ + if not isinstance(hash_name, str): + raise TypeError(hash_name) + + if not isinstance(password, (bytes, bytearray)): + password = bytes(memoryview(password)) + if not isinstance(salt, (bytes, bytearray)): + salt = bytes(memoryview(salt)) + + # Fast inline HMAC implementation + inner = new(hash_name) + outer = new(hash_name) + blocksize = getattr(inner, 'block_size', 64) + if len(password) > blocksize: + password = new(hash_name, password).digest() + password = password + b'\x00' * (blocksize - len(password)) + inner.update(password.translate(_trans_36)) + outer.update(password.translate(_trans_5C)) + + def prf(msg, inner=inner, outer=outer): + # PBKDF2_HMAC uses the password as key. We can re-use the same + # digest objects and just update copies to skip initialization. + icpy = inner.copy() + ocpy = outer.copy() + icpy.update(msg) + ocpy.update(icpy.digest()) + return ocpy.digest() + + if iterations < 1: + raise ValueError(iterations) + if dklen is None: + dklen = outer.digest_size + if dklen < 1: + raise ValueError(dklen) + + dkey = b'' + loop = 1 + from_bytes = int.from_bytes + while len(dkey) < dklen: + prev = prf(salt + loop.to_bytes(4, 'big')) + # endianness doesn't matter here as long to / from use the same + rkey = int.from_bytes(prev, 'big') + for i in range(iterations - 1): + prev = prf(prev) + # rkey = rkey ^ prev + rkey ^= from_bytes(prev, 'big') + loop += 1 + dkey += rkey.to_bytes(inner.digest_size, 'big') + + return dkey[:dklen] + +try: + # OpenSSL's scrypt requires OpenSSL 1.1+ + from _hashlib import scrypt +except ImportError: + pass + + +for __func_name in __always_supported: + # try them all, some may not work due to the OpenSSL + # version not supporting that algorithm. + try: + globals()[__func_name] = __get_hash(__func_name) + except ValueError: + import logging + logging.exception('code for hash %s was not found.', __func_name) + + +# Cleanup locals() +del __always_supported, __func_name, __get_hash +del __py_new, __hash_new, __get_openssl_constructor diff --git a/Lib/heapq.py b/Lib/heapq.py new file mode 100644 index 0000000..b31f418 --- /dev/null +++ b/Lib/heapq.py @@ -0,0 +1,607 @@ +"""Heap queue algorithm (a.k.a. priority queue). + +Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for +all k, counting elements from 0. For the sake of comparison, +non-existing elements are considered to be infinite. The interesting +property of a heap is that a[0] is always its smallest element. + +Usage: + +heap = [] # creates an empty heap +heappush(heap, item) # pushes a new item on the heap +item = heappop(heap) # pops the smallest item from the heap +item = heap[0] # smallest item on the heap without popping it +heapify(x) # transforms list into a heap, in-place, in linear time +item = heapreplace(heap, item) # pops and returns smallest item, and adds + # new item; the heap size is unchanged + +Our API differs from textbook heap algorithms as follows: + +- We use 0-based indexing. This makes the relationship between the + index for a node and the indexes for its children slightly less + obvious, but is more suitable since Python uses 0-based indexing. + +- Our heappop() method returns the smallest item, not the largest. + +These two make it possible to view the heap as a regular Python list +without surprises: heap[0] is the smallest item, and heap.sort() +maintains the heap invariant! +""" + +# Original code by Kevin O'Connor, augmented by Tim Peters and Raymond Hettinger + +__about__ = """Heap queues + +[explanation by François Pinard] + +Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for +all k, counting elements from 0. For the sake of comparison, +non-existing elements are considered to be infinite. The interesting +property of a heap is that a[0] is always its smallest element. + +The strange invariant above is meant to be an efficient memory +representation for a tournament. The numbers below are `k', not a[k]: + + 0 + + 1 2 + + 3 4 5 6 + + 7 8 9 10 11 12 13 14 + + 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 + + +In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'. In +a usual binary tournament we see in sports, each cell is the winner +over the two cells it tops, and we can trace the winner down the tree +to see all opponents s/he had. However, in many computer applications +of such tournaments, we do not need to trace the history of a winner. +To be more memory efficient, when a winner is promoted, we try to +replace it by something else at a lower level, and the rule becomes +that a cell and the two cells it tops contain three different items, +but the top cell "wins" over the two topped cells. + +If this heap invariant is protected at all time, index 0 is clearly +the overall winner. The simplest algorithmic way to remove it and +find the "next" winner is to move some loser (let's say cell 30 in the +diagram above) into the 0 position, and then percolate this new 0 down +the tree, exchanging values, until the invariant is re-established. +This is clearly logarithmic on the total number of items in the tree. +By iterating over all items, you get an O(n ln n) sort. + +A nice feature of this sort is that you can efficiently insert new +items while the sort is going on, provided that the inserted items are +not "better" than the last 0'th element you extracted. This is +especially useful in simulation contexts, where the tree holds all +incoming events, and the "win" condition means the smallest scheduled +time. When an event schedule other events for execution, they are +scheduled into the future, so they can easily go into the heap. So, a +heap is a good structure for implementing schedulers (this is what I +used for my MIDI sequencer :-). + +Various structures for implementing schedulers have been extensively +studied, and heaps are good for this, as they are reasonably speedy, +the speed is almost constant, and the worst case is not much different +than the average case. However, there are other representations which +are more efficient overall, yet the worst cases might be terrible. + +Heaps are also very useful in big disk sorts. You most probably all +know that a big sort implies producing "runs" (which are pre-sorted +sequences, which size is usually related to the amount of CPU memory), +followed by a merging passes for these runs, which merging is often +very cleverly organised[1]. It is very important that the initial +sort produces the longest runs possible. Tournaments are a good way +to that. If, using all the memory available to hold a tournament, you +replace and percolate items that happen to fit the current run, you'll +produce runs which are twice the size of the memory for random input, +and much better for input fuzzily ordered. + +Moreover, if you output the 0'th item on disk and get an input which +may not fit in the current tournament (because the value "wins" over +the last output value), it cannot fit in the heap, so the size of the +heap decreases. The freed memory could be cleverly reused immediately +for progressively building a second heap, which grows at exactly the +same rate the first heap is melting. When the first heap completely +vanishes, you switch heaps and start a new run. Clever and quite +effective! + +In a word, heaps are useful memory structures to know. I use them in +a few applications, and I think it is good to keep a `heap' module +around. :-) + +-------------------- +[1] The disk balancing algorithms which are current, nowadays, are +more annoying than clever, and this is a consequence of the seeking +capabilities of the disks. On devices which cannot seek, like big +tape drives, the story was quite different, and one had to be very +clever to ensure (far in advance) that each tape movement will be the +most effective possible (that is, will best participate at +"progressing" the merge). Some tapes were even able to read +backwards, and this was also used to avoid the rewinding time. +Believe me, real good tape sorts were quite spectacular to watch! +From all times, sorting has always been a Great Art! :-) +""" + +__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge', + 'nlargest', 'nsmallest', 'heappushpop'] + +def heappush(heap, item): + """Push item onto heap, maintaining the heap invariant.""" + heap.append(item) + _siftdown(heap, 0, len(heap)-1) + +def heappop(heap): + """Pop the smallest item off the heap, maintaining the heap invariant.""" + lastelt = heap.pop() # raises appropriate IndexError if heap is empty + if heap: + returnitem = heap[0] + heap[0] = lastelt + _siftup(heap, 0) + return returnitem + return lastelt + +def heapreplace(heap, item): + """Pop and return the current smallest value, and add the new item. + + This is more efficient than heappop() followed by heappush(), and can be + more appropriate when using a fixed-size heap. Note that the value + returned may be larger than item! That constrains reasonable uses of + this routine unless written as part of a conditional replacement: + + if item > heap[0]: + item = heapreplace(heap, item) + """ + returnitem = heap[0] # raises appropriate IndexError if heap is empty + heap[0] = item + _siftup(heap, 0) + return returnitem + +def heappushpop(heap, item): + """Fast version of a heappush followed by a heappop.""" + if heap and heap[0] < item: + item, heap[0] = heap[0], item + _siftup(heap, 0) + return item + +def heapify(x): + """Transform list into a heap, in-place, in O(len(x)) time.""" + n = len(x) + # Transform bottom-up. The largest index there's any point to looking at + # is the largest with a child index in-range, so must have 2*i + 1 < n, + # or i < (n-1)/2. If n is even = 2*j, this is (2*j-1)/2 = j-1/2 so + # j-1 is the largest, which is n//2 - 1. If n is odd = 2*j+1, this is + # (2*j+1-1)/2 = j so j-1 is the largest, and that's again n//2-1. + for i in reversed(range(n//2)): + _siftup(x, i) + +def _heappop_max(heap): + """Maxheap version of a heappop.""" + lastelt = heap.pop() # raises appropriate IndexError if heap is empty + if heap: + returnitem = heap[0] + heap[0] = lastelt + _siftup_max(heap, 0) + return returnitem + return lastelt + +def _heapreplace_max(heap, item): + """Maxheap version of a heappop followed by a heappush.""" + returnitem = heap[0] # raises appropriate IndexError if heap is empty + heap[0] = item + _siftup_max(heap, 0) + return returnitem + +def _heapify_max(x): + """Transform list into a maxheap, in-place, in O(len(x)) time.""" + n = len(x) + for i in reversed(range(n//2)): + _siftup_max(x, i) + +# 'heap' is a heap at all indices >= startpos, except possibly for pos. pos +# is the index of a leaf with a possibly out-of-order value. Restore the +# heap invariant. +def _siftdown(heap, startpos, pos): + newitem = heap[pos] + # Follow the path to the root, moving parents down until finding a place + # newitem fits. + while pos > startpos: + parentpos = (pos - 1) >> 1 + parent = heap[parentpos] + if newitem < parent: + heap[pos] = parent + pos = parentpos + continue + break + heap[pos] = newitem + +# The child indices of heap index pos are already heaps, and we want to make +# a heap at index pos too. We do this by bubbling the smaller child of +# pos up (and so on with that child's children, etc) until hitting a leaf, +# then using _siftdown to move the oddball originally at index pos into place. +# +# We *could* break out of the loop as soon as we find a pos where newitem <= +# both its children, but turns out that's not a good idea, and despite that +# many books write the algorithm that way. During a heap pop, the last array +# element is sifted in, and that tends to be large, so that comparing it +# against values starting from the root usually doesn't pay (= usually doesn't +# get us out of the loop early). See Knuth, Volume 3, where this is +# explained and quantified in an exercise. +# +# Cutting the # of comparisons is important, since these routines have no +# way to extract "the priority" from an array element, so that intelligence +# is likely to be hiding in custom comparison methods, or in array elements +# storing (priority, record) tuples. Comparisons are thus potentially +# expensive. +# +# On random arrays of length 1000, making this change cut the number of +# comparisons made by heapify() a little, and those made by exhaustive +# heappop() a lot, in accord with theory. Here are typical results from 3 +# runs (3 just to demonstrate how small the variance is): +# +# Compares needed by heapify Compares needed by 1000 heappops +# -------------------------- -------------------------------- +# 1837 cut to 1663 14996 cut to 8680 +# 1855 cut to 1659 14966 cut to 8678 +# 1847 cut to 1660 15024 cut to 8703 +# +# Building the heap by using heappush() 1000 times instead required +# 2198, 2148, and 2219 compares: heapify() is more efficient, when +# you can use it. +# +# The total compares needed by list.sort() on the same lists were 8627, +# 8627, and 8632 (this should be compared to the sum of heapify() and +# heappop() compares): list.sort() is (unsurprisingly!) more efficient +# for sorting. + +def _siftup(heap, pos): + endpos = len(heap) + startpos = pos + newitem = heap[pos] + # Bubble up the smaller child until hitting a leaf. + childpos = 2*pos + 1 # leftmost child position + while childpos < endpos: + # Set childpos to index of smaller child. + rightpos = childpos + 1 + if rightpos < endpos and not heap[childpos] < heap[rightpos]: + childpos = rightpos + # Move the smaller child up. + heap[pos] = heap[childpos] + pos = childpos + childpos = 2*pos + 1 + # The leaf at pos is empty now. Put newitem there, and bubble it up + # to its final resting place (by sifting its parents down). + heap[pos] = newitem + _siftdown(heap, startpos, pos) + +def _siftdown_max(heap, startpos, pos): + 'Maxheap variant of _siftdown' + newitem = heap[pos] + # Follow the path to the root, moving parents down until finding a place + # newitem fits. + while pos > startpos: + parentpos = (pos - 1) >> 1 + parent = heap[parentpos] + if parent < newitem: + heap[pos] = parent + pos = parentpos + continue + break + heap[pos] = newitem + +def _siftup_max(heap, pos): + 'Maxheap variant of _siftup' + endpos = len(heap) + startpos = pos + newitem = heap[pos] + # Bubble up the larger child until hitting a leaf. + childpos = 2*pos + 1 # leftmost child position + while childpos < endpos: + # Set childpos to index of larger child. + rightpos = childpos + 1 + if rightpos < endpos and not heap[rightpos] < heap[childpos]: + childpos = rightpos + # Move the larger child up. + heap[pos] = heap[childpos] + pos = childpos + childpos = 2*pos + 1 + # The leaf at pos is empty now. Put newitem there, and bubble it up + # to its final resting place (by sifting its parents down). + heap[pos] = newitem + _siftdown_max(heap, startpos, pos) + +def merge(*iterables, key=None, reverse=False): + '''Merge multiple sorted inputs into a single sorted output. + + Similar to sorted(itertools.chain(*iterables)) but returns a generator, + does not pull the data into memory all at once, and assumes that each of + the input streams is already sorted (smallest to largest). + + >>> list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) + [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] + + If *key* is not None, applies a key function to each element to determine + its sort order. + + >>> list(merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len)) + ['dog', 'cat', 'fish', 'horse', 'kangaroo'] + + ''' + + h = [] + h_append = h.append + + if reverse: + _heapify = _heapify_max + _heappop = _heappop_max + _heapreplace = _heapreplace_max + direction = -1 + else: + _heapify = heapify + _heappop = heappop + _heapreplace = heapreplace + direction = 1 + + if key is None: + for order, it in enumerate(map(iter, iterables)): + try: + next = it.__next__ + h_append([next(), order * direction, next]) + except StopIteration: + pass + _heapify(h) + while len(h) > 1: + try: + while True: + value, order, next = s = h[0] + yield value + s[0] = next() # raises StopIteration when exhausted + _heapreplace(h, s) # restore heap condition + except StopIteration: + _heappop(h) # remove empty iterator + if h: + # fast case when only a single iterator remains + value, order, next = h[0] + yield value + yield from next.__self__ + return + + for order, it in enumerate(map(iter, iterables)): + try: + next = it.__next__ + value = next() + h_append([key(value), order * direction, value, next]) + except StopIteration: + pass + _heapify(h) + while len(h) > 1: + try: + while True: + key_value, order, value, next = s = h[0] + yield value + value = next() + s[0] = key(value) + s[2] = value + _heapreplace(h, s) + except StopIteration: + _heappop(h) + if h: + key_value, order, value, next = h[0] + yield value + yield from next.__self__ + + +# Algorithm notes for nlargest() and nsmallest() +# ============================================== +# +# Make a single pass over the data while keeping the k most extreme values +# in a heap. Memory consumption is limited to keeping k values in a list. +# +# Measured performance for random inputs: +# +# number of comparisons +# n inputs k-extreme values (average of 5 trials) % more than min() +# ------------- ---------------- --------------------- ----------------- +# 1,000 100 3,317 231.7% +# 10,000 100 14,046 40.5% +# 100,000 100 105,749 5.7% +# 1,000,000 100 1,007,751 0.8% +# 10,000,000 100 10,009,401 0.1% +# +# Theoretical number of comparisons for k smallest of n random inputs: +# +# Step Comparisons Action +# ---- -------------------------- --------------------------- +# 1 1.66 * k heapify the first k-inputs +# 2 n - k compare remaining elements to top of heap +# 3 k * (1 + lg2(k)) * ln(n/k) replace the topmost value on the heap +# 4 k * lg2(k) - (k/2) final sort of the k most extreme values +# +# Combining and simplifying for a rough estimate gives: +# +# comparisons = n + k * (log(k, 2) * log(n/k) + log(k, 2) + log(n/k)) +# +# Computing the number of comparisons for step 3: +# ----------------------------------------------- +# * For the i-th new value from the iterable, the probability of being in the +# k most extreme values is k/i. For example, the probability of the 101st +# value seen being in the 100 most extreme values is 100/101. +# * If the value is a new extreme value, the cost of inserting it into the +# heap is 1 + log(k, 2). +# * The probability times the cost gives: +# (k/i) * (1 + log(k, 2)) +# * Summing across the remaining n-k elements gives: +# sum((k/i) * (1 + log(k, 2)) for i in range(k+1, n+1)) +# * This reduces to: +# (H(n) - H(k)) * k * (1 + log(k, 2)) +# * Where H(n) is the n-th harmonic number estimated by: +# gamma = 0.5772156649 +# H(n) = log(n, e) + gamma + 1 / (2 * n) +# http://en.wikipedia.org/wiki/Harmonic_series_(mathematics)#Rate_of_divergence +# * Substituting the H(n) formula: +# comparisons = k * (1 + log(k, 2)) * (log(n/k, e) + (1/n - 1/k) / 2) +# +# Worst-case for step 3: +# ---------------------- +# In the worst case, the input data is reversed sorted so that every new element +# must be inserted in the heap: +# +# comparisons = 1.66 * k + log(k, 2) * (n - k) +# +# Alternative Algorithms +# ---------------------- +# Other algorithms were not used because they: +# 1) Took much more auxiliary memory, +# 2) Made multiple passes over the data. +# 3) Made more comparisons in common cases (small k, large n, semi-random input). +# See the more detailed comparison of approach at: +# http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest + +def nsmallest(n, iterable, key=None): + """Find the n smallest elements in a dataset. + + Equivalent to: sorted(iterable, key=key)[:n] + """ + + # Short-cut for n==1 is to use min() + if n == 1: + it = iter(iterable) + sentinel = object() + if key is None: + result = min(it, default=sentinel) + else: + result = min(it, default=sentinel, key=key) + return [] if result is sentinel else [result] + + # When n>=size, it's faster to use sorted() + try: + size = len(iterable) + except (TypeError, AttributeError): + pass + else: + if n >= size: + return sorted(iterable, key=key)[:n] + + # When key is none, use simpler decoration + if key is None: + it = iter(iterable) + # put the range(n) first so that zip() doesn't + # consume one too many elements from the iterator + result = [(elem, i) for i, elem in zip(range(n), it)] + if not result: + return result + _heapify_max(result) + top = result[0][0] + order = n + _heapreplace = _heapreplace_max + for elem in it: + if elem < top: + _heapreplace(result, (elem, order)) + top, _order = result[0] + order += 1 + result.sort() + return [elem for (elem, order) in result] + + # General case, slowest method + it = iter(iterable) + result = [(key(elem), i, elem) for i, elem in zip(range(n), it)] + if not result: + return result + _heapify_max(result) + top = result[0][0] + order = n + _heapreplace = _heapreplace_max + for elem in it: + k = key(elem) + if k < top: + _heapreplace(result, (k, order, elem)) + top, _order, _elem = result[0] + order += 1 + result.sort() + return [elem for (k, order, elem) in result] + +def nlargest(n, iterable, key=None): + """Find the n largest elements in a dataset. + + Equivalent to: sorted(iterable, key=key, reverse=True)[:n] + """ + + # Short-cut for n==1 is to use max() + if n == 1: + it = iter(iterable) + sentinel = object() + if key is None: + result = max(it, default=sentinel) + else: + result = max(it, default=sentinel, key=key) + return [] if result is sentinel else [result] + + # When n>=size, it's faster to use sorted() + try: + size = len(iterable) + except (TypeError, AttributeError): + pass + else: + if n >= size: + return sorted(iterable, key=key, reverse=True)[:n] + + # When key is none, use simpler decoration + if key is None: + it = iter(iterable) + result = [(elem, i) for i, elem in zip(range(0, -n, -1), it)] + if not result: + return result + heapify(result) + top = result[0][0] + order = -n + _heapreplace = heapreplace + for elem in it: + if top < elem: + _heapreplace(result, (elem, order)) + top, _order = result[0] + order -= 1 + result.sort(reverse=True) + return [elem for (elem, order) in result] + + # General case, slowest method + it = iter(iterable) + result = [(key(elem), i, elem) for i, elem in zip(range(0, -n, -1), it)] + if not result: + return result + heapify(result) + top = result[0][0] + order = -n + _heapreplace = heapreplace + for elem in it: + k = key(elem) + if top < k: + _heapreplace(result, (k, order, elem)) + top, _order, _elem = result[0] + order -= 1 + result.sort(reverse=True) + return [elem for (k, order, elem) in result] + +# If available, use C implementation +try: + from _heapq import * +except ImportError: + pass +try: + from _heapq import _heapreplace_max +except ImportError: + pass +try: + from _heapq import _heapify_max +except ImportError: + pass +try: + from _heapq import _heappop_max +except ImportError: + pass + + +if __name__ == "__main__": + + import doctest + print(doctest.testmod()) diff --git a/Lib/hmac.py b/Lib/hmac.py new file mode 100644 index 0000000..43b7212 --- /dev/null +++ b/Lib/hmac.py @@ -0,0 +1,188 @@ +"""HMAC (Keyed-Hashing for Message Authentication) Python module. + +Implements the HMAC algorithm as described by RFC 2104. +""" + +import warnings as _warnings +from _operator import _compare_digest as compare_digest +try: + import _hashlib as _hashopenssl +except ImportError: + _hashopenssl = None + _openssl_md_meths = None +else: + _openssl_md_meths = frozenset(_hashopenssl.openssl_md_meth_names) +import hashlib as _hashlib + +trans_5C = bytes((x ^ 0x5C) for x in range(256)) +trans_36 = bytes((x ^ 0x36) for x in range(256)) + +# The size of the digests returned by HMAC depends on the underlying +# hashing module used. Use digest_size from the instance of HMAC instead. +digest_size = None + + + +class HMAC: + """RFC 2104 HMAC class. Also complies with RFC 4231. + + This supports the API for Cryptographic Hash Functions (PEP 247). + """ + blocksize = 64 # 512-bit HMAC; can be changed in subclasses. + + def __init__(self, key, msg = None, digestmod = None): + """Create a new HMAC object. + + key: key for the keyed hash object. + msg: Initial input for the hash, if provided. + digestmod: A module supporting PEP 247. *OR* + A hashlib constructor returning a new hash object. *OR* + A hash name suitable for hashlib.new(). + Defaults to hashlib.md5. + Implicit default to hashlib.md5 is deprecated since Python + 3.4 and will be removed in Python 3.8. + + Note: key and msg must be a bytes or bytearray objects. + """ + + if not isinstance(key, (bytes, bytearray)): + raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__) + + if digestmod is None: + _warnings.warn("HMAC() without an explicit digestmod argument " + "is deprecated since Python 3.4, and will be removed " + "in 3.8", + DeprecationWarning, 2) + digestmod = _hashlib.md5 + + if callable(digestmod): + self.digest_cons = digestmod + elif isinstance(digestmod, str): + self.digest_cons = lambda d=b'': _hashlib.new(digestmod, d) + else: + self.digest_cons = lambda d=b'': digestmod.new(d) + + self.outer = self.digest_cons() + self.inner = self.digest_cons() + self.digest_size = self.inner.digest_size + + if hasattr(self.inner, 'block_size'): + blocksize = self.inner.block_size + if blocksize < 16: + _warnings.warn('block_size of %d seems too small; using our ' + 'default of %d.' % (blocksize, self.blocksize), + RuntimeWarning, 2) + blocksize = self.blocksize + else: + _warnings.warn('No block_size attribute on given digest object; ' + 'Assuming %d.' % (self.blocksize), + RuntimeWarning, 2) + blocksize = self.blocksize + + # self.blocksize is the default blocksize. self.block_size is + # effective block size as well as the public API attribute. + self.block_size = blocksize + + if len(key) > blocksize: + key = self.digest_cons(key).digest() + + key = key.ljust(blocksize, b'\0') + self.outer.update(key.translate(trans_5C)) + self.inner.update(key.translate(trans_36)) + if msg is not None: + self.update(msg) + + @property + def name(self): + return "hmac-" + self.inner.name + + def update(self, msg): + """Update this hashing object with the string msg. + """ + self.inner.update(msg) + + def copy(self): + """Return a separate copy of this hashing object. + + An update to this copy won't affect the original object. + """ + # Call __new__ directly to avoid the expensive __init__. + other = self.__class__.__new__(self.__class__) + other.digest_cons = self.digest_cons + other.digest_size = self.digest_size + other.inner = self.inner.copy() + other.outer = self.outer.copy() + return other + + def _current(self): + """Return a hash object for the current state. + + To be used only internally with digest() and hexdigest(). + """ + h = self.outer.copy() + h.update(self.inner.digest()) + return h + + def digest(self): + """Return the hash value of this hashing object. + + This returns a string containing 8-bit data. The object is + not altered in any way by this function; you can continue + updating the object after calling this function. + """ + h = self._current() + return h.digest() + + def hexdigest(self): + """Like digest(), but returns a string of hexadecimal digits instead. + """ + h = self._current() + return h.hexdigest() + +def new(key, msg = None, digestmod = None): + """Create a new hashing object and return it. + + key: The starting key for the hash. + msg: if available, will immediately be hashed into the object's starting + state. + + You can now feed arbitrary strings into the object using its update() + method, and can ask for the hash value at any time by calling its digest() + method. + """ + return HMAC(key, msg, digestmod) + + +def digest(key, msg, digest): + """Fast inline implementation of HMAC + + key: key for the keyed hash object. + msg: input message + digest: A hash name suitable for hashlib.new() for best performance. *OR* + A hashlib constructor returning a new hash object. *OR* + A module supporting PEP 247. + + Note: key and msg must be a bytes or bytearray objects. + """ + if (_hashopenssl is not None and + isinstance(digest, str) and digest in _openssl_md_meths): + return _hashopenssl.hmac_digest(key, msg, digest) + + if callable(digest): + digest_cons = digest + elif isinstance(digest, str): + digest_cons = lambda d=b'': _hashlib.new(digest, d) + else: + digest_cons = lambda d=b'': digest.new(d) + + inner = digest_cons() + outer = digest_cons() + blocksize = getattr(inner, 'block_size', 64) + if len(key) > blocksize: + key = digest_cons(key).digest() + key = key + b'\x00' * (blocksize - len(key)) + inner.update(key.translate(trans_36)) + outer.update(key.translate(trans_5C)) + inner.update(msg) + outer.update(inner.digest()) + return outer.digest() diff --git a/Lib/imp.py b/Lib/imp.py new file mode 100644 index 0000000..866464b --- /dev/null +++ b/Lib/imp.py @@ -0,0 +1,346 @@ +"""This module provides the components needed to build your own __import__ +function. Undocumented functions are obsolete. + +In most cases it is preferred you consider using the importlib module's +functionality over this module. + +""" +# (Probably) need to stay in _imp +from _imp import (lock_held, acquire_lock, release_lock, + get_frozen_object, is_frozen_package, + init_frozen, is_builtin, is_frozen, + _fix_co_filename) +try: + from _imp import create_dynamic +except ImportError: + # Platform doesn't support dynamic loading. + create_dynamic = None + +from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name +from importlib._bootstrap_external import SourcelessFileLoader + +from importlib import machinery +from importlib import util +import importlib +import os +import sys +import tokenize +import types +import warnings + +warnings.warn("the imp module is deprecated in favour of importlib; " + "see the module's documentation for alternative uses", + DeprecationWarning, stacklevel=2) + +# DEPRECATED +SEARCH_ERROR = 0 +PY_SOURCE = 1 +PY_COMPILED = 2 +C_EXTENSION = 3 +PY_RESOURCE = 4 +PKG_DIRECTORY = 5 +C_BUILTIN = 6 +PY_FROZEN = 7 +PY_CODERESOURCE = 8 +IMP_HOOK = 9 + + +def new_module(name): + """**DEPRECATED** + + Create a new module. + + The module is not entered into sys.modules. + + """ + return types.ModuleType(name) + + +def get_magic(): + """**DEPRECATED** + + Return the magic number for .pyc files. + """ + return util.MAGIC_NUMBER + + +def get_tag(): + """Return the magic tag for .pyc files.""" + return sys.implementation.cache_tag + + +def cache_from_source(path, debug_override=None): + """**DEPRECATED** + + Given the path to a .py file, return the path to its .pyc file. + + The .py file does not need to exist; this simply returns the path to the + .pyc file calculated as if the .py file were imported. + + If debug_override is not None, then it must be a boolean and is used in + place of sys.flags.optimize. + + If sys.implementation.cache_tag is None then NotImplementedError is raised. + + """ + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + return util.cache_from_source(path, debug_override) + + +def source_from_cache(path): + """**DEPRECATED** + + Given the path to a .pyc. file, return the path to its .py file. + + The .pyc file does not need to exist; this simply returns the path to + the .py file calculated to correspond to the .pyc file. If path does + not conform to PEP 3147 format, ValueError will be raised. If + sys.implementation.cache_tag is None then NotImplementedError is raised. + + """ + return util.source_from_cache(path) + + +def get_suffixes(): + """**DEPRECATED**""" + extensions = [(s, 'rb', C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES] + source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES] + bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES] + + return extensions + source + bytecode + + +class NullImporter: + + """**DEPRECATED** + + Null import object. + + """ + + def __init__(self, path): + if path == '': + raise ImportError('empty pathname', path='') + elif os.path.isdir(path): + raise ImportError('existing directory', path=path) + + def find_module(self, fullname): + """Always returns None.""" + return None + + +class _HackedGetData: + + """Compatibility support for 'file' arguments of various load_*() + functions.""" + + def __init__(self, fullname, path, file=None): + super().__init__(fullname, path) + self.file = file + + def get_data(self, path): + """Gross hack to contort loader to deal w/ load_*()'s bad API.""" + if self.file and path == self.path: + if not self.file.closed: + file = self.file + else: + self.file = file = open(self.path, 'r') + + with file: + # Technically should be returning bytes, but + # SourceLoader.get_code() just passed what is returned to + # compile() which can handle str. And converting to bytes would + # require figuring out the encoding to decode to and + # tokenize.detect_encoding() only accepts bytes. + return file.read() + else: + return super().get_data(path) + + +class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader): + + """Compatibility support for implementing load_source().""" + + +def load_source(name, pathname, file=None): + loader = _LoadSourceCompatibility(name, pathname, file) + spec = util.spec_from_file_location(name, pathname, loader=loader) + if name in sys.modules: + module = _exec(spec, sys.modules[name]) + else: + module = _load(spec) + # To allow reloading to potentially work, use a non-hacked loader which + # won't rely on a now-closed file object. + module.__loader__ = machinery.SourceFileLoader(name, pathname) + module.__spec__.loader = module.__loader__ + return module + + +class _LoadCompiledCompatibility(_HackedGetData, SourcelessFileLoader): + + """Compatibility support for implementing load_compiled().""" + + +def load_compiled(name, pathname, file=None): + """**DEPRECATED**""" + loader = _LoadCompiledCompatibility(name, pathname, file) + spec = util.spec_from_file_location(name, pathname, loader=loader) + if name in sys.modules: + module = _exec(spec, sys.modules[name]) + else: + module = _load(spec) + # To allow reloading to potentially work, use a non-hacked loader which + # won't rely on a now-closed file object. + module.__loader__ = SourcelessFileLoader(name, pathname) + module.__spec__.loader = module.__loader__ + return module + + +def load_package(name, path): + """**DEPRECATED**""" + if os.path.isdir(path): + extensions = (machinery.SOURCE_SUFFIXES[:] + + machinery.BYTECODE_SUFFIXES[:]) + for extension in extensions: + init_path = os.path.join(path, '__init__' + extension) + if os.path.exists(init_path): + path = init_path + break + else: + raise ValueError('{!r} is not a package'.format(path)) + spec = util.spec_from_file_location(name, path, + submodule_search_locations=[]) + if name in sys.modules: + return _exec(spec, sys.modules[name]) + else: + return _load(spec) + + +def load_module(name, file, filename, details): + """**DEPRECATED** + + Load a module, given information returned by find_module(). + + The module name must include the full package name, if any. + + """ + suffix, mode, type_ = details + if mode and (not mode.startswith(('r', 'U')) or '+' in mode): + raise ValueError('invalid file open mode {!r}'.format(mode)) + elif file is None and type_ in {PY_SOURCE, PY_COMPILED}: + msg = 'file object required for import (type code {})'.format(type_) + raise ValueError(msg) + elif type_ == PY_SOURCE: + return load_source(name, filename, file) + elif type_ == PY_COMPILED: + return load_compiled(name, filename, file) + elif type_ == C_EXTENSION and load_dynamic is not None: + if file is None: + with open(filename, 'rb') as opened_file: + return load_dynamic(name, filename, opened_file) + else: + return load_dynamic(name, filename, file) + elif type_ == PKG_DIRECTORY: + return load_package(name, filename) + elif type_ == C_BUILTIN: + return init_builtin(name) + elif type_ == PY_FROZEN: + return init_frozen(name) + else: + msg = "Don't know how to import {} (type code {})".format(name, type_) + raise ImportError(msg, name=name) + + +def find_module(name, path=None): + """**DEPRECATED** + + Search for a module. + + If path is omitted or None, search for a built-in, frozen or special + module and continue search in sys.path. The module name cannot + contain '.'; to search for a submodule of a package, pass the + submodule name and the package's __path__. + + """ + if not isinstance(name, str): + raise TypeError("'name' must be a str, not {}".format(type(name))) + elif not isinstance(path, (type(None), list)): + # Backwards-compatibility + raise RuntimeError("'path' must be None or a list, " + "not {}".format(type(path))) + + if path is None: + if is_builtin(name): + return None, None, ('', '', C_BUILTIN) + elif is_frozen(name): + return None, None, ('', '', PY_FROZEN) + else: + path = sys.path + + for entry in path: + package_directory = os.path.join(entry, name) + for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]: + package_file_name = '__init__' + suffix + file_path = os.path.join(package_directory, package_file_name) + if os.path.isfile(file_path): + return None, package_directory, ('', '', PKG_DIRECTORY) + for suffix, mode, type_ in get_suffixes(): + file_name = name + suffix + file_path = os.path.join(entry, file_name) + if os.path.isfile(file_path): + break + else: + continue + break # Break out of outer loop when breaking out of inner loop. + else: + raise ImportError(_ERR_MSG.format(name), name=name) + + encoding = None + if 'b' not in mode: + with open(file_path, 'rb') as file: + encoding = tokenize.detect_encoding(file.readline)[0] + file = open(file_path, mode, encoding=encoding) + return file, file_path, (suffix, mode, type_) + + +def reload(module): + """**DEPRECATED** + + Reload the module and return it. + + The module must have been successfully imported before. + + """ + return importlib.reload(module) + + +def init_builtin(name): + """**DEPRECATED** + + Load and return a built-in module by name, or None is such module doesn't + exist + """ + try: + return _builtin_from_name(name) + except ImportError: + return None + + +if create_dynamic: + def load_dynamic(name, path, file=None): + """**DEPRECATED** + + Load an extension module. + """ + import importlib.machinery + loader = importlib.machinery.ExtensionFileLoader(name, path) + + # Issue #24748: Skip the sys.modules check in _load_module_shim; + # always load new extension + spec = importlib.machinery.ModuleSpec( + name=name, loader=loader, origin=path) + return _load(spec) + +else: + load_dynamic = None diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py new file mode 100644 index 0000000..cb37d24 --- /dev/null +++ b/Lib/importlib/__init__.py @@ -0,0 +1,176 @@ +"""A pure Python implementation of import.""" +__all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] + +# Bootstrap help ##################################################### + +# Until bootstrapping is complete, DO NOT import any modules that attempt +# to import importlib._bootstrap (directly or indirectly). Since this +# partially initialised package would be present in sys.modules, those +# modules would get an uninitialised copy of the source version, instead +# of a fully initialised version (either the frozen one or the one +# initialised below if the frozen one is not available). +import _imp # Just the builtin component, NOT the full Python module +import sys + +try: + import _frozen_importlib as _bootstrap +except ImportError: + from . import _bootstrap + _bootstrap._setup(sys, _imp) +else: + # importlib._bootstrap is the built-in import, ensure we don't create + # a second copy of the module. + _bootstrap.__name__ = 'importlib._bootstrap' + _bootstrap.__package__ = 'importlib' + try: + _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') + except NameError: + # __file__ is not guaranteed to be defined, e.g. if this code gets + # frozen by a tool like cx_Freeze. + pass + sys.modules['importlib._bootstrap'] = _bootstrap + +try: + import _frozen_importlib_external as _bootstrap_external +except ImportError: + from . import _bootstrap_external + _bootstrap_external._setup(_bootstrap) + _bootstrap._bootstrap_external = _bootstrap_external +else: + _bootstrap_external.__name__ = 'importlib._bootstrap_external' + _bootstrap_external.__package__ = 'importlib' + try: + _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') + except NameError: + # __file__ is not guaranteed to be defined, e.g. if this code gets + # frozen by a tool like cx_Freeze. + pass + sys.modules['importlib._bootstrap_external'] = _bootstrap_external + +# To simplify imports in test code +_w_long = _bootstrap_external._w_long +_r_long = _bootstrap_external._r_long + +# Fully bootstrapped at this point, import whatever you like, circular +# dependencies and startup overhead minimisation permitting :) + +import types +import warnings + + +# Public API ######################################################### + +from ._bootstrap import __import__ + + +def invalidate_caches(): + """Call the invalidate_caches() method on all meta path finders stored in + sys.meta_path (where implemented).""" + for finder in sys.meta_path: + if hasattr(finder, 'invalidate_caches'): + finder.invalidate_caches() + + +def find_loader(name, path=None): + """Return the loader for the specified module. + + This is a backward-compatible wrapper around find_spec(). + + This function is deprecated in favor of importlib.util.find_spec(). + + """ + warnings.warn('Deprecated since Python 3.4. ' + 'Use importlib.util.find_spec() instead.', + DeprecationWarning, stacklevel=2) + try: + loader = sys.modules[name].__loader__ + if loader is None: + raise ValueError('{}.__loader__ is None'.format(name)) + else: + return loader + except KeyError: + pass + except AttributeError: + raise ValueError('{}.__loader__ is not set'.format(name)) from None + + spec = _bootstrap._find_spec(name, path) + # We won't worry about malformed specs (missing attributes). + if spec is None: + return None + if spec.loader is None: + if spec.submodule_search_locations is None: + raise ImportError('spec for {} missing loader'.format(name), + name=name) + raise ImportError('namespace packages do not have loaders', + name=name) + return spec.loader + + +def import_module(name, package=None): + """Import a module. + + The 'package' argument is required when performing a relative import. It + specifies the package to use as the anchor point from which to resolve the + relative import to an absolute import. + + """ + level = 0 + if name.startswith('.'): + if not package: + msg = ("the 'package' argument is required to perform a relative " + "import for {!r}") + raise TypeError(msg.format(name)) + for character in name: + if character != '.': + break + level += 1 + return _bootstrap._gcd_import(name[level:], package, level) + + +_RELOADING = {} + + +def reload(module): + """Reload the module and return it. + + The module must have been successfully imported before. + + """ + if not module or not isinstance(module, types.ModuleType): + raise TypeError("reload() argument must be a module") + try: + name = module.__spec__.name + except AttributeError: + name = module.__name__ + + if sys.modules.get(name) is not module: + msg = "module {} not in sys.modules" + raise ImportError(msg.format(name), name=name) + if name in _RELOADING: + return _RELOADING[name] + _RELOADING[name] = module + try: + parent_name = name.rpartition('.')[0] + if parent_name: + try: + parent = sys.modules[parent_name] + except KeyError: + msg = "parent {!r} not in sys.modules" + raise ImportError(msg.format(parent_name), + name=parent_name) from None + else: + pkgpath = parent.__path__ + else: + pkgpath = None + target = module + spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) + if spec is None: + raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name) + _bootstrap._exec(spec, module) + # The module may have replaced itself in sys.modules! + return sys.modules[name] + finally: + try: + del _RELOADING[name] + except KeyError: + pass diff --git a/Lib/importlib/__pycache__/__init__.cpython-37.pyc b/Lib/importlib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd15769de2048d0bdb3595123cd1cd0d9dc279d2 GIT binary patch literal 3755 zcmai0&668P74M!Ijigzvto@AFNzCMf*a|@v2o+P5p<;Ut7|ddv5IbV2sabXJYIgPI zo|bLNql=x~k}B>LRoW^pT)A=K#E~P#VGbPNSH zy^d2idZqqGdjlR=5$@-#y(u=us#yD+w_g#jh;`whcQ#?|EwLdyd_O1rk6H8V^um>J zG*&XaHPPMSAWZtBp6ttkj&*|JaGxYYrCWIrMYbD7`Et?g55>4A^Oa<9Kkg+W)-vkE zovuuCU&-Du7EdX_J5Lc**5pvJHyr9zt9UeBw<>zcUh7nvR~ORh66_5U9Yw9tWV(Dh z2Scb@I~7Fop_Xb8_olBeRzIWj^z-IR));My_Sd1U(nA9e?=`&XJ7^w;njP|O_S?-F z(@uumeB!7|#^&xZCf}>vVZwng-D&??-0Ow9E5jEYah6o;c&cfj1k(bf6_}8I(oND3e{r}Mca9#!N_@LB>?6L( zUQdP(fQk{6#A-Mm2$K~NDZ1EvcKQBz&@sq_9wA3cb^tm`ns7h95AzGa60pWP>9r{M zUsp8U-acKKCWFob{U5Zx*9wsv1?XR<1Ex|fW6^p_0VYtV8mH;W`?9w)-FP%>MUiz! z6wzUKh66c0`+|5d)L|<1^c)@0IPTFb>?bLOENl_8X%Qi46vD(RQ^Wf9CH{a{wlh?j^aRnuy}54{<>%7zo>d>EGFF`~EFenQLYgn#Fl=fx zHa)dUIy^$Sdfjx%8wRDeIYYuFW5O!`83gIOXjsK}0`Bk{ukeOb;dSoe-E?Z`dw?JP zs8`|YP0U`Pv4jD=290fW1PA8W929oU)po|yw}m@%HP75RA&o8k@3#~L53HKP+ma7AB?HuP_`&} zZ=4Vdg6{?);6P!Zl!)=E2PY!jmV#R04Q+|C09$IHS7;6OFdQR~V=IjZoi4yJ8YVEa zuZDf-PdZ(irDQtnK`U6>sC&)~O^LzSdzgjLpBT4*R^-W?x28WO&i_9rf}-L)FCNAM z;0-lXM4&s(l0lWy>4QXf^Xey)QIT|8_-r$8DLUwgq9Qj-Hj~Q5>GP6-WA66TgLbvk zjaA%1iF_`x6al!8H(f`=DwH-J_nf*(9ZIbZl|p)mzo~YZthotk##BS2)%?(T;-qJ_ zi=qggp42jS=z+&MxcVHJnXYC(vdoMxRo2jKW2Ph7v3?hhFgpnUHx-X*U*`{7<;gdYoR^^+kdyV zg}>16!lq05MVYF@z5FiAyu-$ zUK5p!|K9n7lNI~K{Pm1#6)u`)7iPDUfOh*ss#>_*(QdGM+wRAD0hhuua8jLiZkyYZ z$zY2VB%MHRnhKNXMFo%rkiz~rE!b~Q0x9XZ(~)VqKkoG=MUDbQdlK-G#p3Ck_DY7E z$O3Uj%N}4-sGYu6SO*ysy`rp`dx*K_rA=Q~}0?J1TK^4kN8i@{0{)MqeS+BkcTX`ii1uTlJ{Z|Val?BL%(A6f% z+yklAH)u#W0Xg5ke)E@Cwr}kGBo7p}suN;ib&ftlC-E-U6OpUeNVaAT?+o>iX}6a5 zOSnMFPP3BxcGGqbP0VjE+2cpFk=(a~c6oGkK$>%3!_U~z8>FAmbIR$8E=6D9O|PP1 zegiyBfUEPG(*OupF{Ynmc%53}_kft*0Yv#a`m2~5I1Wj9lkd>qt9dz!#IS=KIy$&z zqT>-q*rK-*f%>L$P_PE7yFEL3EN8ioa;3*3)uJJ8-vyaK2Yj`k^x*5ftmLSNLY!B3 zaAxBm>-uvq=w95rRh1N$qX(#ig9CJw>8Ni(tk$R@nlX1sQ>zRwsrN}nZhFRb#)+mT zRxaCMfLh?hn`k^<3*a(1#JG{KdOr8zz*Sy%eNK+D@&Il-`O=^-c>NMqmTGRL61){` Hc<%oI_kjk` literal 0 HcmV?d00001 diff --git a/Lib/importlib/__pycache__/abc.cpython-37.pyc b/Lib/importlib/__pycache__/abc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a4c26e65663d6d74e69df2fe328627fd088d336 GIT binary patch literal 13509 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 literal 0 HcmV?d00001 diff --git a/Lib/importlib/__pycache__/machinery.cpython-37.pyc b/Lib/importlib/__pycache__/machinery.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19e2d1b98cada6b42cad81a9a5814269487595ee GIT binary patch literal 995 zcmZva&2G~`5XaYczQ5CeiUbE=BOxT{v4Ju^GKdcA^R6~4dt=otw8P{#ez0p7wZzJde@qd*IE zs$nfKf*jQ&0~;Cw&I9LgF5?1l9_KSI(n3_k#i)c!Q5lz`3a&&|T+L!7h}Cc{<1%m^ z*E6mFH*h24DsU4wGp+%*a4X|Fa2vOQ8$t66!bgE_qi$>aYQ7?7$)`Vqf5(9j|Wz7@y_jC&8_}q@JHbBWI7*RjIcHMPq6*( z{v+#hZjJ5HWV}BdGI;m_%3+_yjNF7m^35=-PUSxJsFFjge*R|ebuG=rG}#quc(1YB(-BC^5A*M6P)(OwXi{p1KK- zQj-&(-NfOR1ZI?V*c9vKGQ1_iTrzITRVd7aGaqv48oU7K^0E>&q2Ca1D^~Jz)<1O? z0&df>#_zAp=O@ltk_2+0TTtAC+gxCapn+ z?tMNT_=`{#BAqMlcG9Bj2F!QeH0QzzX~n%}OhW6ugd4Df=al3@(#|2|66hk2J-Vx= zsP>eU?CauHWvU+Xx{`*HrjnKt_47mFJ30biT6(=};Ttux;t@zrFX=T+Jx`3?H&f#m DRx}1; literal 0 HcmV?d00001 diff --git a/Lib/importlib/__pycache__/util.cpython-37.pyc b/Lib/importlib/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0001063adb48a23888cc58f202c4f0d930f2682c GIT binary patch literal 9379 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 0 + self.count -= 1 + if self.count == 0: + self.owner = None + if self.waiters: + self.waiters -= 1 + self.wakeup.release() + + def __repr__(self): + return '_ModuleLock({!r}) at {}'.format(self.name, id(self)) + + +class _DummyModuleLock: + """A simple _ModuleLock equivalent for Python builds without + multi-threading support.""" + + def __init__(self, name): + self.name = name + self.count = 0 + + def acquire(self): + self.count += 1 + return True + + def release(self): + if self.count == 0: + raise RuntimeError('cannot release un-acquired lock') + self.count -= 1 + + def __repr__(self): + return '_DummyModuleLock({!r}) at {}'.format(self.name, id(self)) + + +class _ModuleLockManager: + + def __init__(self, name): + self._name = name + self._lock = None + + def __enter__(self): + self._lock = _get_module_lock(self._name) + self._lock.acquire() + + def __exit__(self, *args, **kwargs): + self._lock.release() + + +# The following two functions are for consumption by Python/import.c. + +def _get_module_lock(name): + """Get or create the module lock for a given module name. + + Acquire/release internally the global import lock to protect + _module_locks.""" + + _imp.acquire_lock() + try: + try: + lock = _module_locks[name]() + except KeyError: + lock = None + + if lock is None: + if _thread is None: + lock = _DummyModuleLock(name) + else: + lock = _ModuleLock(name) + + def cb(ref, name=name): + _imp.acquire_lock() + try: + # bpo-31070: Check if another thread created a new lock + # after the previous lock was destroyed + # but before the weakref callback was called. + if _module_locks.get(name) is ref: + del _module_locks[name] + finally: + _imp.release_lock() + + _module_locks[name] = _weakref.ref(lock, cb) + finally: + _imp.release_lock() + + return lock + + +def _lock_unlock_module(name): + """Acquires then releases the module lock for a given module name. + + This is used to ensure a module is completely initialized, in the + event it is being imported by another thread. + """ + lock = _get_module_lock(name) + try: + lock.acquire() + except _DeadlockError: + # Concurrent circular import, we'll accept a partially initialized + # module object. + pass + else: + lock.release() + +# Frame stripping magic ############################################### +def _call_with_frames_removed(f, *args, **kwds): + """remove_importlib_frames in import.c will always remove sequences + of importlib frames that end with a call to this function + + Use it instead of a normal call in places where including the importlib + frames introduces unwanted noise into the traceback (e.g. when executing + module code) + """ + return f(*args, **kwds) + + +def _verbose_message(message, *args, verbosity=1): + """Print the message to stderr if -v/PYTHONVERBOSE is turned on.""" + if sys.flags.verbose >= verbosity: + if not message.startswith(('#', 'import ')): + message = '# ' + message + print(message.format(*args), file=sys.stderr) + + +def _requires_builtin(fxn): + """Decorator to verify the named module is built-in.""" + def _requires_builtin_wrapper(self, fullname): + if fullname not in sys.builtin_module_names: + raise ImportError('{!r} is not a built-in module'.format(fullname), + name=fullname) + return fxn(self, fullname) + _wrap(_requires_builtin_wrapper, fxn) + return _requires_builtin_wrapper + + +def _requires_frozen(fxn): + """Decorator to verify the named module is frozen.""" + def _requires_frozen_wrapper(self, fullname): + if not _imp.is_frozen(fullname): + raise ImportError('{!r} is not a frozen module'.format(fullname), + name=fullname) + return fxn(self, fullname) + _wrap(_requires_frozen_wrapper, fxn) + return _requires_frozen_wrapper + + +# Typically used by loader classes as a method replacement. +def _load_module_shim(self, fullname): + """Load the specified module into sys.modules and return it. + + This method is deprecated. Use loader.exec_module instead. + + """ + spec = spec_from_loader(fullname, self) + if fullname in sys.modules: + module = sys.modules[fullname] + _exec(spec, module) + return sys.modules[fullname] + else: + return _load(spec) + +# Module specifications ####################################################### + +def _module_repr(module): + # The implementation of ModuleType.__repr__(). + loader = getattr(module, '__loader__', None) + if hasattr(loader, 'module_repr'): + # As soon as BuiltinImporter, FrozenImporter, and NamespaceLoader + # drop their implementations for module_repr. we can add a + # deprecation warning here. + try: + return loader.module_repr(module) + except Exception: + pass + try: + spec = module.__spec__ + except AttributeError: + pass + else: + if spec is not None: + return _module_repr_from_spec(spec) + + # We could use module.__class__.__name__ instead of 'module' in the + # various repr permutations. + try: + name = module.__name__ + except AttributeError: + name = '?' + try: + filename = module.__file__ + except AttributeError: + if loader is None: + return ''.format(name) + else: + return ''.format(name, loader) + else: + return ''.format(name, filename) + + +class _installed_safely: + + def __init__(self, module): + self._module = module + self._spec = module.__spec__ + + def __enter__(self): + # This must be done before putting the module in sys.modules + # (otherwise an optimization shortcut in import.c becomes + # wrong) + self._spec._initializing = True + sys.modules[self._spec.name] = self._module + + def __exit__(self, *args): + try: + spec = self._spec + if any(arg is not None for arg in args): + try: + del sys.modules[spec.name] + except KeyError: + pass + else: + _verbose_message('import {!r} # {!r}', spec.name, spec.loader) + finally: + self._spec._initializing = False + + +class ModuleSpec: + """The specification for a module, used for loading. + + A module's spec is the source for information about the module. For + data associated with the module, including source, use the spec's + loader. + + `name` is the absolute name of the module. `loader` is the loader + to use when loading the module. `parent` is the name of the + package the module is in. The parent is derived from the name. + + `is_package` determines if the module is considered a package or + not. On modules this is reflected by the `__path__` attribute. + + `origin` is the specific location used by the loader from which to + load the module, if that information is available. When filename is + set, origin will match. + + `has_location` indicates that a spec's "origin" reflects a location. + When this is True, `__file__` attribute of the module is set. + + `cached` is the location of the cached bytecode file, if any. It + corresponds to the `__cached__` attribute. + + `submodule_search_locations` is the sequence of path entries to + search when importing submodules. If set, is_package should be + True--and False otherwise. + + Packages are simply modules that (may) have submodules. If a spec + has a non-None value in `submodule_search_locations`, the import + system will consider modules loaded from the spec as packages. + + Only finders (see importlib.abc.MetaPathFinder and + importlib.abc.PathEntryFinder) should modify ModuleSpec instances. + + """ + + def __init__(self, name, loader, *, origin=None, loader_state=None, + is_package=None): + self.name = name + self.loader = loader + self.origin = origin + self.loader_state = loader_state + self.submodule_search_locations = [] if is_package else None + + # file-location attributes + self._set_fileattr = False + self._cached = None + + def __repr__(self): + args = ['name={!r}'.format(self.name), + 'loader={!r}'.format(self.loader)] + if self.origin is not None: + args.append('origin={!r}'.format(self.origin)) + if self.submodule_search_locations is not None: + args.append('submodule_search_locations={}' + .format(self.submodule_search_locations)) + return '{}({})'.format(self.__class__.__name__, ', '.join(args)) + + def __eq__(self, other): + smsl = self.submodule_search_locations + try: + return (self.name == other.name and + self.loader == other.loader and + self.origin == other.origin and + smsl == other.submodule_search_locations and + self.cached == other.cached and + self.has_location == other.has_location) + except AttributeError: + return False + + @property + def cached(self): + if self._cached is None: + if self.origin is not None and self._set_fileattr: + if _bootstrap_external is None: + raise NotImplementedError + self._cached = _bootstrap_external._get_cached(self.origin) + return self._cached + + @cached.setter + def cached(self, cached): + self._cached = cached + + @property + def parent(self): + """The name of the module's parent.""" + if self.submodule_search_locations is None: + return self.name.rpartition('.')[0] + else: + return self.name + + @property + def has_location(self): + return self._set_fileattr + + @has_location.setter + def has_location(self, value): + self._set_fileattr = bool(value) + + +def spec_from_loader(name, loader, *, origin=None, is_package=None): + """Return a module spec based on various loader methods.""" + if hasattr(loader, 'get_filename'): + if _bootstrap_external is None: + raise NotImplementedError + spec_from_file_location = _bootstrap_external.spec_from_file_location + + if is_package is None: + return spec_from_file_location(name, loader=loader) + search = [] if is_package else None + return spec_from_file_location(name, loader=loader, + submodule_search_locations=search) + + if is_package is None: + if hasattr(loader, 'is_package'): + try: + is_package = loader.is_package(name) + except ImportError: + is_package = None # aka, undefined + else: + # the default + is_package = False + + return ModuleSpec(name, loader, origin=origin, is_package=is_package) + + +def _spec_from_module(module, loader=None, origin=None): + # This function is meant for use in _setup(). + try: + spec = module.__spec__ + except AttributeError: + pass + else: + if spec is not None: + return spec + + name = module.__name__ + if loader is None: + try: + loader = module.__loader__ + except AttributeError: + # loader will stay None. + pass + try: + location = module.__file__ + except AttributeError: + location = None + if origin is None: + if location is None: + try: + origin = loader._ORIGIN + except AttributeError: + origin = None + else: + origin = location + try: + cached = module.__cached__ + except AttributeError: + cached = None + try: + submodule_search_locations = list(module.__path__) + except AttributeError: + submodule_search_locations = None + + spec = ModuleSpec(name, loader, origin=origin) + spec._set_fileattr = False if location is None else True + spec.cached = cached + spec.submodule_search_locations = submodule_search_locations + return spec + + +def _init_module_attrs(spec, module, *, override=False): + # The passed-in module may be not support attribute assignment, + # in which case we simply don't set the attributes. + # __name__ + if (override or getattr(module, '__name__', None) is None): + try: + module.__name__ = spec.name + except AttributeError: + pass + # __loader__ + if override or getattr(module, '__loader__', None) is None: + loader = spec.loader + if loader is None: + # A backward compatibility hack. + if spec.submodule_search_locations is not None: + if _bootstrap_external is None: + raise NotImplementedError + _NamespaceLoader = _bootstrap_external._NamespaceLoader + + loader = _NamespaceLoader.__new__(_NamespaceLoader) + loader._path = spec.submodule_search_locations + spec.loader = loader + # While the docs say that module.__file__ is not set for + # built-in modules, and the code below will avoid setting it if + # spec.has_location is false, this is incorrect for namespace + # packages. Namespace packages have no location, but their + # __spec__.origin is None, and thus their module.__file__ + # should also be None for consistency. While a bit of a hack, + # this is the best place to ensure this consistency. + # + # See # https://docs.python.org/3/library/importlib.html#importlib.abc.Loader.load_module + # and bpo-32305 + module.__file__ = None + try: + module.__loader__ = loader + except AttributeError: + pass + # __package__ + if override or getattr(module, '__package__', None) is None: + try: + module.__package__ = spec.parent + except AttributeError: + pass + # __spec__ + try: + module.__spec__ = spec + except AttributeError: + pass + # __path__ + if override or getattr(module, '__path__', None) is None: + if spec.submodule_search_locations is not None: + try: + module.__path__ = spec.submodule_search_locations + except AttributeError: + pass + # __file__/__cached__ + if spec.has_location: + if override or getattr(module, '__file__', None) is None: + try: + module.__file__ = spec.origin + except AttributeError: + pass + + if override or getattr(module, '__cached__', None) is None: + if spec.cached is not None: + try: + module.__cached__ = spec.cached + except AttributeError: + pass + return module + + +def module_from_spec(spec): + """Create a module based on the provided spec.""" + # Typically loaders will not implement create_module(). + module = None + if hasattr(spec.loader, 'create_module'): + # If create_module() returns `None` then it means default + # module creation should be used. + module = spec.loader.create_module(spec) + elif hasattr(spec.loader, 'exec_module'): + raise ImportError('loaders that define exec_module() ' + 'must also define create_module()') + if module is None: + module = _new_module(spec.name) + _init_module_attrs(spec, module) + return module + + +def _module_repr_from_spec(spec): + """Return the repr to use for the module.""" + # We mostly replicate _module_repr() using the spec attributes. + name = '?' if spec.name is None else spec.name + if spec.origin is None: + if spec.loader is None: + return ''.format(name) + else: + return ''.format(name, spec.loader) + else: + if spec.has_location: + return ''.format(name, spec.origin) + else: + return ''.format(spec.name, spec.origin) + + +# Used by importlib.reload() and _load_module_shim(). +def _exec(spec, module): + """Execute the spec's specified module in an existing module's namespace.""" + name = spec.name + with _ModuleLockManager(name): + if sys.modules.get(name) is not module: + msg = 'module {!r} not in sys.modules'.format(name) + raise ImportError(msg, name=name) + if spec.loader is None: + if spec.submodule_search_locations is None: + raise ImportError('missing loader', name=spec.name) + # namespace package + _init_module_attrs(spec, module, override=True) + return module + _init_module_attrs(spec, module, override=True) + if not hasattr(spec.loader, 'exec_module'): + # (issue19713) Once BuiltinImporter and ExtensionFileLoader + # have exec_module() implemented, we can add a deprecation + # warning here. + spec.loader.load_module(name) + else: + spec.loader.exec_module(module) + return sys.modules[name] + + +def _load_backward_compatible(spec): + # (issue19713) Once BuiltinImporter and ExtensionFileLoader + # have exec_module() implemented, we can add a deprecation + # warning here. + spec.loader.load_module(spec.name) + # The module must be in sys.modules at this point! + module = sys.modules[spec.name] + if getattr(module, '__loader__', None) is None: + try: + module.__loader__ = spec.loader + except AttributeError: + pass + if getattr(module, '__package__', None) is None: + try: + # Since module.__path__ may not line up with + # spec.submodule_search_paths, we can't necessarily rely + # on spec.parent here. + module.__package__ = module.__name__ + if not hasattr(module, '__path__'): + module.__package__ = spec.name.rpartition('.')[0] + except AttributeError: + pass + if getattr(module, '__spec__', None) is None: + try: + module.__spec__ = spec + except AttributeError: + pass + return module + +def _load_unlocked(spec): + # A helper for direct use by the import system. + if spec.loader is not None: + # not a namespace package + if not hasattr(spec.loader, 'exec_module'): + return _load_backward_compatible(spec) + + module = module_from_spec(spec) + with _installed_safely(module): + if spec.loader is None: + if spec.submodule_search_locations is None: + raise ImportError('missing loader', name=spec.name) + # A namespace package so do nothing. + else: + spec.loader.exec_module(module) + + # We don't ensure that the import-related module attributes get + # set in the sys.modules replacement case. Such modules are on + # their own. + return sys.modules[spec.name] + +# A method used during testing of _load_unlocked() and by +# _load_module_shim(). +def _load(spec): + """Return a new module object, loaded by the spec's loader. + + The module is not added to its parent. + + If a module is already in sys.modules, that existing module gets + clobbered. + + """ + with _ModuleLockManager(spec.name): + return _load_unlocked(spec) + + +# Loaders ##################################################################### + +class BuiltinImporter: + + """Meta path import for built-in modules. + + All methods are either class or static methods to avoid the need to + instantiate the class. + + """ + + @staticmethod + def module_repr(module): + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ + return ''.format(module.__name__) + + @classmethod + def find_spec(cls, fullname, path=None, target=None): + if path is not None: + return None + if _imp.is_builtin(fullname): + return spec_from_loader(fullname, cls, origin='built-in') + else: + return None + + @classmethod + def find_module(cls, fullname, path=None): + """Find the built-in module. + + If 'path' is ever specified then the search is considered a failure. + + This method is deprecated. Use find_spec() instead. + + """ + spec = cls.find_spec(fullname, path) + return spec.loader if spec is not None else None + + @classmethod + def create_module(self, spec): + """Create a built-in module""" + if spec.name not in sys.builtin_module_names: + raise ImportError('{!r} is not a built-in module'.format(spec.name), + name=spec.name) + return _call_with_frames_removed(_imp.create_builtin, spec) + + @classmethod + def exec_module(self, module): + """Exec a built-in module""" + _call_with_frames_removed(_imp.exec_builtin, module) + + @classmethod + @_requires_builtin + def get_code(cls, fullname): + """Return None as built-in modules do not have code objects.""" + return None + + @classmethod + @_requires_builtin + def get_source(cls, fullname): + """Return None as built-in modules do not have source code.""" + return None + + @classmethod + @_requires_builtin + def is_package(cls, fullname): + """Return False as built-in modules are never packages.""" + return False + + load_module = classmethod(_load_module_shim) + + +class FrozenImporter: + + """Meta path import for frozen modules. + + All methods are either class or static methods to avoid the need to + instantiate the class. + + """ + + @staticmethod + def module_repr(m): + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ + return ''.format(m.__name__) + + @classmethod + def find_spec(cls, fullname, path=None, target=None): + if _imp.is_frozen(fullname): + return spec_from_loader(fullname, cls, origin='frozen') + else: + return None + + @classmethod + def find_module(cls, fullname, path=None): + """Find a frozen module. + + This method is deprecated. Use find_spec() instead. + + """ + return cls if _imp.is_frozen(fullname) else None + + @classmethod + def create_module(cls, spec): + """Use default semantics for module creation.""" + + @staticmethod + def exec_module(module): + name = module.__spec__.name + if not _imp.is_frozen(name): + raise ImportError('{!r} is not a frozen module'.format(name), + name=name) + code = _call_with_frames_removed(_imp.get_frozen_object, name) + exec(code, module.__dict__) + + @classmethod + def load_module(cls, fullname): + """Load a frozen module. + + This method is deprecated. Use exec_module() instead. + + """ + return _load_module_shim(cls, fullname) + + @classmethod + @_requires_frozen + def get_code(cls, fullname): + """Return the code object for the frozen module.""" + return _imp.get_frozen_object(fullname) + + @classmethod + @_requires_frozen + def get_source(cls, fullname): + """Return None as frozen modules do not have source code.""" + return None + + @classmethod + @_requires_frozen + def is_package(cls, fullname): + """Return True if the frozen module is a package.""" + return _imp.is_frozen_package(fullname) + + +# Import itself ############################################################### + +class _ImportLockContext: + + """Context manager for the import lock.""" + + def __enter__(self): + """Acquire the import lock.""" + _imp.acquire_lock() + + def __exit__(self, exc_type, exc_value, exc_traceback): + """Release the import lock regardless of any raised exceptions.""" + _imp.release_lock() + + +def _resolve_name(name, package, level): + """Resolve a relative module name to an absolute one.""" + bits = package.rsplit('.', level - 1) + if len(bits) < level: + raise ValueError('attempted relative import beyond top-level package') + base = bits[0] + return '{}.{}'.format(base, name) if name else base + + +def _find_spec_legacy(finder, name, path): + # This would be a good place for a DeprecationWarning if + # we ended up going that route. + loader = finder.find_module(name, path) + if loader is None: + return None + return spec_from_loader(name, loader) + + +def _find_spec(name, path, target=None): + """Find a module's spec.""" + meta_path = sys.meta_path + if meta_path is None: + # PyImport_Cleanup() is running or has been called. + raise ImportError("sys.meta_path is None, Python is likely " + "shutting down") + + if not meta_path: + _warnings.warn('sys.meta_path is empty', ImportWarning) + + # We check sys.modules here for the reload case. While a passed-in + # target will usually indicate a reload there is no guarantee, whereas + # sys.modules provides one. + is_reload = name in sys.modules + for finder in meta_path: + with _ImportLockContext(): + try: + find_spec = finder.find_spec + except AttributeError: + spec = _find_spec_legacy(finder, name, path) + if spec is None: + continue + else: + spec = find_spec(name, path, target) + if spec is not None: + # The parent import may have already imported this module. + if not is_reload and name in sys.modules: + module = sys.modules[name] + try: + __spec__ = module.__spec__ + except AttributeError: + # We use the found spec since that is the one that + # we would have used if the parent module hadn't + # beaten us to the punch. + return spec + else: + if __spec__ is None: + return spec + else: + return __spec__ + else: + return spec + else: + return None + + +def _sanity_check(name, package, level): + """Verify arguments are "sane".""" + if not isinstance(name, str): + raise TypeError('module name must be str, not {}'.format(type(name))) + if level < 0: + raise ValueError('level must be >= 0') + if level > 0: + if not isinstance(package, str): + raise TypeError('__package__ not set to a string') + elif not package: + raise ImportError('attempted relative import with no known parent ' + 'package') + if not name and level == 0: + raise ValueError('Empty module name') + + +_ERR_MSG_PREFIX = 'No module named ' +_ERR_MSG = _ERR_MSG_PREFIX + '{!r}' + +def _find_and_load_unlocked(name, import_): + path = None + parent = name.rpartition('.')[0] + if parent: + if parent not in sys.modules: + _call_with_frames_removed(import_, parent) + # Crazy side-effects! + if name in sys.modules: + return sys.modules[name] + parent_module = sys.modules[parent] + try: + path = parent_module.__path__ + except AttributeError: + msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent) + raise ModuleNotFoundError(msg, name=name) from None + spec = _find_spec(name, path) + if spec is None: + raise ModuleNotFoundError(_ERR_MSG.format(name), name=name) + else: + module = _load_unlocked(spec) + if parent: + # Set the module as an attribute on its parent. + parent_module = sys.modules[parent] + setattr(parent_module, name.rpartition('.')[2], module) + return module + + +_NEEDS_LOADING = object() + + +def _find_and_load(name, import_): + """Find and load the module.""" + with _ModuleLockManager(name): + module = sys.modules.get(name, _NEEDS_LOADING) + if module is _NEEDS_LOADING: + return _find_and_load_unlocked(name, import_) + + if module is None: + message = ('import of {} halted; ' + 'None in sys.modules'.format(name)) + raise ModuleNotFoundError(message, name=name) + + _lock_unlock_module(name) + return module + + +def _gcd_import(name, package=None, level=0): + """Import and return the module based on its name, the package the call is + being made from, and the level adjustment. + + This function represents the greatest common denominator of functionality + between import_module and __import__. This includes setting __package__ if + the loader did not. + + """ + _sanity_check(name, package, level) + if level > 0: + name = _resolve_name(name, package, level) + return _find_and_load(name, _gcd_import) + + +def _handle_fromlist(module, fromlist, import_, *, recursive=False): + """Figure out what __import__ should return. + + The import_ parameter is a callable which takes the name of module to + import. It is required to decouple the function from assuming importlib's + import implementation is desired. + + """ + # The hell that is fromlist ... + # If a package was imported, try to import stuff from fromlist. + if hasattr(module, '__path__'): + for x in fromlist: + if not isinstance(x, str): + if recursive: + where = module.__name__ + '.__all__' + else: + where = "``from list''" + raise TypeError(f"Item in {where} must be str, " + f"not {type(x).__name__}") + elif x == '*': + if not recursive and hasattr(module, '__all__'): + _handle_fromlist(module, module.__all__, import_, + recursive=True) + elif not hasattr(module, x): + from_name = '{}.{}'.format(module.__name__, x) + try: + _call_with_frames_removed(import_, from_name) + except ModuleNotFoundError as exc: + # Backwards-compatibility dictates we ignore failed + # imports triggered by fromlist for modules that don't + # exist. + if (exc.name == from_name and + sys.modules.get(from_name, _NEEDS_LOADING) is not None): + continue + raise + return module + + +def _calc___package__(globals): + """Calculate what __package__ should be. + + __package__ is not guaranteed to be defined or could be set to None + to represent that its proper value is unknown. + + """ + package = globals.get('__package__') + spec = globals.get('__spec__') + if package is not None: + if spec is not None and package != spec.parent: + _warnings.warn("__package__ != __spec__.parent " + f"({package!r} != {spec.parent!r})", + ImportWarning, stacklevel=3) + return package + elif spec is not None: + return spec.parent + else: + _warnings.warn("can't resolve package from __spec__ or __package__, " + "falling back on __name__ and __path__", + ImportWarning, stacklevel=3) + package = globals['__name__'] + if '__path__' not in globals: + package = package.rpartition('.')[0] + return package + + +def __import__(name, globals=None, locals=None, fromlist=(), level=0): + """Import a module. + + The 'globals' argument is used to infer where the import is occurring from + to handle relative imports. The 'locals' argument is ignored. The + 'fromlist' argument specifies what should exist as attributes on the module + being imported (e.g. ``from module import ``). The 'level' + argument represents the package location to import from in a relative + import (e.g. ``from ..pkg import mod`` would have a 'level' of 2). + + """ + if level == 0: + module = _gcd_import(name) + else: + globals_ = globals if globals is not None else {} + package = _calc___package__(globals_) + module = _gcd_import(name, package, level) + if not fromlist: + # Return up to the first dot in 'name'. This is complicated by the fact + # that 'name' may be relative. + if level == 0: + return _gcd_import(name.partition('.')[0]) + elif not name: + return module + else: + # Figure out where to slice the module's name up to the first dot + # in 'name'. + cut_off = len(name) - len(name.partition('.')[0]) + # Slice end needs to be positive to alleviate need to special-case + # when ``'.' not in name``. + return sys.modules[module.__name__[:len(module.__name__)-cut_off]] + else: + return _handle_fromlist(module, fromlist, _gcd_import) + + +def _builtin_from_name(name): + spec = BuiltinImporter.find_spec(name) + if spec is None: + raise ImportError('no built-in module named ' + name) + return _load_unlocked(spec) + + +def _setup(sys_module, _imp_module): + """Setup importlib by importing needed built-in modules and injecting them + into the global namespace. + + As sys is needed for sys.modules access and _imp is needed to load built-in + modules, those two modules must be explicitly passed in. + + """ + global _imp, sys + _imp = _imp_module + sys = sys_module + + # Set up the spec for existing builtin/frozen modules. + module_type = type(sys) + for name, module in sys.modules.items(): + if isinstance(module, module_type): + if name in sys.builtin_module_names: + loader = BuiltinImporter + elif _imp.is_frozen(name): + loader = FrozenImporter + else: + continue + spec = _spec_from_module(module, loader) + _init_module_attrs(spec, module) + + # Directly load built-in modules needed during bootstrap. + self_module = sys.modules[__name__] + for builtin_name in ('_thread', '_warnings', '_weakref'): + if builtin_name not in sys.modules: + builtin_module = _builtin_from_name(builtin_name) + else: + builtin_module = sys.modules[builtin_name] + setattr(self_module, builtin_name, builtin_module) + + +def _install(sys_module, _imp_module): + """Install importers for builtin and frozen modules""" + _setup(sys_module, _imp_module) + + sys.meta_path.append(BuiltinImporter) + sys.meta_path.append(FrozenImporter) + + +def _install_external_importers(): + """Install importers that require external filesystem access""" + global _bootstrap_external + import _frozen_importlib_external + _bootstrap_external = _frozen_importlib_external + _frozen_importlib_external._install(sys.modules[__name__]) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py new file mode 100644 index 0000000..53b24ff --- /dev/null +++ b/Lib/importlib/_bootstrap_external.py @@ -0,0 +1,1562 @@ +"""Core implementation of path-based import. + +This module is NOT meant to be directly imported! It has been designed such +that it can be bootstrapped into Python as the implementation of import. As +such it requires the injection of specific modules and attributes in order to +work. One should use importlib as the public-facing version of this module. + +""" +# IMPORTANT: Whenever making changes to this module, be sure to run a top-level +# `make regen-importlib` followed by `make` in order to get the frozen version +# of the module updated. Not doing so will result in the Makefile to fail for +# all others who don't have a ./python around to freeze the module in the early +# stages of compilation. +# + +# See importlib._setup() for what is injected into the global namespace. + +# When editing this code be aware that code executed at import time CANNOT +# reference any injected objects! This includes not only global code but also +# anything specified at the class level. + +# Bootstrap-related code ###################################################### +_CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win', +_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin' +_CASE_INSENSITIVE_PLATFORMS = (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY + + _CASE_INSENSITIVE_PLATFORMS_STR_KEY) + + +def _make_relax_case(): + if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): + if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS_STR_KEY): + key = 'PYTHONCASEOK' + else: + key = b'PYTHONCASEOK' + + def _relax_case(): + """True if filenames must be checked case-insensitively.""" + return key in _os.environ + else: + def _relax_case(): + """True if filenames must be checked case-insensitively.""" + return False + return _relax_case + + +def _w_long(x): + """Convert a 32-bit integer to little-endian.""" + return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little') + + +def _r_long(int_bytes): + """Convert 4 bytes in little-endian to an integer.""" + return int.from_bytes(int_bytes, 'little') + + +def _path_join(*path_parts): + """Replacement for os.path.join().""" + return path_sep.join([part.rstrip(path_separators) + for part in path_parts if part]) + + +def _path_split(path): + """Replacement for os.path.split().""" + if len(path_separators) == 1: + front, _, tail = path.rpartition(path_sep) + return front, tail + for x in reversed(path): + if x in path_separators: + front, tail = path.rsplit(x, maxsplit=1) + return front, tail + return '', path + + +def _path_stat(path): + """Stat the path. + + Made a separate function to make it easier to override in experiments + (e.g. cache stat results). + + """ + return _os.stat(path) + + +def _path_is_mode_type(path, mode): + """Test whether the path is the specified mode type.""" + try: + stat_info = _path_stat(path) + except OSError: + return False + return (stat_info.st_mode & 0o170000) == mode + + +def _path_isfile(path): + """Replacement for os.path.isfile.""" + return _path_is_mode_type(path, 0o100000) + + +def _path_isdir(path): + """Replacement for os.path.isdir.""" + if not path: + path = _os.getcwd() + return _path_is_mode_type(path, 0o040000) + + +def _write_atomic(path, data, mode=0o666): + """Best-effort function to write data to a path atomically. + Be prepared to handle a FileExistsError if concurrent writing of the + temporary file is attempted.""" + # id() is used to generate a pseudo-random filename. + path_tmp = '{}.{}'.format(path, id(path)) + fd = _os.open(path_tmp, + _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666) + try: + # We first write data to a temporary file, and then use os.replace() to + # perform an atomic rename. + with _io.FileIO(fd, 'wb') as file: + file.write(data) + _os.replace(path_tmp, path) + except OSError: + try: + _os.unlink(path_tmp) + except OSError: + pass + raise + + +_code_type = type(_write_atomic.__code__) + + +# Finder/loader utility code ############################################### + +# Magic word to reject .pyc files generated by other Python versions. +# It should change for each incompatible change to the bytecode. +# +# The value of CR and LF is incorporated so if you ever read or write +# a .pyc file in text mode the magic number will be wrong; also, the +# Apple MPW compiler swaps their values, botching string constants. +# +# There were a variety of old schemes for setting the magic number. +# The current working scheme is to increment the previous value by +# 10. +# +# Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic +# number also includes a new "magic tag", i.e. a human readable string used +# to represent the magic number in __pycache__ directories. When you change +# the magic number, you must also set a new unique magic tag. Generally this +# can be named after the Python major version of the magic number bump, but +# it can really be anything, as long as it's different than anything else +# that's come before. The tags are included in the following table, starting +# with Python 3.2a0. +# +# Known values: +# Python 1.5: 20121 +# Python 1.5.1: 20121 +# Python 1.5.2: 20121 +# Python 1.6: 50428 +# Python 2.0: 50823 +# Python 2.0.1: 50823 +# Python 2.1: 60202 +# Python 2.1.1: 60202 +# Python 2.1.2: 60202 +# Python 2.2: 60717 +# Python 2.3a0: 62011 +# Python 2.3a0: 62021 +# Python 2.3a0: 62011 (!) +# Python 2.4a0: 62041 +# Python 2.4a3: 62051 +# Python 2.4b1: 62061 +# Python 2.5a0: 62071 +# Python 2.5a0: 62081 (ast-branch) +# Python 2.5a0: 62091 (with) +# Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) +# Python 2.5b3: 62101 (fix wrong code: for x, in ...) +# Python 2.5b3: 62111 (fix wrong code: x += yield) +# Python 2.5c1: 62121 (fix wrong lnotab with for loops and +# storing constants that should have been removed) +# Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) +# Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) +# Python 2.6a1: 62161 (WITH_CLEANUP optimization) +# Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND) +# Python 2.7a0: 62181 (optimize conditional branches: +# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) +# Python 2.7a0 62191 (introduce SETUP_WITH) +# Python 2.7a0 62201 (introduce BUILD_SET) +# Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD) +# Python 3000: 3000 +# 3010 (removed UNARY_CONVERT) +# 3020 (added BUILD_SET) +# 3030 (added keyword-only parameters) +# 3040 (added signature annotations) +# 3050 (print becomes a function) +# 3060 (PEP 3115 metaclass syntax) +# 3061 (string literals become unicode) +# 3071 (PEP 3109 raise changes) +# 3081 (PEP 3137 make __file__ and __name__ unicode) +# 3091 (kill str8 interning) +# 3101 (merge from 2.6a0, see 62151) +# 3103 (__file__ points to source file) +# Python 3.0a4: 3111 (WITH_CLEANUP optimization). +# Python 3.0b1: 3131 (lexical exception stacking, including POP_EXCEPT + #3021) +# Python 3.1a1: 3141 (optimize list, set and dict comprehensions: +# change LIST_APPEND and SET_ADD, add MAP_ADD #2183) +# Python 3.1a1: 3151 (optimize conditional branches: +# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE + #4715) +# Python 3.2a1: 3160 (add SETUP_WITH #6101) +# tag: cpython-32 +# Python 3.2a2: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR #9225) +# tag: cpython-32 +# Python 3.2a3 3180 (add DELETE_DEREF #4617) +# Python 3.3a1 3190 (__class__ super closure changed) +# Python 3.3a1 3200 (PEP 3155 __qualname__ added #13448) +# Python 3.3a1 3210 (added size modulo 2**32 to the pyc header #13645) +# Python 3.3a2 3220 (changed PEP 380 implementation #14230) +# Python 3.3a4 3230 (revert changes to implicit __class__ closure #14857) +# Python 3.4a1 3250 (evaluate positional default arguments before +# keyword-only defaults #16967) +# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override +# free vars #17853) +# Python 3.4a1 3270 (various tweaks to the __class__ closure #12370) +# Python 3.4a1 3280 (remove implicit class argument) +# Python 3.4a4 3290 (changes to __qualname__ computation #19301) +# Python 3.4a4 3300 (more changes to __qualname__ computation #19301) +# Python 3.4rc2 3310 (alter __qualname__ computation #20625) +# Python 3.5a1 3320 (PEP 465: Matrix multiplication operator #21176) +# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations #2292) +# Python 3.5b2 3340 (fix dictionary display evaluation order #11205) +# Python 3.5b3 3350 (add GET_YIELD_FROM_ITER opcode #24400) +# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286) +# Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483) +# Python 3.6a1 3361 (lineno delta of code.co_lnotab becomes signed #26107) +# Python 3.6a2 3370 (16 bit wordcode #26647) +# Python 3.6a2 3371 (add BUILD_CONST_KEY_MAP opcode #27140) +# Python 3.6a2 3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE +# #27095) +# Python 3.6b1 3373 (add BUILD_STRING opcode #27078) +# Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes +# #27985) +# Python 3.6b1 3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL + #27213) +# Python 3.6b1 3377 (set __class__ cell from type.__new__ #23722) +# Python 3.6b2 3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257) +# Python 3.6rc1 3379 (more thorough __class__ validation #23722) +# Python 3.7a1 3390 (add LOAD_METHOD and CALL_METHOD opcodes #26110) +# Python 3.7a2 3391 (update GET_AITER #31709) +# Python 3.7a4 3392 (PEP 552: Deterministic pycs #31650) +# Python 3.7b1 3393 (remove STORE_ANNOTATION opcode #32550) +# Python 3.7b5 3394 (restored docstring as the firts stmt in the body; +# this might affected the first line number #32911) +# +# MAGIC must change whenever the bytecode emitted by the compiler may no +# longer be understood by older implementations of the eval loop (usually +# due to the addition of new opcodes). +# +# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array +# in PC/launcher.c must also be updated. + +MAGIC_NUMBER = (3394).to_bytes(2, 'little') + b'\r\n' +_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c + +_PYCACHE = '__pycache__' +_OPT = 'opt-' + +SOURCE_SUFFIXES = ['.py'] # _setup() adds .pyw as needed. + +BYTECODE_SUFFIXES = ['.pyc'] +# Deprecated. +DEBUG_BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES = BYTECODE_SUFFIXES + +def cache_from_source(path, debug_override=None, *, optimization=None): + """Given the path to a .py file, return the path to its .pyc file. + + The .py file does not need to exist; this simply returns the path to the + .pyc file calculated as if the .py file were imported. + + The 'optimization' parameter controls the presumed optimization level of + the bytecode file. If 'optimization' is not None, the string representation + of the argument is taken and verified to be alphanumeric (else ValueError + is raised). + + The debug_override parameter is deprecated. If debug_override is not None, + a True value is the same as setting 'optimization' to the empty string + while a False value is equivalent to setting 'optimization' to '1'. + + If sys.implementation.cache_tag is None then NotImplementedError is raised. + + """ + if debug_override is not None: + _warnings.warn('the debug_override parameter is deprecated; use ' + "'optimization' instead", DeprecationWarning) + if optimization is not None: + message = 'debug_override or optimization must be set to None' + raise TypeError(message) + optimization = '' if debug_override else 1 + path = _os.fspath(path) + head, tail = _path_split(path) + base, sep, rest = tail.rpartition('.') + tag = sys.implementation.cache_tag + if tag is None: + raise NotImplementedError('sys.implementation.cache_tag is None') + almost_filename = ''.join([(base if base else rest), sep, tag]) + if optimization is None: + if sys.flags.optimize == 0: + optimization = '' + else: + optimization = sys.flags.optimize + optimization = str(optimization) + if optimization != '': + if not optimization.isalnum(): + raise ValueError('{!r} is not alphanumeric'.format(optimization)) + almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization) + return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0]) + + +def source_from_cache(path): + """Given the path to a .pyc. file, return the path to its .py file. + + The .pyc file does not need to exist; this simply returns the path to + the .py file calculated to correspond to the .pyc file. If path does + not conform to PEP 3147/488 format, ValueError will be raised. If + sys.implementation.cache_tag is None then NotImplementedError is raised. + + """ + if sys.implementation.cache_tag is None: + raise NotImplementedError('sys.implementation.cache_tag is None') + path = _os.fspath(path) + head, pycache_filename = _path_split(path) + head, pycache = _path_split(head) + if pycache != _PYCACHE: + raise ValueError('{} not bottom-level directory in ' + '{!r}'.format(_PYCACHE, path)) + dot_count = pycache_filename.count('.') + if dot_count not in {2, 3}: + raise ValueError('expected only 2 or 3 dots in ' + '{!r}'.format(pycache_filename)) + elif dot_count == 3: + optimization = pycache_filename.rsplit('.', 2)[-2] + if not optimization.startswith(_OPT): + raise ValueError("optimization portion of filename does not start " + "with {!r}".format(_OPT)) + opt_level = optimization[len(_OPT):] + if not opt_level.isalnum(): + raise ValueError("optimization level {!r} is not an alphanumeric " + "value".format(optimization)) + base_filename = pycache_filename.partition('.')[0] + return _path_join(head, base_filename + SOURCE_SUFFIXES[0]) + + +def _get_sourcefile(bytecode_path): + """Convert a bytecode file path to a source path (if possible). + + This function exists purely for backwards-compatibility for + PyImport_ExecCodeModuleWithFilenames() in the C API. + + """ + if len(bytecode_path) == 0: + return None + rest, _, extension = bytecode_path.rpartition('.') + if not rest or extension.lower()[-3:-1] != 'py': + return bytecode_path + try: + source_path = source_from_cache(bytecode_path) + except (NotImplementedError, ValueError): + source_path = bytecode_path[:-1] + return source_path if _path_isfile(source_path) else bytecode_path + + +def _get_cached(filename): + if filename.endswith(tuple(SOURCE_SUFFIXES)): + try: + return cache_from_source(filename) + except NotImplementedError: + pass + elif filename.endswith(tuple(BYTECODE_SUFFIXES)): + return filename + else: + return None + + +def _calc_mode(path): + """Calculate the mode permissions for a bytecode file.""" + try: + mode = _path_stat(path).st_mode + except OSError: + mode = 0o666 + # We always ensure write access so we can update cached files + # later even when the source files are read-only on Windows (#6074) + mode |= 0o200 + return mode + + +def _check_name(method): + """Decorator to verify that the module being requested matches the one the + loader can handle. + + The first argument (self) must define _name which the second argument is + compared against. If the comparison fails then ImportError is raised. + + """ + def _check_name_wrapper(self, name=None, *args, **kwargs): + if name is None: + name = self.name + elif self.name != name: + raise ImportError('loader for %s cannot handle %s' % + (self.name, name), name=name) + return method(self, name, *args, **kwargs) + try: + _wrap = _bootstrap._wrap + except NameError: + # XXX yuck + def _wrap(new, old): + for replace in ['__module__', '__name__', '__qualname__', '__doc__']: + if hasattr(old, replace): + setattr(new, replace, getattr(old, replace)) + new.__dict__.update(old.__dict__) + _wrap(_check_name_wrapper, method) + return _check_name_wrapper + + +def _find_module_shim(self, fullname): + """Try to find a loader for the specified module by delegating to + self.find_loader(). + + This method is deprecated in favor of finder.find_spec(). + + """ + # Call find_loader(). If it returns a string (indicating this + # is a namespace package portion), generate a warning and + # return None. + loader, portions = self.find_loader(fullname) + if loader is None and len(portions): + msg = 'Not importing directory {}: missing __init__' + _warnings.warn(msg.format(portions[0]), ImportWarning) + return loader + + +def _classify_pyc(data, name, exc_details): + """Perform basic validity checking of a pyc header and return the flags field, + which determines how the pyc should be further validated against the source. + + *data* is the contents of the pyc file. (Only the first 16 bytes are + required, though.) + + *name* is the name of the module being imported. It is used for logging. + + *exc_details* is a dictionary passed to ImportError if it raised for + improved debugging. + + ImportError is raised when the magic number is incorrect or when the flags + field is invalid. EOFError is raised when the data is found to be truncated. + + """ + magic = data[:4] + if magic != MAGIC_NUMBER: + message = f'bad magic number in {name!r}: {magic!r}' + _bootstrap._verbose_message('{}', message) + raise ImportError(message, **exc_details) + if len(data) < 16: + message = f'reached EOF while reading pyc header of {name!r}' + _bootstrap._verbose_message('{}', message) + raise EOFError(message) + flags = _r_long(data[4:8]) + # Only the first two flags are defined. + if flags & ~0b11: + message = f'invalid flags {flags!r} in {name!r}' + raise ImportError(message, **exc_details) + return flags + + +def _validate_timestamp_pyc(data, source_mtime, source_size, name, + exc_details): + """Validate a pyc against the source last-modified time. + + *data* is the contents of the pyc file. (Only the first 16 bytes are + required.) + + *source_mtime* is the last modified timestamp of the source file. + + *source_size* is None or the size of the source file in bytes. + + *name* is the name of the module being imported. It is used for logging. + + *exc_details* is a dictionary passed to ImportError if it raised for + improved debugging. + + An ImportError is raised if the bytecode is stale. + + """ + if _r_long(data[8:12]) != (source_mtime & 0xFFFFFFFF): + message = f'bytecode is stale for {name!r}' + _bootstrap._verbose_message('{}', message) + raise ImportError(message, **exc_details) + if (source_size is not None and + _r_long(data[12:16]) != (source_size & 0xFFFFFFFF)): + raise ImportError(f'bytecode is stale for {name!r}', **exc_details) + + +def _validate_hash_pyc(data, source_hash, name, exc_details): + """Validate a hash-based pyc by checking the real source hash against the one in + the pyc header. + + *data* is the contents of the pyc file. (Only the first 16 bytes are + required.) + + *source_hash* is the importlib.util.source_hash() of the source file. + + *name* is the name of the module being imported. It is used for logging. + + *exc_details* is a dictionary passed to ImportError if it raised for + improved debugging. + + An ImportError is raised if the bytecode is stale. + + """ + if data[8:16] != source_hash: + raise ImportError( + f'hash in bytecode doesn\'t match hash of source {name!r}', + **exc_details, + ) + + +def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None): + """Compile bytecode as found in a pyc.""" + code = marshal.loads(data) + if isinstance(code, _code_type): + _bootstrap._verbose_message('code object from {!r}', bytecode_path) + if source_path is not None: + _imp._fix_co_filename(code, source_path) + return code + else: + raise ImportError('Non-code object in {!r}'.format(bytecode_path), + name=name, path=bytecode_path) + + +def _code_to_timestamp_pyc(code, mtime=0, source_size=0): + "Produce the data for a timestamp-based pyc." + data = bytearray(MAGIC_NUMBER) + data.extend(_w_long(0)) + data.extend(_w_long(mtime)) + data.extend(_w_long(source_size)) + data.extend(marshal.dumps(code)) + return data + + +def _code_to_hash_pyc(code, source_hash, checked=True): + "Produce the data for a hash-based pyc." + data = bytearray(MAGIC_NUMBER) + flags = 0b1 | checked << 1 + data.extend(_w_long(flags)) + assert len(source_hash) == 8 + data.extend(source_hash) + data.extend(marshal.dumps(code)) + return data + + +def decode_source(source_bytes): + """Decode bytes representing source code and return the string. + + Universal newline support is used in the decoding. + """ + import tokenize # To avoid bootstrap issues. + source_bytes_readline = _io.BytesIO(source_bytes).readline + encoding = tokenize.detect_encoding(source_bytes_readline) + newline_decoder = _io.IncrementalNewlineDecoder(None, True) + return newline_decoder.decode(source_bytes.decode(encoding[0])) + + +# Module specifications ####################################################### + +_POPULATE = object() + + +def spec_from_file_location(name, location=None, *, loader=None, + submodule_search_locations=_POPULATE): + """Return a module spec based on a file location. + + To indicate that the module is a package, set + submodule_search_locations to a list of directory paths. An + empty list is sufficient, though its not otherwise useful to the + import system. + + The loader must take a spec as its only __init__() arg. + + """ + if location is None: + # The caller may simply want a partially populated location- + # oriented spec. So we set the location to a bogus value and + # fill in as much as we can. + location = '' + if hasattr(loader, 'get_filename'): + # ExecutionLoader + try: + location = loader.get_filename(name) + except ImportError: + pass + else: + location = _os.fspath(location) + + # If the location is on the filesystem, but doesn't actually exist, + # we could return None here, indicating that the location is not + # valid. However, we don't have a good way of testing since an + # indirect location (e.g. a zip file or URL) will look like a + # non-existent file relative to the filesystem. + + spec = _bootstrap.ModuleSpec(name, loader, origin=location) + spec._set_fileattr = True + + # Pick a loader if one wasn't provided. + if loader is None: + for loader_class, suffixes in _get_supported_file_loaders(): + if location.endswith(tuple(suffixes)): + loader = loader_class(name, location) + spec.loader = loader + break + else: + return None + + # Set submodule_search_paths appropriately. + if submodule_search_locations is _POPULATE: + # Check the loader. + if hasattr(loader, 'is_package'): + try: + is_package = loader.is_package(name) + except ImportError: + pass + else: + if is_package: + spec.submodule_search_locations = [] + else: + spec.submodule_search_locations = submodule_search_locations + if spec.submodule_search_locations == []: + if location: + dirname = _path_split(location)[0] + spec.submodule_search_locations.append(dirname) + + return spec + + +# Loaders ##################################################################### + +class WindowsRegistryFinder: + + """Meta path finder for modules declared in the Windows registry.""" + + REGISTRY_KEY = ( + 'Software\\Python\\PythonCore\\{sys_version}' + '\\Modules\\{fullname}') + REGISTRY_KEY_DEBUG = ( + 'Software\\Python\\PythonCore\\{sys_version}' + '\\Modules\\{fullname}\\Debug') + DEBUG_BUILD = False # Changed in _setup() + + @classmethod + def _open_registry(cls, key): + try: + return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key) + except OSError: + return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key) + + @classmethod + def _search_registry(cls, fullname): + if cls.DEBUG_BUILD: + registry_key = cls.REGISTRY_KEY_DEBUG + else: + registry_key = cls.REGISTRY_KEY + key = registry_key.format(fullname=fullname, + sys_version='%d.%d' % sys.version_info[:2]) + try: + with cls._open_registry(key) as hkey: + filepath = _winreg.QueryValue(hkey, '') + except OSError: + return None + return filepath + + @classmethod + def find_spec(cls, fullname, path=None, target=None): + filepath = cls._search_registry(fullname) + if filepath is None: + return None + try: + _path_stat(filepath) + except OSError: + return None + for loader, suffixes in _get_supported_file_loaders(): + if filepath.endswith(tuple(suffixes)): + spec = _bootstrap.spec_from_loader(fullname, + loader(fullname, filepath), + origin=filepath) + return spec + + @classmethod + def find_module(cls, fullname, path=None): + """Find module named in the registry. + + This method is deprecated. Use exec_module() instead. + + """ + spec = cls.find_spec(fullname, path) + if spec is not None: + return spec.loader + else: + return None + + +class _LoaderBasics: + + """Base class of common code needed by both SourceLoader and + SourcelessFileLoader.""" + + def is_package(self, fullname): + """Concrete implementation of InspectLoader.is_package by checking if + the path returned by get_filename has a filename of '__init__.py'.""" + filename = _path_split(self.get_filename(fullname))[1] + filename_base = filename.rsplit('.', 1)[0] + tail_name = fullname.rpartition('.')[2] + return filename_base == '__init__' and tail_name != '__init__' + + def create_module(self, spec): + """Use default semantics for module creation.""" + + def exec_module(self, module): + """Execute the module.""" + code = self.get_code(module.__name__) + if code is None: + raise ImportError('cannot load module {!r} when get_code() ' + 'returns None'.format(module.__name__)) + _bootstrap._call_with_frames_removed(exec, code, module.__dict__) + + def load_module(self, fullname): + """This module is deprecated.""" + return _bootstrap._load_module_shim(self, fullname) + + +class SourceLoader(_LoaderBasics): + + def path_mtime(self, path): + """Optional method that returns the modification time (an int) for the + specified path, where path is a str. + + Raises OSError when the path cannot be handled. + """ + raise OSError + + def path_stats(self, path): + """Optional method returning a metadata dict for the specified path + to by the path (str). + Possible keys: + - 'mtime' (mandatory) is the numeric timestamp of last source + code modification; + - 'size' (optional) is the size in bytes of the source code. + + Implementing this method allows the loader to read bytecode files. + Raises OSError when the path cannot be handled. + """ + return {'mtime': self.path_mtime(path)} + + def _cache_bytecode(self, source_path, cache_path, data): + """Optional method which writes data (bytes) to a file path (a str). + + Implementing this method allows for the writing of bytecode files. + + The source path is needed in order to correctly transfer permissions + """ + # For backwards compatibility, we delegate to set_data() + return self.set_data(cache_path, data) + + def set_data(self, path, data): + """Optional method which writes data (bytes) to a file path (a str). + + Implementing this method allows for the writing of bytecode files. + """ + + + def get_source(self, fullname): + """Concrete implementation of InspectLoader.get_source.""" + path = self.get_filename(fullname) + try: + source_bytes = self.get_data(path) + except OSError as exc: + raise ImportError('source not available through get_data()', + name=fullname) from exc + return decode_source(source_bytes) + + def source_to_code(self, data, path, *, _optimize=-1): + """Return the code object compiled from source. + + The 'data' argument can be any object type that compile() supports. + """ + return _bootstrap._call_with_frames_removed(compile, data, path, 'exec', + dont_inherit=True, optimize=_optimize) + + def get_code(self, fullname): + """Concrete implementation of InspectLoader.get_code. + + Reading of bytecode requires path_stats to be implemented. To write + bytecode, set_data must also be implemented. + + """ + source_path = self.get_filename(fullname) + source_mtime = None + source_bytes = None + source_hash = None + hash_based = False + check_source = True + try: + bytecode_path = cache_from_source(source_path) + except NotImplementedError: + bytecode_path = None + else: + try: + st = self.path_stats(source_path) + except OSError: + pass + else: + source_mtime = int(st['mtime']) + try: + data = self.get_data(bytecode_path) + except OSError: + pass + else: + exc_details = { + 'name': fullname, + 'path': bytecode_path, + } + try: + flags = _classify_pyc(data, fullname, exc_details) + bytes_data = memoryview(data)[16:] + hash_based = flags & 0b1 != 0 + if hash_based: + check_source = flags & 0b10 != 0 + if (_imp.check_hash_based_pycs != 'never' and + (check_source or + _imp.check_hash_based_pycs == 'always')): + source_bytes = self.get_data(source_path) + source_hash = _imp.source_hash( + _RAW_MAGIC_NUMBER, + source_bytes, + ) + _validate_hash_pyc(data, source_hash, fullname, + exc_details) + else: + _validate_timestamp_pyc( + data, + source_mtime, + st['size'], + fullname, + exc_details, + ) + except (ImportError, EOFError): + pass + else: + _bootstrap._verbose_message('{} matches {}', bytecode_path, + source_path) + return _compile_bytecode(bytes_data, name=fullname, + bytecode_path=bytecode_path, + source_path=source_path) + if source_bytes is None: + source_bytes = self.get_data(source_path) + code_object = self.source_to_code(source_bytes, source_path) + _bootstrap._verbose_message('code object from {}', source_path) + if (not sys.dont_write_bytecode and bytecode_path is not None and + source_mtime is not None): + if hash_based: + if source_hash is None: + source_hash = _imp.source_hash(source_bytes) + data = _code_to_hash_pyc(code_object, source_hash, check_source) + else: + data = _code_to_timestamp_pyc(code_object, source_mtime, + len(source_bytes)) + try: + self._cache_bytecode(source_path, bytecode_path, data) + _bootstrap._verbose_message('wrote {!r}', bytecode_path) + except NotImplementedError: + pass + return code_object + + +class FileLoader: + + """Base file loader class which implements the loader protocol methods that + require file system usage.""" + + def __init__(self, fullname, path): + """Cache the module name and the path to the file found by the + finder.""" + self.name = fullname + self.path = path + + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.__dict__ == other.__dict__) + + def __hash__(self): + return hash(self.name) ^ hash(self.path) + + @_check_name + def load_module(self, fullname): + """Load a module from a file. + + This method is deprecated. Use exec_module() instead. + + """ + # The only reason for this method is for the name check. + # Issue #14857: Avoid the zero-argument form of super so the implementation + # of that form can be updated without breaking the frozen module + return super(FileLoader, self).load_module(fullname) + + @_check_name + def get_filename(self, fullname): + """Return the path to the source file as found by the finder.""" + return self.path + + def get_data(self, path): + """Return the data from path as raw bytes.""" + with _io.FileIO(path, 'r') as file: + return file.read() + + # ResourceReader ABC API. + + @_check_name + def get_resource_reader(self, module): + if self.is_package(module): + return self + return None + + def open_resource(self, resource): + path = _path_join(_path_split(self.path)[0], resource) + return _io.FileIO(path, 'r') + + def resource_path(self, resource): + if not self.is_resource(resource): + raise FileNotFoundError + path = _path_join(_path_split(self.path)[0], resource) + return path + + def is_resource(self, name): + if path_sep in name: + return False + path = _path_join(_path_split(self.path)[0], name) + return _path_isfile(path) + + def contents(self): + return iter(_os.listdir(_path_split(self.path)[0])) + + +class SourceFileLoader(FileLoader, SourceLoader): + + """Concrete implementation of SourceLoader using the file system.""" + + def path_stats(self, path): + """Return the metadata for the path.""" + st = _path_stat(path) + return {'mtime': st.st_mtime, 'size': st.st_size} + + def _cache_bytecode(self, source_path, bytecode_path, data): + # Adapt between the two APIs + mode = _calc_mode(source_path) + return self.set_data(bytecode_path, data, _mode=mode) + + def set_data(self, path, data, *, _mode=0o666): + """Write bytes data to a file.""" + parent, filename = _path_split(path) + path_parts = [] + # Figure out what directories are missing. + while parent and not _path_isdir(parent): + parent, part = _path_split(parent) + path_parts.append(part) + # Create needed directories. + for part in reversed(path_parts): + parent = _path_join(parent, part) + try: + _os.mkdir(parent) + except FileExistsError: + # Probably another Python process already created the dir. + continue + except OSError as exc: + # Could be a permission error, read-only filesystem: just forget + # about writing the data. + _bootstrap._verbose_message('could not create {!r}: {!r}', + parent, exc) + return + try: + _write_atomic(path, data, _mode) + _bootstrap._verbose_message('created {!r}', path) + except OSError as exc: + # Same as above: just don't write the bytecode. + _bootstrap._verbose_message('could not create {!r}: {!r}', path, + exc) + + +class SourcelessFileLoader(FileLoader, _LoaderBasics): + + """Loader which handles sourceless file imports.""" + + def get_code(self, fullname): + path = self.get_filename(fullname) + data = self.get_data(path) + # Call _classify_pyc to do basic validation of the pyc but ignore the + # result. There's no source to check against. + exc_details = { + 'name': fullname, + 'path': path, + } + _classify_pyc(data, fullname, exc_details) + return _compile_bytecode( + memoryview(data)[16:], + name=fullname, + bytecode_path=path, + ) + + def get_source(self, fullname): + """Return None as there is no source code.""" + return None + + +# Filled in by _setup(). +EXTENSION_SUFFIXES = [] + + +class ExtensionFileLoader(FileLoader, _LoaderBasics): + + """Loader for extension modules. + + The constructor is designed to work with FileFinder. + + """ + + def __init__(self, name, path): + self.name = name + self.path = path + + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.__dict__ == other.__dict__) + + def __hash__(self): + return hash(self.name) ^ hash(self.path) + + def create_module(self, spec): + """Create an unitialized extension module""" + module = _bootstrap._call_with_frames_removed( + _imp.create_dynamic, spec) + _bootstrap._verbose_message('extension module {!r} loaded from {!r}', + spec.name, self.path) + return module + + def exec_module(self, module): + """Initialize an extension module""" + _bootstrap._call_with_frames_removed(_imp.exec_dynamic, module) + _bootstrap._verbose_message('extension module {!r} executed from {!r}', + self.name, self.path) + + def is_package(self, fullname): + """Return True if the extension module is a package.""" + file_name = _path_split(self.path)[1] + return any(file_name == '__init__' + suffix + for suffix in EXTENSION_SUFFIXES) + + def get_code(self, fullname): + """Return None as an extension module cannot create a code object.""" + return None + + def get_source(self, fullname): + """Return None as extension modules have no source code.""" + return None + + @_check_name + def get_filename(self, fullname): + """Return the path to the source file as found by the finder.""" + return self.path + + +class _NamespacePath: + """Represents a namespace package's path. It uses the module name + to find its parent module, and from there it looks up the parent's + __path__. When this changes, the module's own path is recomputed, + using path_finder. For top-level modules, the parent module's path + is sys.path.""" + + def __init__(self, name, path, path_finder): + self._name = name + self._path = path + self._last_parent_path = tuple(self._get_parent_path()) + self._path_finder = path_finder + + def _find_parent_path_names(self): + """Returns a tuple of (parent-module-name, parent-path-attr-name)""" + parent, dot, me = self._name.rpartition('.') + if dot == '': + # This is a top-level module. sys.path contains the parent path. + return 'sys', 'path' + # Not a top-level module. parent-module.__path__ contains the + # parent path. + return parent, '__path__' + + def _get_parent_path(self): + parent_module_name, path_attr_name = self._find_parent_path_names() + return getattr(sys.modules[parent_module_name], path_attr_name) + + def _recalculate(self): + # If the parent's path has changed, recalculate _path + parent_path = tuple(self._get_parent_path()) # Make a copy + if parent_path != self._last_parent_path: + spec = self._path_finder(self._name, parent_path) + # Note that no changes are made if a loader is returned, but we + # do remember the new parent path + if spec is not None and spec.loader is None: + if spec.submodule_search_locations: + self._path = spec.submodule_search_locations + self._last_parent_path = parent_path # Save the copy + return self._path + + def __iter__(self): + return iter(self._recalculate()) + + def __setitem__(self, index, path): + self._path[index] = path + + def __len__(self): + return len(self._recalculate()) + + def __repr__(self): + return '_NamespacePath({!r})'.format(self._path) + + def __contains__(self, item): + return item in self._recalculate() + + def append(self, item): + self._path.append(item) + + +# We use this exclusively in module_from_spec() for backward-compatibility. +class _NamespaceLoader: + def __init__(self, name, path, path_finder): + self._path = _NamespacePath(name, path, path_finder) + + @classmethod + def module_repr(cls, module): + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ + return ''.format(module.__name__) + + def is_package(self, fullname): + return True + + def get_source(self, fullname): + return '' + + def get_code(self, fullname): + return compile('', '', 'exec', dont_inherit=True) + + def create_module(self, spec): + """Use default semantics for module creation.""" + + def exec_module(self, module): + pass + + def load_module(self, fullname): + """Load a namespace module. + + This method is deprecated. Use exec_module() instead. + + """ + # The import system never calls this method. + _bootstrap._verbose_message('namespace module loaded with path {!r}', + self._path) + return _bootstrap._load_module_shim(self, fullname) + + +# Finders ##################################################################### + +class PathFinder: + + """Meta path finder for sys.path and package __path__ attributes.""" + + @classmethod + def invalidate_caches(cls): + """Call the invalidate_caches() method on all path entry finders + stored in sys.path_importer_caches (where implemented).""" + for name, finder in list(sys.path_importer_cache.items()): + if finder is None: + del sys.path_importer_cache[name] + elif hasattr(finder, 'invalidate_caches'): + finder.invalidate_caches() + + @classmethod + def _path_hooks(cls, path): + """Search sys.path_hooks for a finder for 'path'.""" + if sys.path_hooks is not None and not sys.path_hooks: + _warnings.warn('sys.path_hooks is empty', ImportWarning) + for hook in sys.path_hooks: + try: + return hook(path) + except ImportError: + continue + else: + return None + + @classmethod + def _path_importer_cache(cls, path): + """Get the finder for the path entry from sys.path_importer_cache. + + If the path entry is not in the cache, find the appropriate finder + and cache it. If no finder is available, store None. + + """ + if path == '': + try: + path = _os.getcwd() + except FileNotFoundError: + # Don't cache the failure as the cwd can easily change to + # a valid directory later on. + return None + try: + finder = sys.path_importer_cache[path] + except KeyError: + finder = cls._path_hooks(path) + sys.path_importer_cache[path] = finder + return finder + + @classmethod + def _legacy_get_spec(cls, fullname, finder): + # This would be a good place for a DeprecationWarning if + # we ended up going that route. + if hasattr(finder, 'find_loader'): + loader, portions = finder.find_loader(fullname) + else: + loader = finder.find_module(fullname) + portions = [] + if loader is not None: + return _bootstrap.spec_from_loader(fullname, loader) + spec = _bootstrap.ModuleSpec(fullname, None) + spec.submodule_search_locations = portions + return spec + + @classmethod + def _get_spec(cls, fullname, path, target=None): + """Find the loader or namespace_path for this module/package name.""" + # If this ends up being a namespace package, namespace_path is + # the list of paths that will become its __path__ + namespace_path = [] + for entry in path: + if not isinstance(entry, (str, bytes)): + continue + finder = cls._path_importer_cache(entry) + if finder is not None: + if hasattr(finder, 'find_spec'): + spec = finder.find_spec(fullname, target) + else: + spec = cls._legacy_get_spec(fullname, finder) + if spec is None: + continue + if spec.loader is not None: + return spec + portions = spec.submodule_search_locations + if portions is None: + raise ImportError('spec missing loader') + # This is possibly part of a namespace package. + # Remember these path entries (if any) for when we + # create a namespace package, and continue iterating + # on path. + namespace_path.extend(portions) + else: + spec = _bootstrap.ModuleSpec(fullname, None) + spec.submodule_search_locations = namespace_path + return spec + + @classmethod + def find_spec(cls, fullname, path=None, target=None): + """Try to find a spec for 'fullname' on sys.path or 'path'. + + The search is based on sys.path_hooks and sys.path_importer_cache. + """ + if path is None: + path = sys.path + spec = cls._get_spec(fullname, path, target) + if spec is None: + return None + elif spec.loader is None: + namespace_path = spec.submodule_search_locations + if namespace_path: + # We found at least one namespace path. Return a spec which + # can create the namespace package. + spec.origin = None + spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec) + return spec + else: + return None + else: + return spec + + @classmethod + def find_module(cls, fullname, path=None): + """find the module on sys.path or 'path' based on sys.path_hooks and + sys.path_importer_cache. + + This method is deprecated. Use find_spec() instead. + + """ + spec = cls.find_spec(fullname, path) + if spec is None: + return None + return spec.loader + + +class FileFinder: + + """File-based finder. + + Interactions with the file system are cached for performance, being + refreshed when the directory the finder is handling has been modified. + + """ + + def __init__(self, path, *loader_details): + """Initialize with the path to search on and a variable number of + 2-tuples containing the loader and the file suffixes the loader + recognizes.""" + loaders = [] + for loader, suffixes in loader_details: + loaders.extend((suffix, loader) for suffix in suffixes) + self._loaders = loaders + # Base (directory) path + self.path = path or '.' + self._path_mtime = -1 + self._path_cache = set() + self._relaxed_path_cache = set() + + def invalidate_caches(self): + """Invalidate the directory mtime.""" + self._path_mtime = -1 + + find_module = _find_module_shim + + def find_loader(self, fullname): + """Try to find a loader for the specified module, or the namespace + package portions. Returns (loader, list-of-portions). + + This method is deprecated. Use find_spec() instead. + + """ + spec = self.find_spec(fullname) + if spec is None: + return None, [] + return spec.loader, spec.submodule_search_locations or [] + + def _get_spec(self, loader_class, fullname, path, smsl, target): + loader = loader_class(fullname, path) + return spec_from_file_location(fullname, path, loader=loader, + submodule_search_locations=smsl) + + def find_spec(self, fullname, target=None): + """Try to find a spec for the specified module. + + Returns the matching spec, or None if not found. + """ + is_namespace = False + tail_module = fullname.rpartition('.')[2] + try: + mtime = _path_stat(self.path or _os.getcwd()).st_mtime + except OSError: + mtime = -1 + if mtime != self._path_mtime: + self._fill_cache() + self._path_mtime = mtime + # tail_module keeps the original casing, for __file__ and friends + if _relax_case(): + cache = self._relaxed_path_cache + cache_module = tail_module.lower() + else: + cache = self._path_cache + cache_module = tail_module + # Check if the module is the name of a directory (and thus a package). + if cache_module in cache: + base_path = _path_join(self.path, tail_module) + for suffix, loader_class in self._loaders: + init_filename = '__init__' + suffix + full_path = _path_join(base_path, init_filename) + if _path_isfile(full_path): + return self._get_spec(loader_class, fullname, full_path, [base_path], target) + else: + # If a namespace package, return the path if we don't + # find a module in the next section. + is_namespace = _path_isdir(base_path) + # Check for a file w/ a proper suffix exists. + for suffix, loader_class in self._loaders: + full_path = _path_join(self.path, tail_module + suffix) + _bootstrap._verbose_message('trying {}', full_path, verbosity=2) + if cache_module + suffix in cache: + if _path_isfile(full_path): + return self._get_spec(loader_class, fullname, full_path, + None, target) + if is_namespace: + _bootstrap._verbose_message('possible namespace for {}', base_path) + spec = _bootstrap.ModuleSpec(fullname, None) + spec.submodule_search_locations = [base_path] + return spec + return None + + def _fill_cache(self): + """Fill the cache of potential modules and packages for this directory.""" + path = self.path + try: + contents = _os.listdir(path or _os.getcwd()) + except (FileNotFoundError, PermissionError, NotADirectoryError): + # Directory has either been removed, turned into a file, or made + # unreadable. + contents = [] + # We store two cached versions, to handle runtime changes of the + # PYTHONCASEOK environment variable. + if not sys.platform.startswith('win'): + self._path_cache = set(contents) + else: + # Windows users can import modules with case-insensitive file + # suffixes (for legacy reasons). Make the suffix lowercase here + # so it's done once instead of for every import. This is safe as + # the specified suffixes to check against are always specified in a + # case-sensitive manner. + lower_suffix_contents = set() + for item in contents: + name, dot, suffix = item.partition('.') + if dot: + new_name = '{}.{}'.format(name, suffix.lower()) + else: + new_name = name + lower_suffix_contents.add(new_name) + self._path_cache = lower_suffix_contents + if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): + self._relaxed_path_cache = {fn.lower() for fn in contents} + + @classmethod + def path_hook(cls, *loader_details): + """A class method which returns a closure to use on sys.path_hook + which will return an instance using the specified loaders and the path + called on the closure. + + If the path called on the closure is not a directory, ImportError is + raised. + + """ + def path_hook_for_FileFinder(path): + """Path hook for importlib.machinery.FileFinder.""" + if not _path_isdir(path): + raise ImportError('only directories are supported', path=path) + return cls(path, *loader_details) + + return path_hook_for_FileFinder + + def __repr__(self): + return 'FileFinder({!r})'.format(self.path) + + +# Import setup ############################################################### + +def _fix_up_module(ns, name, pathname, cpathname=None): + # This function is used by PyImport_ExecCodeModuleObject(). + loader = ns.get('__loader__') + spec = ns.get('__spec__') + if not loader: + if spec: + loader = spec.loader + elif pathname == cpathname: + loader = SourcelessFileLoader(name, pathname) + else: + loader = SourceFileLoader(name, pathname) + if not spec: + spec = spec_from_file_location(name, pathname, loader=loader) + try: + ns['__spec__'] = spec + ns['__loader__'] = loader + ns['__file__'] = pathname + ns['__cached__'] = cpathname + except Exception: + # Not important enough to report. + pass + + +def _get_supported_file_loaders(): + """Returns a list of file-based module loaders. + + Each item is a tuple (loader, suffixes). + """ + extensions = ExtensionFileLoader, _imp.extension_suffixes() + source = SourceFileLoader, SOURCE_SUFFIXES + bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES + return [extensions, source, bytecode] + + +def _setup(_bootstrap_module): + """Setup the path-based importers for importlib by importing needed + built-in modules and injecting them into the global namespace. + + Other components are extracted from the core bootstrap module. + + """ + global sys, _imp, _bootstrap + _bootstrap = _bootstrap_module + sys = _bootstrap.sys + _imp = _bootstrap._imp + + # Directly load built-in modules needed during bootstrap. + self_module = sys.modules[__name__] + for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'): + if builtin_name not in sys.modules: + builtin_module = _bootstrap._builtin_from_name(builtin_name) + else: + builtin_module = sys.modules[builtin_name] + setattr(self_module, builtin_name, builtin_module) + + # Directly load the os module (needed during bootstrap). + os_details = ('posix', ['/']), ('nt', ['\\', '/']) + for builtin_os, path_separators in os_details: + # Assumption made in _path_join() + assert all(len(sep) == 1 for sep in path_separators) + path_sep = path_separators[0] + if builtin_os in sys.modules: + os_module = sys.modules[builtin_os] + break + else: + try: + os_module = _bootstrap._builtin_from_name(builtin_os) + break + except ImportError: + continue + else: + raise ImportError('importlib requires posix or nt') + setattr(self_module, '_os', os_module) + setattr(self_module, 'path_sep', path_sep) + setattr(self_module, 'path_separators', ''.join(path_separators)) + + # Directly load the _thread module (needed during bootstrap). + thread_module = _bootstrap._builtin_from_name('_thread') + setattr(self_module, '_thread', thread_module) + + # Directly load the _weakref module (needed during bootstrap). + weakref_module = _bootstrap._builtin_from_name('_weakref') + setattr(self_module, '_weakref', weakref_module) + + # Directly load the winreg module (needed during bootstrap). + if builtin_os == 'nt': + winreg_module = _bootstrap._builtin_from_name('winreg') + setattr(self_module, '_winreg', winreg_module) + + # Constants + setattr(self_module, '_relax_case', _make_relax_case()) + EXTENSION_SUFFIXES.extend(_imp.extension_suffixes()) + if builtin_os == 'nt': + SOURCE_SUFFIXES.append('.pyw') + if '_d.pyd' in EXTENSION_SUFFIXES: + WindowsRegistryFinder.DEBUG_BUILD = True + + +def _install(_bootstrap_module): + """Install the path-based import components.""" + _setup(_bootstrap_module) + supported_loaders = _get_supported_file_loaders() + sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) + sys.meta_path.append(PathFinder) diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py new file mode 100644 index 0000000..dbdd5bf --- /dev/null +++ b/Lib/importlib/abc.py @@ -0,0 +1,388 @@ +"""Abstract base classes related to import.""" +from . import _bootstrap +from . import _bootstrap_external +from . import machinery +try: + import _frozen_importlib +except ImportError as exc: + if exc.name != '_frozen_importlib': + raise + _frozen_importlib = None +try: + import _frozen_importlib_external +except ImportError as exc: + _frozen_importlib_external = _bootstrap_external +import abc +import warnings + + +def _register(abstract_cls, *classes): + for cls in classes: + abstract_cls.register(cls) + if _frozen_importlib is not None: + try: + frozen_cls = getattr(_frozen_importlib, cls.__name__) + except AttributeError: + frozen_cls = getattr(_frozen_importlib_external, cls.__name__) + abstract_cls.register(frozen_cls) + + +class Finder(metaclass=abc.ABCMeta): + + """Legacy abstract base class for import finders. + + It may be subclassed for compatibility with legacy third party + reimplementations of the import system. Otherwise, finder + implementations should derive from the more specific MetaPathFinder + or PathEntryFinder ABCs. + + Deprecated since Python 3.3 + """ + + @abc.abstractmethod + def find_module(self, fullname, path=None): + """An abstract method that should find a module. + The fullname is a str and the optional path is a str or None. + Returns a Loader object or None. + """ + + +class MetaPathFinder(Finder): + + """Abstract base class for import finders on sys.meta_path.""" + + # We don't define find_spec() here since that would break + # hasattr checks we do to support backward compatibility. + + def find_module(self, fullname, path): + """Return a loader for the module. + + If no module is found, return None. The fullname is a str and + the path is a list of strings or None. + + This method is deprecated since Python 3.4 in favor of + finder.find_spec(). If find_spec() exists then backwards-compatible + functionality is provided for this method. + + """ + warnings.warn("MetaPathFinder.find_module() is deprecated since Python " + "3.4 in favor of MetaPathFinder.find_spec()" + "(available since 3.4)", + DeprecationWarning, + stacklevel=2) + if not hasattr(self, 'find_spec'): + return None + found = self.find_spec(fullname, path) + return found.loader if found is not None else None + + def invalidate_caches(self): + """An optional method for clearing the finder's cache, if any. + This method is used by importlib.invalidate_caches(). + """ + +_register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter, + machinery.PathFinder, machinery.WindowsRegistryFinder) + + +class PathEntryFinder(Finder): + + """Abstract base class for path entry finders used by PathFinder.""" + + # We don't define find_spec() here since that would break + # hasattr checks we do to support backward compatibility. + + def find_loader(self, fullname): + """Return (loader, namespace portion) for the path entry. + + The fullname is a str. The namespace portion is a sequence of + path entries contributing to part of a namespace package. The + sequence may be empty. If loader is not None, the portion will + be ignored. + + The portion will be discarded if another path entry finder + locates the module as a normal module or package. + + This method is deprecated since Python 3.4 in favor of + finder.find_spec(). If find_spec() is provided than backwards-compatible + functionality is provided. + """ + warnings.warn("PathEntryFinder.find_loader() is deprecated since Python " + "3.4 in favor of PathEntryFinder.find_spec() " + "(available since 3.4)", + DeprecationWarning, + stacklevel=2) + if not hasattr(self, 'find_spec'): + return None, [] + found = self.find_spec(fullname) + if found is not None: + if not found.submodule_search_locations: + portions = [] + else: + portions = found.submodule_search_locations + return found.loader, portions + else: + return None, [] + + find_module = _bootstrap_external._find_module_shim + + def invalidate_caches(self): + """An optional method for clearing the finder's cache, if any. + This method is used by PathFinder.invalidate_caches(). + """ + +_register(PathEntryFinder, machinery.FileFinder) + + +class Loader(metaclass=abc.ABCMeta): + + """Abstract base class for import loaders.""" + + def create_module(self, spec): + """Return a module to initialize and into which to load. + + This method should raise ImportError if anything prevents it + from creating a new module. It may return None to indicate + that the spec should create the new module. + """ + # By default, defer to default semantics for the new module. + return None + + # We don't define exec_module() here since that would break + # hasattr checks we do to support backward compatibility. + + def load_module(self, fullname): + """Return the loaded module. + + The module must be added to sys.modules and have import-related + attributes set properly. The fullname is a str. + + ImportError is raised on failure. + + This method is deprecated in favor of loader.exec_module(). If + exec_module() exists then it is used to provide a backwards-compatible + functionality for this method. + + """ + if not hasattr(self, 'exec_module'): + raise ImportError + return _bootstrap._load_module_shim(self, fullname) + + def module_repr(self, module): + """Return a module's repr. + + Used by the module type when the method does not raise + NotImplementedError. + + This method is deprecated. + + """ + # The exception will cause ModuleType.__repr__ to ignore this method. + raise NotImplementedError + + +class ResourceLoader(Loader): + + """Abstract base class for loaders which can return data from their + back-end storage. + + This ABC represents one of the optional protocols specified by PEP 302. + + """ + + @abc.abstractmethod + def get_data(self, path): + """Abstract method which when implemented should return the bytes for + the specified path. The path must be a str.""" + raise OSError + + +class InspectLoader(Loader): + + """Abstract base class for loaders which support inspection about the + modules they can load. + + This ABC represents one of the optional protocols specified by PEP 302. + + """ + + def is_package(self, fullname): + """Optional method which when implemented should return whether the + module is a package. The fullname is a str. Returns a bool. + + Raises ImportError if the module cannot be found. + """ + raise ImportError + + def get_code(self, fullname): + """Method which returns the code object for the module. + + The fullname is a str. Returns a types.CodeType if possible, else + returns None if a code object does not make sense + (e.g. built-in module). Raises ImportError if the module cannot be + found. + """ + source = self.get_source(fullname) + if source is None: + return None + return self.source_to_code(source) + + @abc.abstractmethod + def get_source(self, fullname): + """Abstract method which should return the source code for the + module. The fullname is a str. Returns a str. + + Raises ImportError if the module cannot be found. + """ + raise ImportError + + @staticmethod + def source_to_code(data, path=''): + """Compile 'data' into a code object. + + The 'data' argument can be anything that compile() can handle. The'path' + argument should be where the data was retrieved (when applicable).""" + return compile(data, path, 'exec', dont_inherit=True) + + exec_module = _bootstrap_external._LoaderBasics.exec_module + load_module = _bootstrap_external._LoaderBasics.load_module + +_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter) + + +class ExecutionLoader(InspectLoader): + + """Abstract base class for loaders that wish to support the execution of + modules as scripts. + + This ABC represents one of the optional protocols specified in PEP 302. + + """ + + @abc.abstractmethod + def get_filename(self, fullname): + """Abstract method which should return the value that __file__ is to be + set to. + + Raises ImportError if the module cannot be found. + """ + raise ImportError + + def get_code(self, fullname): + """Method to return the code object for fullname. + + Should return None if not applicable (e.g. built-in module). + Raise ImportError if the module cannot be found. + """ + source = self.get_source(fullname) + if source is None: + return None + try: + path = self.get_filename(fullname) + except ImportError: + return self.source_to_code(source) + else: + return self.source_to_code(source, path) + +_register(ExecutionLoader, machinery.ExtensionFileLoader) + + +class FileLoader(_bootstrap_external.FileLoader, ResourceLoader, ExecutionLoader): + + """Abstract base class partially implementing the ResourceLoader and + ExecutionLoader ABCs.""" + +_register(FileLoader, machinery.SourceFileLoader, + machinery.SourcelessFileLoader) + + +class SourceLoader(_bootstrap_external.SourceLoader, ResourceLoader, ExecutionLoader): + + """Abstract base class for loading source code (and optionally any + corresponding bytecode). + + To support loading from source code, the abstractmethods inherited from + ResourceLoader and ExecutionLoader need to be implemented. To also support + loading from bytecode, the optional methods specified directly by this ABC + is required. + + Inherited abstractmethods not implemented in this ABC: + + * ResourceLoader.get_data + * ExecutionLoader.get_filename + + """ + + def path_mtime(self, path): + """Return the (int) modification time for the path (str).""" + if self.path_stats.__func__ is SourceLoader.path_stats: + raise OSError + return int(self.path_stats(path)['mtime']) + + def path_stats(self, path): + """Return a metadata dict for the source pointed to by the path (str). + Possible keys: + - 'mtime' (mandatory) is the numeric timestamp of last source + code modification; + - 'size' (optional) is the size in bytes of the source code. + """ + if self.path_mtime.__func__ is SourceLoader.path_mtime: + raise OSError + return {'mtime': self.path_mtime(path)} + + def set_data(self, path, data): + """Write the bytes to the path (if possible). + + Accepts a str path and data as bytes. + + Any needed intermediary directories are to be created. If for some + reason the file cannot be written because of permissions, fail + silently. + """ + +_register(SourceLoader, machinery.SourceFileLoader) + + +class ResourceReader(metaclass=abc.ABCMeta): + + """Abstract base class to provide resource-reading support. + + Loaders that support resource reading are expected to implement + the ``get_resource_reader(fullname)`` method and have it either return None + or an object compatible with this ABC. + """ + + @abc.abstractmethod + def open_resource(self, resource): + """Return an opened, file-like object for binary reading. + + The 'resource' argument is expected to represent only a file name + and thus not contain any subdirectory components. + + If the resource cannot be found, FileNotFoundError is raised. + """ + raise FileNotFoundError + + @abc.abstractmethod + def resource_path(self, resource): + """Return the file system path to the specified resource. + + The 'resource' argument is expected to represent only a file name + and thus not contain any subdirectory components. + + If the resource does not exist on the file system, raise + FileNotFoundError. + """ + raise FileNotFoundError + + @abc.abstractmethod + def is_resource(self, name): + """Return True if the named 'name' is consider a resource.""" + raise FileNotFoundError + + @abc.abstractmethod + def contents(self): + """Return an iterable of strings over the contents of the package.""" + return [] + + +_register(ResourceReader, machinery.SourceFileLoader) diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py new file mode 100644 index 0000000..1b2b5c9 --- /dev/null +++ b/Lib/importlib/machinery.py @@ -0,0 +1,21 @@ +"""The machinery of importlib: finders, loaders, hooks, etc.""" + +import _imp + +from ._bootstrap import ModuleSpec +from ._bootstrap import BuiltinImporter +from ._bootstrap import FrozenImporter +from ._bootstrap_external import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES, + OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, + EXTENSION_SUFFIXES) +from ._bootstrap_external import WindowsRegistryFinder +from ._bootstrap_external import PathFinder +from ._bootstrap_external import FileFinder +from ._bootstrap_external import SourceFileLoader +from ._bootstrap_external import SourcelessFileLoader +from ._bootstrap_external import ExtensionFileLoader + + +def all_suffixes(): + """Returns a list of all recognized module suffixes for this process""" + return SOURCE_SUFFIXES + BYTECODE_SUFFIXES + EXTENSION_SUFFIXES diff --git a/Lib/importlib/resources.py b/Lib/importlib/resources.py new file mode 100644 index 0000000..cbefdd5 --- /dev/null +++ b/Lib/importlib/resources.py @@ -0,0 +1,343 @@ +import os +import tempfile + +from . import abc as resources_abc +from contextlib import contextmanager, suppress +from importlib import import_module +from importlib.abc import ResourceLoader +from io import BytesIO, TextIOWrapper +from pathlib import Path +from types import ModuleType +from typing import Iterable, Iterator, Optional, Set, Union # noqa: F401 +from typing import cast +from typing.io import BinaryIO, TextIO +from zipimport import ZipImportError + + +__all__ = [ + 'Package', + 'Resource', + 'contents', + 'is_resource', + 'open_binary', + 'open_text', + 'path', + 'read_binary', + 'read_text', + ] + + +Package = Union[str, ModuleType] +Resource = Union[str, os.PathLike] + + +def _get_package(package) -> ModuleType: + """Take a package name or module object and return the module. + + If a name, the module is imported. If the passed or imported module + object is not a package, raise an exception. + """ + if hasattr(package, '__spec__'): + if package.__spec__.submodule_search_locations is None: + raise TypeError('{!r} is not a package'.format( + package.__spec__.name)) + else: + return package + else: + module = import_module(package) + if module.__spec__.submodule_search_locations is None: + raise TypeError('{!r} is not a package'.format(package)) + else: + return module + + +def _normalize_path(path) -> str: + """Normalize a path by ensuring it is a string. + + If the resulting string contains path separators, an exception is raised. + """ + parent, file_name = os.path.split(path) + if parent: + raise ValueError('{!r} must be only a file name'.format(path)) + else: + return file_name + + +def _get_resource_reader( + package: ModuleType) -> Optional[resources_abc.ResourceReader]: + # Return the package's loader if it's a ResourceReader. We can't use + # a issubclass() check here because apparently abc.'s __subclasscheck__() + # hook wants to create a weak reference to the object, but + # zipimport.zipimporter does not support weak references, resulting in a + # TypeError. That seems terrible. + spec = package.__spec__ + if hasattr(spec.loader, 'get_resource_reader'): + return cast(resources_abc.ResourceReader, + spec.loader.get_resource_reader(spec.name)) + return None + + +def _check_location(package): + if package.__spec__.origin is None or not package.__spec__.has_location: + raise FileNotFoundError(f'Package has no location {package!r}') + + +def open_binary(package: Package, resource: Resource) -> BinaryIO: + """Return a file-like object opened for binary reading of the resource.""" + resource = _normalize_path(resource) + package = _get_package(package) + reader = _get_resource_reader(package) + if reader is not None: + return reader.open_resource(resource) + _check_location(package) + absolute_package_path = os.path.abspath(package.__spec__.origin) + package_path = os.path.dirname(absolute_package_path) + full_path = os.path.join(package_path, resource) + try: + return open(full_path, mode='rb') + except OSError: + # Just assume the loader is a resource loader; all the relevant + # importlib.machinery loaders are and an AttributeError for + # get_data() will make it clear what is needed from the loader. + loader = cast(ResourceLoader, package.__spec__.loader) + data = None + if hasattr(package.__spec__.loader, 'get_data'): + with suppress(OSError): + data = loader.get_data(full_path) + if data is None: + package_name = package.__spec__.name + message = '{!r} resource not found in {!r}'.format( + resource, package_name) + raise FileNotFoundError(message) + else: + return BytesIO(data) + + +def open_text(package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict') -> TextIO: + """Return a file-like object opened for text reading of the resource.""" + resource = _normalize_path(resource) + package = _get_package(package) + reader = _get_resource_reader(package) + if reader is not None: + return TextIOWrapper(reader.open_resource(resource), encoding, errors) + _check_location(package) + absolute_package_path = os.path.abspath(package.__spec__.origin) + package_path = os.path.dirname(absolute_package_path) + full_path = os.path.join(package_path, resource) + try: + return open(full_path, mode='r', encoding=encoding, errors=errors) + except OSError: + # Just assume the loader is a resource loader; all the relevant + # importlib.machinery loaders are and an AttributeError for + # get_data() will make it clear what is needed from the loader. + loader = cast(ResourceLoader, package.__spec__.loader) + data = None + if hasattr(package.__spec__.loader, 'get_data'): + with suppress(OSError): + data = loader.get_data(full_path) + if data is None: + package_name = package.__spec__.name + message = '{!r} resource not found in {!r}'.format( + resource, package_name) + raise FileNotFoundError(message) + else: + return TextIOWrapper(BytesIO(data), encoding, errors) + + +def read_binary(package: Package, resource: Resource) -> bytes: + """Return the binary contents of the resource.""" + resource = _normalize_path(resource) + package = _get_package(package) + with open_binary(package, resource) as fp: + return fp.read() + + +def read_text(package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict') -> str: + """Return the decoded string of the resource. + + The decoding-related arguments have the same semantics as those of + bytes.decode(). + """ + resource = _normalize_path(resource) + package = _get_package(package) + with open_text(package, resource, encoding, errors) as fp: + return fp.read() + + +@contextmanager +def path(package: Package, resource: Resource) -> Iterator[Path]: + """A context manager providing a file path object to the resource. + + If the resource does not already exist on its own on the file system, + a temporary file will be created. If the file was created, the file + will be deleted upon exiting the context manager (no exception is + raised if the file was deleted prior to the context manager + exiting). + """ + resource = _normalize_path(resource) + package = _get_package(package) + reader = _get_resource_reader(package) + if reader is not None: + try: + yield Path(reader.resource_path(resource)) + return + except FileNotFoundError: + pass + else: + _check_location(package) + # Fall-through for both the lack of resource_path() *and* if + # resource_path() raises FileNotFoundError. + package_directory = Path(package.__spec__.origin).parent + file_path = package_directory / resource + if file_path.exists(): + yield file_path + else: + with open_binary(package, resource) as fp: + data = fp.read() + # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try' + # blocks due to the need to close the temporary file to work on + # Windows properly. + fd, raw_path = tempfile.mkstemp() + try: + os.write(fd, data) + os.close(fd) + yield Path(raw_path) + finally: + try: + os.remove(raw_path) + except FileNotFoundError: + pass + + +def is_resource(package: Package, name: str) -> bool: + """True if 'name' is a resource inside 'package'. + + Directories are *not* resources. + """ + package = _get_package(package) + _normalize_path(name) + reader = _get_resource_reader(package) + if reader is not None: + return reader.is_resource(name) + try: + package_contents = set(contents(package)) + except (NotADirectoryError, FileNotFoundError): + return False + if name not in package_contents: + return False + # Just because the given file_name lives as an entry in the package's + # contents doesn't necessarily mean it's a resource. Directories are not + # resources, so let's try to find out if it's a directory or not. + path = Path(package.__spec__.origin).parent / name + return path.is_file() + + +def contents(package: Package) -> Iterable[str]: + """Return an iterable of entries in 'package'. + + Note that not all entries are resources. Specifically, directories are + not considered resources. Use `is_resource()` on each entry returned here + to check if it is a resource or not. + """ + package = _get_package(package) + reader = _get_resource_reader(package) + if reader is not None: + return reader.contents() + # Is the package a namespace package? By definition, namespace packages + # cannot have resources. We could use _check_location() and catch the + # exception, but that's extra work, so just inline the check. + elif package.__spec__.origin is None or not package.__spec__.has_location: + return () + else: + package_directory = Path(package.__spec__.origin).parent + return os.listdir(package_directory) + + +# Private implementation of ResourceReader and get_resource_reader() called +# from zipimport.c. Don't use these directly! We're implementing these in +# Python because 1) it's easier, 2) zipimport may get rewritten in Python +# itself at some point, so doing this all in C would difficult and a waste of +# effort. + +class _ZipImportResourceReader(resources_abc.ResourceReader): + """Private class used to support ZipImport.get_resource_reader(). + + This class is allowed to reference all the innards and private parts of + the zipimporter. + """ + + def __init__(self, zipimporter, fullname): + self.zipimporter = zipimporter + self.fullname = fullname + + def open_resource(self, resource): + fullname_as_path = self.fullname.replace('.', '/') + path = f'{fullname_as_path}/{resource}' + try: + return BytesIO(self.zipimporter.get_data(path)) + except OSError: + raise FileNotFoundError(path) + + def resource_path(self, resource): + # All resources are in the zip file, so there is no path to the file. + # Raising FileNotFoundError tells the higher level API to extract the + # binary data and create a temporary file. + raise FileNotFoundError + + def is_resource(self, name): + # Maybe we could do better, but if we can get the data, it's a + # resource. Otherwise it isn't. + fullname_as_path = self.fullname.replace('.', '/') + path = f'{fullname_as_path}/{name}' + try: + self.zipimporter.get_data(path) + except OSError: + return False + return True + + def contents(self): + # This is a bit convoluted, because fullname will be a module path, + # but _files is a list of file names relative to the top of the + # archive's namespace. We want to compare file paths to find all the + # names of things inside the module represented by fullname. So we + # turn the module path of fullname into a file path relative to the + # top of the archive, and then we iterate through _files looking for + # names inside that "directory". + fullname_path = Path(self.zipimporter.get_filename(self.fullname)) + relative_path = fullname_path.relative_to(self.zipimporter.archive) + # Don't forget that fullname names a package, so its path will include + # __init__.py, which we want to ignore. + assert relative_path.name == '__init__.py' + package_path = relative_path.parent + subdirs_seen = set() + for filename in self.zipimporter._files: + try: + relative = Path(filename).relative_to(package_path) + except ValueError: + continue + # If the path of the file (which is relative to the top of the zip + # namespace), relative to the package given when the resource + # reader was created, has a parent, then it's a name in a + # subdirectory and thus we skip it. + parent_name = relative.parent.name + if len(parent_name) == 0: + yield relative.name + elif parent_name not in subdirs_seen: + subdirs_seen.add(parent_name) + yield parent_name + + +# Called from zipimport.c +def _zipimport_get_resource_reader(zipimporter, fullname): + try: + if not zipimporter.is_package(fullname): + return None + except ZipImportError: + return None + return _ZipImportResourceReader(zipimporter, fullname) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py new file mode 100644 index 0000000..201e0f4 --- /dev/null +++ b/Lib/importlib/util.py @@ -0,0 +1,300 @@ +"""Utility code for constructing importers, etc.""" +from . import abc +from ._bootstrap import module_from_spec +from ._bootstrap import _resolve_name +from ._bootstrap import spec_from_loader +from ._bootstrap import _find_spec +from ._bootstrap_external import MAGIC_NUMBER +from ._bootstrap_external import _RAW_MAGIC_NUMBER +from ._bootstrap_external import cache_from_source +from ._bootstrap_external import decode_source +from ._bootstrap_external import source_from_cache +from ._bootstrap_external import spec_from_file_location + +from contextlib import contextmanager +import _imp +import functools +import sys +import types +import warnings + + +def source_hash(source_bytes): + "Return the hash of *source_bytes* as used in hash-based pyc files." + return _imp.source_hash(_RAW_MAGIC_NUMBER, source_bytes) + + +def resolve_name(name, package): + """Resolve a relative module name to an absolute one.""" + if not name.startswith('.'): + return name + elif not package: + raise ValueError(f'no package specified for {repr(name)} ' + '(required for relative module names)') + level = 0 + for character in name: + if character != '.': + break + level += 1 + return _resolve_name(name[level:], package, level) + + +def _find_spec_from_path(name, path=None): + """Return the spec for the specified module. + + First, sys.modules is checked to see if the module was already imported. If + so, then sys.modules[name].__spec__ is returned. If that happens to be + set to None, then ValueError is raised. If the module is not in + sys.modules, then sys.meta_path is searched for a suitable spec with the + value of 'path' given to the finders. None is returned if no spec could + be found. + + Dotted names do not have their parent packages implicitly imported. You will + most likely need to explicitly import all parent packages in the proper + order for a submodule to get the correct spec. + + """ + if name not in sys.modules: + return _find_spec(name, path) + else: + module = sys.modules[name] + if module is None: + return None + try: + spec = module.__spec__ + except AttributeError: + raise ValueError('{}.__spec__ is not set'.format(name)) from None + else: + if spec is None: + raise ValueError('{}.__spec__ is None'.format(name)) + return spec + + +def find_spec(name, package=None): + """Return the spec for the specified module. + + First, sys.modules is checked to see if the module was already imported. If + so, then sys.modules[name].__spec__ is returned. If that happens to be + set to None, then ValueError is raised. If the module is not in + sys.modules, then sys.meta_path is searched for a suitable spec with the + value of 'path' given to the finders. None is returned if no spec could + be found. + + If the name is for submodule (contains a dot), the parent module is + automatically imported. + + The name and package arguments work the same as importlib.import_module(). + In other words, relative module names (with leading dots) work. + + """ + fullname = resolve_name(name, package) if name.startswith('.') else name + if fullname not in sys.modules: + parent_name = fullname.rpartition('.')[0] + if parent_name: + parent = __import__(parent_name, fromlist=['__path__']) + try: + parent_path = parent.__path__ + except AttributeError as e: + raise ModuleNotFoundError( + f"__path__ attribute not found on {parent_name!r} " + f"while trying to find {fullname!r}", name=fullname) from e + else: + parent_path = None + return _find_spec(fullname, parent_path) + else: + module = sys.modules[fullname] + if module is None: + return None + try: + spec = module.__spec__ + except AttributeError: + raise ValueError('{}.__spec__ is not set'.format(name)) from None + else: + if spec is None: + raise ValueError('{}.__spec__ is None'.format(name)) + return spec + + +@contextmanager +def _module_to_load(name): + is_reload = name in sys.modules + + module = sys.modules.get(name) + if not is_reload: + # This must be done before open() is called as the 'io' module + # implicitly imports 'locale' and would otherwise trigger an + # infinite loop. + module = type(sys)(name) + # This must be done before putting the module in sys.modules + # (otherwise an optimization shortcut in import.c becomes wrong) + module.__initializing__ = True + sys.modules[name] = module + try: + yield module + except Exception: + if not is_reload: + try: + del sys.modules[name] + except KeyError: + pass + finally: + module.__initializing__ = False + + +def set_package(fxn): + """Set __package__ on the returned module. + + This function is deprecated. + + """ + @functools.wraps(fxn) + def set_package_wrapper(*args, **kwargs): + warnings.warn('The import system now takes care of this automatically.', + DeprecationWarning, stacklevel=2) + module = fxn(*args, **kwargs) + if getattr(module, '__package__', None) is None: + module.__package__ = module.__name__ + if not hasattr(module, '__path__'): + module.__package__ = module.__package__.rpartition('.')[0] + return module + return set_package_wrapper + + +def set_loader(fxn): + """Set __loader__ on the returned module. + + This function is deprecated. + + """ + @functools.wraps(fxn) + def set_loader_wrapper(self, *args, **kwargs): + warnings.warn('The import system now takes care of this automatically.', + DeprecationWarning, stacklevel=2) + module = fxn(self, *args, **kwargs) + if getattr(module, '__loader__', None) is None: + module.__loader__ = self + return module + return set_loader_wrapper + + +def module_for_loader(fxn): + """Decorator to handle selecting the proper module for loaders. + + The decorated function is passed the module to use instead of the module + name. The module passed in to the function is either from sys.modules if + it already exists or is a new module. If the module is new, then __name__ + is set the first argument to the method, __loader__ is set to self, and + __package__ is set accordingly (if self.is_package() is defined) will be set + before it is passed to the decorated function (if self.is_package() does + not work for the module it will be set post-load). + + If an exception is raised and the decorator created the module it is + subsequently removed from sys.modules. + + The decorator assumes that the decorated function takes the module name as + the second argument. + + """ + warnings.warn('The import system now takes care of this automatically.', + DeprecationWarning, stacklevel=2) + @functools.wraps(fxn) + def module_for_loader_wrapper(self, fullname, *args, **kwargs): + with _module_to_load(fullname) as module: + module.__loader__ = self + try: + is_package = self.is_package(fullname) + except (ImportError, AttributeError): + pass + else: + if is_package: + module.__package__ = fullname + else: + module.__package__ = fullname.rpartition('.')[0] + # If __package__ was not set above, __import__() will do it later. + return fxn(self, module, *args, **kwargs) + + return module_for_loader_wrapper + + +class _LazyModule(types.ModuleType): + + """A subclass of the module type which triggers loading upon attribute access.""" + + def __getattribute__(self, attr): + """Trigger the load of the module and return the attribute.""" + # All module metadata must be garnered from __spec__ in order to avoid + # using mutated values. + # Stop triggering this method. + self.__class__ = types.ModuleType + # Get the original name to make sure no object substitution occurred + # in sys.modules. + original_name = self.__spec__.name + # Figure out exactly what attributes were mutated between the creation + # of the module and now. + attrs_then = self.__spec__.loader_state['__dict__'] + original_type = self.__spec__.loader_state['__class__'] + attrs_now = self.__dict__ + attrs_updated = {} + for key, value in attrs_now.items(): + # Code that set the attribute may have kept a reference to the + # assigned object, making identity more important than equality. + if key not in attrs_then: + attrs_updated[key] = value + elif id(attrs_now[key]) != id(attrs_then[key]): + attrs_updated[key] = value + self.__spec__.loader.exec_module(self) + # If exec_module() was used directly there is no guarantee the module + # object was put into sys.modules. + if original_name in sys.modules: + if id(self) != id(sys.modules[original_name]): + raise ValueError(f"module object for {original_name!r} " + "substituted in sys.modules during a lazy " + "load") + # Update after loading since that's what would happen in an eager + # loading situation. + self.__dict__.update(attrs_updated) + return getattr(self, attr) + + def __delattr__(self, attr): + """Trigger the load and then perform the deletion.""" + # To trigger the load and raise an exception if the attribute + # doesn't exist. + self.__getattribute__(attr) + delattr(self, attr) + + +class LazyLoader(abc.Loader): + + """A loader that creates a module which defers loading until attribute access.""" + + @staticmethod + def __check_eager_loader(loader): + if not hasattr(loader, 'exec_module'): + raise TypeError('loader must define exec_module()') + + @classmethod + def factory(cls, loader): + """Construct a callable which returns the eager loader made lazy.""" + cls.__check_eager_loader(loader) + return lambda *args, **kwargs: cls(loader(*args, **kwargs)) + + def __init__(self, loader): + self.__check_eager_loader(loader) + self.loader = loader + + def create_module(self, spec): + return self.loader.create_module(spec) + + def exec_module(self, module): + """Make the module load lazily.""" + module.__spec__.loader = self.loader + module.__loader__ = self.loader + # Don't need to worry about deep-copying as trying to set an attribute + # on an object would have triggered the load, + # e.g. ``module.__spec__.loader = None`` would trigger a load from + # trying to access module.__spec__. + loader_state = {} + loader_state['__dict__'] = module.__dict__.copy() + loader_state['__class__'] = module.__class__ + module.__spec__.loader_state = loader_state + module.__class__ = _LazyModule diff --git a/Lib/io.py b/Lib/io.py new file mode 100644 index 0000000..968ee50 --- /dev/null +++ b/Lib/io.py @@ -0,0 +1,99 @@ +"""The io module provides the Python interfaces to stream handling. The +builtin open function is defined in this module. + +At the top of the I/O hierarchy is the abstract base class IOBase. It +defines the basic interface to a stream. Note, however, that there is no +separation between reading and writing to streams; implementations are +allowed to raise an OSError if they do not support a given operation. + +Extending IOBase is RawIOBase which deals simply with the reading and +writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide +an interface to OS files. + +BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its +subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer +streams that are readable, writable, and both respectively. +BufferedRandom provides a buffered interface to random access +streams. BytesIO is a simple stream of in-memory bytes. + +Another IOBase subclass, TextIOBase, deals with the encoding and decoding +of streams into text. TextIOWrapper, which extends it, is a buffered text +interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO +is an in-memory stream for text. + +Argument names are not part of the specification, and only the arguments +of open() are intended to be used as keyword arguments. + +data: + +DEFAULT_BUFFER_SIZE + + An int containing the default buffer size used by the module's buffered + I/O classes. open() uses the file's blksize (as obtained by os.stat) if + possible. +""" +# New I/O library conforming to PEP 3116. + +__author__ = ("Guido van Rossum , " + "Mike Verdone , " + "Mark Russell , " + "Antoine Pitrou , " + "Amaury Forgeot d'Arc , " + "Benjamin Peterson ") + +__all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO", + "BytesIO", "StringIO", "BufferedIOBase", + "BufferedReader", "BufferedWriter", "BufferedRWPair", + "BufferedRandom", "TextIOBase", "TextIOWrapper", + "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"] + + +import _io +import abc + +from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, + open, FileIO, BytesIO, StringIO, BufferedReader, + BufferedWriter, BufferedRWPair, BufferedRandom, + IncrementalNewlineDecoder, TextIOWrapper) + +OpenWrapper = _io.open # for compatibility with _pyio + +# Pretend this exception was created here. +UnsupportedOperation.__module__ = "io" + +# for seek() +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + +# Declaring ABCs in C is tricky so we do it here. +# Method descriptions and default implementations are inherited from the C +# version however. +class IOBase(_io._IOBase, metaclass=abc.ABCMeta): + __doc__ = _io._IOBase.__doc__ + +class RawIOBase(_io._RawIOBase, IOBase): + __doc__ = _io._RawIOBase.__doc__ + +class BufferedIOBase(_io._BufferedIOBase, IOBase): + __doc__ = _io._BufferedIOBase.__doc__ + +class TextIOBase(_io._TextIOBase, IOBase): + __doc__ = _io._TextIOBase.__doc__ + +RawIOBase.register(FileIO) + +for klass in (BytesIO, BufferedReader, BufferedWriter, BufferedRandom, + BufferedRWPair): + BufferedIOBase.register(klass) + +for klass in (StringIO, TextIOWrapper): + TextIOBase.register(klass) +del klass + +try: + from _io import _WindowsConsoleIO +except ImportError: + pass +else: + RawIOBase.register(_WindowsConsoleIO) diff --git a/Lib/keyword.py b/Lib/keyword.py new file mode 100644 index 0000000..431991d --- /dev/null +++ b/Lib/keyword.py @@ -0,0 +1,96 @@ +#! /usr/bin/env python3 + +"""Keywords (from "graminit.c") + +This file is automatically generated; please don't muck it up! + +To update the symbols in this file, 'cd' to the top directory of +the python source tree after building the interpreter and run: + + ./python Lib/keyword.py +""" + +__all__ = ["iskeyword", "kwlist"] + +kwlist = [ +#--start keywords-- + 'False', + 'None', + 'True', + 'and', + 'as', + 'assert', + 'async', + 'await', + 'break', + 'class', + 'continue', + 'def', + 'del', + 'elif', + 'else', + 'except', + 'finally', + 'for', + 'from', + 'global', + 'if', + 'import', + 'in', + 'is', + 'lambda', + 'nonlocal', + 'not', + 'or', + 'pass', + 'raise', + 'return', + 'try', + 'while', + 'with', + 'yield', +#--end keywords-- + ] + +iskeyword = frozenset(kwlist).__contains__ + +def main(): + import sys, re + + args = sys.argv[1:] + iptfile = args and args[0] or "Python/graminit.c" + if len(args) > 1: optfile = args[1] + else: optfile = "Lib/keyword.py" + + # load the output skeleton from the target, taking care to preserve its + # newline convention. + with open(optfile, newline='') as fp: + format = fp.readlines() + nl = format[0][len(format[0].strip()):] if format else '\n' + + # scan the source file for keywords + with open(iptfile) as fp: + strprog = re.compile('"([^"]+)"') + lines = [] + for line in fp: + if '{1, "' in line: + match = strprog.search(line) + if match: + lines.append(" '" + match.group(1) + "'," + nl) + lines.sort() + + # insert the lines of keywords into the skeleton + try: + start = format.index("#--start keywords--" + nl) + 1 + end = format.index("#--end keywords--" + nl) + format[start:end] = lines + except ValueError: + sys.stderr.write("target does not contain format markers\n") + sys.exit(1) + + # write the output file + with open(optfile, 'w', newline='') as fp: + fp.writelines(format) + +if __name__ == "__main__": + main() diff --git a/Lib/linecache.py b/Lib/linecache.py new file mode 100644 index 0000000..3afcce1 --- /dev/null +++ b/Lib/linecache.py @@ -0,0 +1,177 @@ +"""Cache lines from Python source files. + +This is intended to read lines from modules imported -- hence if a filename +is not found, it will look down the module search path for a file by +that name. +""" + +import functools +import sys +import os +import tokenize + +__all__ = ["getline", "clearcache", "checkcache"] + +def getline(filename, lineno, module_globals=None): + lines = getlines(filename, module_globals) + if 1 <= lineno <= len(lines): + return lines[lineno-1] + else: + return '' + + +# The cache + +# The cache. Maps filenames to either a thunk which will provide source code, +# or a tuple (size, mtime, lines, fullname) once loaded. +cache = {} + + +def clearcache(): + """Clear the cache entirely.""" + + global cache + cache = {} + + +def getlines(filename, module_globals=None): + """Get the lines for a Python source file from the cache. + Update the cache if it doesn't contain an entry for this file already.""" + + if filename in cache: + entry = cache[filename] + if len(entry) != 1: + return cache[filename][2] + + try: + return updatecache(filename, module_globals) + except MemoryError: + clearcache() + return [] + + +def checkcache(filename=None): + """Discard cache entries that are out of date. + (This is not checked upon each call!)""" + + if filename is None: + filenames = list(cache.keys()) + else: + if filename in cache: + filenames = [filename] + else: + return + + for filename in filenames: + entry = cache[filename] + if len(entry) == 1: + # lazy cache entry, leave it lazy. + continue + size, mtime, lines, fullname = entry + if mtime is None: + continue # no-op for files loaded via a __loader__ + try: + stat = os.stat(fullname) + except OSError: + del cache[filename] + continue + if size != stat.st_size or mtime != stat.st_mtime: + del cache[filename] + + +def updatecache(filename, module_globals=None): + """Update a cache entry and return its list of lines. + If something's wrong, print a message, discard the cache entry, + and return an empty list.""" + + if filename in cache: + if len(cache[filename]) != 1: + del cache[filename] + if not filename or (filename.startswith('<') and filename.endswith('>')): + return [] + + fullname = filename + try: + stat = os.stat(fullname) + except OSError: + basename = filename + + # Realise a lazy loader based lookup if there is one + # otherwise try to lookup right now. + if lazycache(filename, module_globals): + try: + data = cache[filename][0]() + except (ImportError, OSError): + pass + else: + if data is None: + # No luck, the PEP302 loader cannot find the source + # for this module. + return [] + cache[filename] = ( + len(data), None, + [line+'\n' for line in data.splitlines()], fullname + ) + return cache[filename][2] + + # Try looking through the module search path, which is only useful + # when handling a relative filename. + if os.path.isabs(filename): + return [] + + for dirname in sys.path: + try: + fullname = os.path.join(dirname, basename) + except (TypeError, AttributeError): + # Not sufficiently string-like to do anything useful with. + continue + try: + stat = os.stat(fullname) + break + except OSError: + pass + else: + return [] + try: + with tokenize.open(fullname) as fp: + lines = fp.readlines() + except OSError: + return [] + if lines and not lines[-1].endswith('\n'): + lines[-1] += '\n' + size, mtime = stat.st_size, stat.st_mtime + cache[filename] = size, mtime, lines, fullname + return lines + + +def lazycache(filename, module_globals): + """Seed the cache for filename with module_globals. + + The module loader will be asked for the source only when getlines is + called, not immediately. + + If there is an entry in the cache already, it is not altered. + + :return: True if a lazy load is registered in the cache, + otherwise False. To register such a load a module loader with a + get_source method must be found, the filename must be a cachable + filename, and the filename must not be already cached. + """ + if filename in cache: + if len(cache[filename]) == 1: + return True + else: + return False + if not filename or (filename.startswith('<') and filename.endswith('>')): + return False + # Try for a __loader__, if available + if module_globals and '__loader__' in module_globals: + name = module_globals.get('__name__') + loader = module_globals['__loader__'] + get_source = getattr(loader, 'get_source', None) + + if name and get_source: + get_lines = functools.partial(get_source, name) + cache[filename] = (get_lines,) + return True + return False diff --git a/Lib/locale.py b/Lib/locale.py new file mode 100644 index 0000000..f3d3973 --- /dev/null +++ b/Lib/locale.py @@ -0,0 +1,1749 @@ +"""Locale support module. + +The module provides low-level access to the C lib's locale APIs and adds high +level number formatting APIs as well as a locale aliasing engine to complement +these. + +The aliasing engine includes support for many commonly used locale names and +maps them to values suitable for passing to the C lib's setlocale() function. It +also includes default encodings for all supported locale names. + +""" + +import sys +import encodings +import encodings.aliases +import re +import _collections_abc +from builtins import str as _builtin_str +import functools + +# Try importing the _locale module. +# +# If this fails, fall back on a basic 'C' locale emulation. + +# Yuck: LC_MESSAGES is non-standard: can't tell whether it exists before +# trying the import. So __all__ is also fiddled at the end of the file. +__all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error", + "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm", + "str", "atof", "atoi", "format", "format_string", "currency", + "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY", + "LC_NUMERIC", "LC_ALL", "CHAR_MAX"] + +def _strcoll(a,b): + """ strcoll(string,string) -> int. + Compares two strings according to the locale. + """ + return (a > b) - (a < b) + +def _strxfrm(s): + """ strxfrm(string) -> string. + Returns a string that behaves for cmp locale-aware. + """ + return s + +try: + + from _locale import * + +except ImportError: + + # Locale emulation + + CHAR_MAX = 127 + LC_ALL = 6 + LC_COLLATE = 3 + LC_CTYPE = 0 + LC_MESSAGES = 5 + LC_MONETARY = 4 + LC_NUMERIC = 1 + LC_TIME = 2 + Error = ValueError + + def localeconv(): + """ localeconv() -> dict. + Returns numeric and monetary locale-specific parameters. + """ + # 'C' locale default values + return {'grouping': [127], + 'currency_symbol': '', + 'n_sign_posn': 127, + 'p_cs_precedes': 127, + 'n_cs_precedes': 127, + 'mon_grouping': [], + 'n_sep_by_space': 127, + 'decimal_point': '.', + 'negative_sign': '', + 'positive_sign': '', + 'p_sep_by_space': 127, + 'int_curr_symbol': '', + 'p_sign_posn': 127, + 'thousands_sep': '', + 'mon_thousands_sep': '', + 'frac_digits': 127, + 'mon_decimal_point': '', + 'int_frac_digits': 127} + + def setlocale(category, value=None): + """ setlocale(integer,string=None) -> string. + Activates/queries locale processing. + """ + if value not in (None, '', 'C'): + raise Error('_locale emulation only supports "C" locale') + return 'C' + +# These may or may not exist in _locale, so be sure to set them. +if 'strxfrm' not in globals(): + strxfrm = _strxfrm +if 'strcoll' not in globals(): + strcoll = _strcoll + + +_localeconv = localeconv + +# With this dict, you can override some items of localeconv's return value. +# This is useful for testing purposes. +_override_localeconv = {} + +@functools.wraps(_localeconv) +def localeconv(): + d = _localeconv() + if _override_localeconv: + d.update(_override_localeconv) + return d + + +### Number formatting APIs + +# Author: Martin von Loewis +# improved by Georg Brandl + +# Iterate over grouping intervals +def _grouping_intervals(grouping): + last_interval = None + for interval in grouping: + # if grouping is -1, we are done + if interval == CHAR_MAX: + return + # 0: re-use last group ad infinitum + if interval == 0: + if last_interval is None: + raise ValueError("invalid grouping") + while True: + yield last_interval + yield interval + last_interval = interval + +#perform the grouping from right to left +def _group(s, monetary=False): + conv = localeconv() + thousands_sep = conv[monetary and 'mon_thousands_sep' or 'thousands_sep'] + grouping = conv[monetary and 'mon_grouping' or 'grouping'] + if not grouping: + return (s, 0) + if s[-1] == ' ': + stripped = s.rstrip() + right_spaces = s[len(stripped):] + s = stripped + else: + right_spaces = '' + left_spaces = '' + groups = [] + for interval in _grouping_intervals(grouping): + if not s or s[-1] not in "0123456789": + # only non-digit characters remain (sign, spaces) + left_spaces = s + s = '' + break + groups.append(s[-interval:]) + s = s[:-interval] + if s: + groups.append(s) + groups.reverse() + return ( + left_spaces + thousands_sep.join(groups) + right_spaces, + len(thousands_sep) * (len(groups) - 1) + ) + +# Strip a given amount of excess padding from the given string +def _strip_padding(s, amount): + lpos = 0 + while amount and s[lpos] == ' ': + lpos += 1 + amount -= 1 + rpos = len(s) - 1 + while amount and s[rpos] == ' ': + rpos -= 1 + amount -= 1 + return s[lpos:rpos+1] + +_percent_re = re.compile(r'%(?:\((?P.*?)\))?' + r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') + +def _format(percent, value, grouping=False, monetary=False, *additional): + if additional: + formatted = percent % ((value,) + additional) + else: + formatted = percent % value + # floats and decimal ints need special action! + if percent[-1] in 'eEfFgG': + seps = 0 + parts = formatted.split('.') + if grouping: + parts[0], seps = _group(parts[0], monetary=monetary) + decimal_point = localeconv()[monetary and 'mon_decimal_point' + or 'decimal_point'] + formatted = decimal_point.join(parts) + if seps: + formatted = _strip_padding(formatted, seps) + elif percent[-1] in 'diu': + seps = 0 + if grouping: + formatted, seps = _group(formatted, monetary=monetary) + if seps: + formatted = _strip_padding(formatted, seps) + return formatted + +def format_string(f, val, grouping=False, monetary=False): + """Formats a string in the same way that the % formatting would use, + but takes the current locale into account. + + Grouping is applied if the third parameter is true. + Conversion uses monetary thousands separator and grouping strings if + forth parameter monetary is true.""" + percents = list(_percent_re.finditer(f)) + new_f = _percent_re.sub('%s', f) + + if isinstance(val, _collections_abc.Mapping): + new_val = [] + for perc in percents: + if perc.group()[-1]=='%': + new_val.append('%') + else: + new_val.append(_format(perc.group(), val, grouping, monetary)) + else: + if not isinstance(val, tuple): + val = (val,) + new_val = [] + i = 0 + for perc in percents: + if perc.group()[-1]=='%': + new_val.append('%') + else: + starcount = perc.group('modifiers').count('*') + new_val.append(_format(perc.group(), + val[i], + grouping, + monetary, + *val[i+1:i+1+starcount])) + i += (1 + starcount) + val = tuple(new_val) + + return new_f % val + +def format(percent, value, grouping=False, monetary=False, *additional): + """Deprecated, use format_string instead.""" + import warnings + warnings.warn( + "This method will be removed in a future version of Python. " + "Use 'locale.format_string()' instead.", + DeprecationWarning, stacklevel=2 + ) + + match = _percent_re.match(percent) + if not match or len(match.group())!= len(percent): + raise ValueError(("format() must be given exactly one %%char " + "format specifier, %s not valid") % repr(percent)) + return _format(percent, value, grouping, monetary, *additional) + +def currency(val, symbol=True, grouping=False, international=False): + """Formats val according to the currency settings + in the current locale.""" + conv = localeconv() + + # check for illegal values + digits = conv[international and 'int_frac_digits' or 'frac_digits'] + if digits == 127: + raise ValueError("Currency formatting is not possible using " + "the 'C' locale.") + + s = _format('%%.%if' % digits, abs(val), grouping, monetary=True) + # '<' and '>' are markers if the sign must be inserted between symbol and value + s = '<' + s + '>' + + if symbol: + smb = conv[international and 'int_curr_symbol' or 'currency_symbol'] + precedes = conv[val<0 and 'n_cs_precedes' or 'p_cs_precedes'] + separated = conv[val<0 and 'n_sep_by_space' or 'p_sep_by_space'] + + if precedes: + s = smb + (separated and ' ' or '') + s + else: + s = s + (separated and ' ' or '') + smb + + sign_pos = conv[val<0 and 'n_sign_posn' or 'p_sign_posn'] + sign = conv[val<0 and 'negative_sign' or 'positive_sign'] + + if sign_pos == 0: + s = '(' + s + ')' + elif sign_pos == 1: + s = sign + s + elif sign_pos == 2: + s = s + sign + elif sign_pos == 3: + s = s.replace('<', sign) + elif sign_pos == 4: + s = s.replace('>', sign) + else: + # the default if nothing specified; + # this should be the most fitting sign position + s = sign + s + + return s.replace('<', '').replace('>', '') + +def str(val): + """Convert float to string, taking the locale into account.""" + return _format("%.12g", val) + +def delocalize(string): + "Parses a string as a normalized number according to the locale settings." + + conv = localeconv() + + #First, get rid of the grouping + ts = conv['thousands_sep'] + if ts: + string = string.replace(ts, '') + + #next, replace the decimal point with a dot + dd = conv['decimal_point'] + if dd: + string = string.replace(dd, '.') + return string + +def atof(string, func=float): + "Parses a string as a float according to the locale settings." + return func(delocalize(string)) + +def atoi(string): + "Converts a string to an integer according to the locale settings." + return int(delocalize(string)) + +def _test(): + setlocale(LC_ALL, "") + #do grouping + s1 = format_string("%d", 123456789,1) + print(s1, "is", atoi(s1)) + #standard formatting + s1 = str(3.14) + print(s1, "is", atof(s1)) + +### Locale name aliasing engine + +# Author: Marc-Andre Lemburg, mal@lemburg.com +# Various tweaks by Fredrik Lundh + +# store away the low-level version of setlocale (it's +# overridden below) +_setlocale = setlocale + +def _replace_encoding(code, encoding): + if '.' in code: + langname = code[:code.index('.')] + else: + langname = code + # Convert the encoding to a C lib compatible encoding string + norm_encoding = encodings.normalize_encoding(encoding) + #print('norm encoding: %r' % norm_encoding) + norm_encoding = encodings.aliases.aliases.get(norm_encoding.lower(), + norm_encoding) + #print('aliased encoding: %r' % norm_encoding) + encoding = norm_encoding + norm_encoding = norm_encoding.lower() + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + else: + norm_encoding = norm_encoding.replace('_', '') + norm_encoding = norm_encoding.replace('-', '') + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + #print('found encoding %r' % encoding) + return langname + '.' + encoding + +def _append_modifier(code, modifier): + if modifier == 'euro': + if '.' not in code: + return code + '.ISO8859-15' + _, _, encoding = code.partition('.') + if encoding in ('ISO8859-15', 'UTF-8'): + return code + if encoding == 'ISO8859-1': + return _replace_encoding(code, 'ISO8859-15') + return code + '@' + modifier + +def normalize(localename): + + """ Returns a normalized locale code for the given locale + name. + + The returned locale code is formatted for use with + setlocale(). + + If normalization fails, the original name is returned + unchanged. + + If the given encoding is not known, the function defaults to + the default encoding for the locale code just like setlocale() + does. + + """ + # Normalize the locale name and extract the encoding and modifier + code = localename.lower() + if ':' in code: + # ':' is sometimes used as encoding delimiter. + code = code.replace(':', '.') + if '@' in code: + code, modifier = code.split('@', 1) + else: + modifier = '' + if '.' in code: + langname, encoding = code.split('.')[:2] + else: + langname = code + encoding = '' + + # First lookup: fullname (possibly with encoding and modifier) + lang_enc = langname + if encoding: + norm_encoding = encoding.replace('-', '') + norm_encoding = norm_encoding.replace('_', '') + lang_enc += '.' + norm_encoding + lookup_name = lang_enc + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + return code + #print('first lookup failed') + + if modifier: + # Second try: fullname without modifier (possibly with encoding) + code = locale_alias.get(lang_enc, None) + if code is not None: + #print('lookup without modifier succeeded') + if '@' not in code: + return _append_modifier(code, modifier) + if code.split('@', 1)[1].lower() == modifier: + return code + #print('second lookup failed') + + if encoding: + # Third try: langname (without encoding, possibly with modifier) + lookup_name = langname + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + #print('lookup without encoding succeeded') + if '@' not in code: + return _replace_encoding(code, encoding) + code, modifier = code.split('@', 1) + return _replace_encoding(code, encoding) + '@' + modifier + + if modifier: + # Fourth try: langname (without encoding and modifier) + code = locale_alias.get(langname, None) + if code is not None: + #print('lookup without modifier and encoding succeeded') + if '@' not in code: + code = _replace_encoding(code, encoding) + return _append_modifier(code, modifier) + code, defmod = code.split('@', 1) + if defmod.lower() == modifier: + return _replace_encoding(code, encoding) + '@' + defmod + + return localename + +def _parse_localename(localename): + + """ Parses the locale code for localename and returns the + result as tuple (language code, encoding). + + The localename is normalized and passed through the locale + alias engine. A ValueError is raised in case the locale name + cannot be parsed. + + The language code corresponds to RFC 1766. code and encoding + can be None in case the values cannot be determined or are + unknown to this implementation. + + """ + code = normalize(localename) + if '@' in code: + # Deal with locale modifiers + code, modifier = code.split('@', 1) + if modifier == 'euro' and '.' not in code: + # Assume Latin-9 for @euro locales. This is bogus, + # since some systems may use other encodings for these + # locales. Also, we ignore other modifiers. + return code, 'iso-8859-15' + + if '.' in code: + return tuple(code.split('.')[:2]) + elif code == 'C': + return None, None + raise ValueError('unknown locale: %s' % localename) + +def _build_localename(localetuple): + + """ Builds a locale code from the given tuple (language code, + encoding). + + No aliasing or normalizing takes place. + + """ + try: + language, encoding = localetuple + + if language is None: + language = 'C' + if encoding is None: + return language + else: + return language + '.' + encoding + except (TypeError, ValueError): + raise TypeError('Locale must be None, a string, or an iterable of ' + 'two strings -- language code, encoding.') from None + +def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): + + """ Tries to determine the default locale settings and returns + them as tuple (language code, encoding). + + According to POSIX, a program which has not called + setlocale(LC_ALL, "") runs using the portable 'C' locale. + Calling setlocale(LC_ALL, "") lets it use the default locale as + defined by the LANG variable. Since we don't want to interfere + with the current locale setting we thus emulate the behavior + in the way described above. + + To maintain compatibility with other platforms, not only the + LANG variable is tested, but a list of variables given as + envvars parameter. The first found to be defined will be + used. envvars defaults to the search path used in GNU gettext; + it must always contain the variable name 'LANG'. + + Except for the code 'C', the language code corresponds to RFC + 1766. code and encoding can be None in case the values cannot + be determined. + + """ + + try: + # check if it's supported by the _locale module + import _locale + code, encoding = _locale._getdefaultlocale() + except (ImportError, AttributeError): + pass + else: + # make sure the code/encoding values are valid + if sys.platform == "win32" and code and code[:2] == "0x": + # map windows language identifier to language name + code = windows_locale.get(int(code, 0)) + # ...add other platform-specific processing here, if + # necessary... + return code, encoding + + # fall back on POSIX behaviour + import os + lookup = os.environ.get + for variable in envvars: + localename = lookup(variable,None) + if localename: + if variable == 'LANGUAGE': + localename = localename.split(':')[0] + break + else: + localename = 'C' + return _parse_localename(localename) + + +def getlocale(category=LC_CTYPE): + + """ Returns the current setting for the given locale category as + tuple (language code, encoding). + + category may be one of the LC_* value except LC_ALL. It + defaults to LC_CTYPE. + + Except for the code 'C', the language code corresponds to RFC + 1766. code and encoding can be None in case the values cannot + be determined. + + """ + localename = _setlocale(category) + if category == LC_ALL and ';' in localename: + raise TypeError('category LC_ALL is not supported') + return _parse_localename(localename) + +def setlocale(category, locale=None): + + """ Set the locale for the given category. The locale can be + a string, an iterable of two strings (language code and encoding), + or None. + + Iterables are converted to strings using the locale aliasing + engine. Locale strings are passed directly to the C lib. + + category may be given as one of the LC_* values. + + """ + if locale and not isinstance(locale, _builtin_str): + # convert to string + locale = normalize(_build_localename(locale)) + return _setlocale(category, locale) + +def resetlocale(category=LC_ALL): + + """ Sets the locale for category to the default setting. + + The default setting is determined by calling + getdefaultlocale(). category defaults to LC_ALL. + + """ + _setlocale(category, _build_localename(getdefaultlocale())) + +if sys.platform.startswith("win"): + # On Win32, this will return the ANSI code page + def getpreferredencoding(do_setlocale = True): + """Return the charset that the user is likely using.""" + if sys.flags.utf8_mode: + return 'UTF-8' + import _bootlocale + return _bootlocale.getpreferredencoding(False) +else: + # On Unix, if CODESET is available, use that. + try: + CODESET + except NameError: + if hasattr(sys, 'getandroidapilevel'): + # On Android langinfo.h and CODESET are missing, and UTF-8 is + # always used in mbstowcs() and wcstombs(). + def getpreferredencoding(do_setlocale = True): + return 'UTF-8' + else: + # Fall back to parsing environment variables :-( + def getpreferredencoding(do_setlocale = True): + """Return the charset that the user is likely using, + by looking at environment variables.""" + if sys.flags.utf8_mode: + return 'UTF-8' + res = getdefaultlocale()[1] + if res is None: + # LANG not set, default conservatively to ASCII + res = 'ascii' + return res + else: + def getpreferredencoding(do_setlocale = True): + """Return the charset that the user is likely using, + according to the system configuration.""" + if sys.flags.utf8_mode: + return 'UTF-8' + import _bootlocale + if do_setlocale: + oldloc = setlocale(LC_CTYPE) + try: + setlocale(LC_CTYPE, "") + except Error: + pass + result = _bootlocale.getpreferredencoding(False) + if do_setlocale: + setlocale(LC_CTYPE, oldloc) + return result + + +### Database +# +# The following data was extracted from the locale.alias file which +# comes with X11 and then hand edited removing the explicit encoding +# definitions and adding some more aliases. The file is usually +# available as /usr/lib/X11/locale/locale.alias. +# + +# +# The local_encoding_alias table maps lowercase encoding alias names +# to C locale encoding names (case-sensitive). Note that normalize() +# first looks up the encoding in the encodings.aliases dictionary and +# then applies this mapping to find the correct C lib name for the +# encoding. +# +locale_encoding_alias = { + + # Mappings for non-standard encoding names used in locale names + '437': 'C', + 'c': 'C', + 'en': 'ISO8859-1', + 'jis': 'JIS7', + 'jis7': 'JIS7', + 'ajec': 'eucJP', + 'koi8c': 'KOI8-C', + 'microsoftcp1251': 'CP1251', + 'microsoftcp1255': 'CP1255', + 'microsoftcp1256': 'CP1256', + '88591': 'ISO8859-1', + '88592': 'ISO8859-2', + '88595': 'ISO8859-5', + '885915': 'ISO8859-15', + + # Mappings from Python codec names to C lib encoding names + 'ascii': 'ISO8859-1', + 'latin_1': 'ISO8859-1', + 'iso8859_1': 'ISO8859-1', + 'iso8859_10': 'ISO8859-10', + 'iso8859_11': 'ISO8859-11', + 'iso8859_13': 'ISO8859-13', + 'iso8859_14': 'ISO8859-14', + 'iso8859_15': 'ISO8859-15', + 'iso8859_16': 'ISO8859-16', + 'iso8859_2': 'ISO8859-2', + 'iso8859_3': 'ISO8859-3', + 'iso8859_4': 'ISO8859-4', + 'iso8859_5': 'ISO8859-5', + 'iso8859_6': 'ISO8859-6', + 'iso8859_7': 'ISO8859-7', + 'iso8859_8': 'ISO8859-8', + 'iso8859_9': 'ISO8859-9', + 'iso2022_jp': 'JIS7', + 'shift_jis': 'SJIS', + 'tactis': 'TACTIS', + 'euc_jp': 'eucJP', + 'euc_kr': 'eucKR', + 'utf_8': 'UTF-8', + 'koi8_r': 'KOI8-R', + 'koi8_t': 'KOI8-T', + 'koi8_u': 'KOI8-U', + 'kz1048': 'RK1048', + 'cp1251': 'CP1251', + 'cp1255': 'CP1255', + 'cp1256': 'CP1256', + + # XXX This list is still incomplete. If you know more + # mappings, please file a bug report. Thanks. +} + +for k, v in sorted(locale_encoding_alias.items()): + k = k.replace('_', '') + locale_encoding_alias.setdefault(k, v) + +# +# The locale_alias table maps lowercase alias names to C locale names +# (case-sensitive). Encodings are always separated from the locale +# name using a dot ('.'); they should only be given in case the +# language name is needed to interpret the given encoding alias +# correctly (CJK codes often have this need). +# +# Note that the normalize() function which uses this tables +# removes '_' and '-' characters from the encoding part of the +# locale name before doing the lookup. This saves a lot of +# space in the table. +# +# MAL 2004-12-10: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.4 +# and older): +# +# updated 'bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'bg_bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'bulgarian' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'cz_cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'czech' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'dutch' -> 'nl_BE.ISO8859-1' to 'nl_NL.ISO8859-1' +# updated 'et' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' +# updated 'et_ee' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' +# updated 'fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' +# updated 'fi_fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' +# updated 'iw' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'iw_il' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'japanese' -> 'ja_JP.SJIS' to 'ja_JP.eucJP' +# updated 'lt' -> 'lt_LT.ISO8859-4' to 'lt_LT.ISO8859-13' +# updated 'lv' -> 'lv_LV.ISO8859-4' to 'lv_LV.ISO8859-13' +# updated 'sl' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' +# updated 'slovene' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' +# updated 'th_th' -> 'th_TH.TACTIS' to 'th_TH.ISO8859-11' +# updated 'zh_cn' -> 'zh_CN.eucCN' to 'zh_CN.gb2312' +# updated 'zh_cn.big5' -> 'zh_TW.eucTW' to 'zh_TW.big5' +# updated 'zh_tw' -> 'zh_TW.eucTW' to 'zh_TW.big5' +# +# MAL 2008-05-30: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.5 +# and older): +# +# updated 'cs_cs.iso88592' -> 'cs_CZ.ISO8859-2' to 'cs_CS.ISO8859-2' +# updated 'serbocroatian' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh_hr.iso88592' -> 'sh_HR.ISO8859-2' to 'hr_HR.ISO8859-2' +# updated 'sh_sp' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh_yu' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sp' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sp_yu' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_sp' -> 'sr_SP.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sr_yu' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.cp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' +# updated 'sr_yu.iso88592' -> 'sr_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sr_yu.iso88595' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.iso88595@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.microsoftcp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' +# updated 'sr_yu.utf8@cyrillic' -> 'sr_YU.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_yu@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# +# AP 2010-04-12: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.6.5 +# and older): +# +# updated 'ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' +# updated 'ru_ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' +# updated 'serbocroatian' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sh' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sh_yu' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# updated 'sr@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# updated 'sr@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr_cs.utf8@latn' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr_yu' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8@latin' +# updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8' +# updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# +# SS 2013-12-20: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 3.3.3 +# and older): +# +# updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8' +# updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# +# SS 2014-10-01: +# Updated alias mapping with glibc 2.19 supported locales. +# +# SS 2018-05-05: +# Updated alias mapping with glibc 2.27 supported locales. +# +# These are the differences compared to the old mapping (Python 3.6.5 +# and older): +# +# updated 'ca_es@valencia' -> 'ca_ES.ISO8859-15@valencia' to 'ca_ES.UTF-8@valencia' +# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' +# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' + +locale_alias = { + 'a3': 'az_AZ.KOI8-C', + 'a3_az': 'az_AZ.KOI8-C', + 'a3_az.koic': 'az_AZ.KOI8-C', + 'aa_dj': 'aa_DJ.ISO8859-1', + 'aa_er': 'aa_ER.UTF-8', + 'aa_et': 'aa_ET.UTF-8', + 'af': 'af_ZA.ISO8859-1', + 'af_za': 'af_ZA.ISO8859-1', + 'agr_pe': 'agr_PE.UTF-8', + 'ak_gh': 'ak_GH.UTF-8', + 'am': 'am_ET.UTF-8', + 'am_et': 'am_ET.UTF-8', + 'american': 'en_US.ISO8859-1', + 'an_es': 'an_ES.ISO8859-15', + 'anp_in': 'anp_IN.UTF-8', + 'ar': 'ar_AA.ISO8859-6', + 'ar_aa': 'ar_AA.ISO8859-6', + 'ar_ae': 'ar_AE.ISO8859-6', + 'ar_bh': 'ar_BH.ISO8859-6', + 'ar_dz': 'ar_DZ.ISO8859-6', + 'ar_eg': 'ar_EG.ISO8859-6', + 'ar_in': 'ar_IN.UTF-8', + 'ar_iq': 'ar_IQ.ISO8859-6', + 'ar_jo': 'ar_JO.ISO8859-6', + 'ar_kw': 'ar_KW.ISO8859-6', + 'ar_lb': 'ar_LB.ISO8859-6', + 'ar_ly': 'ar_LY.ISO8859-6', + 'ar_ma': 'ar_MA.ISO8859-6', + 'ar_om': 'ar_OM.ISO8859-6', + 'ar_qa': 'ar_QA.ISO8859-6', + 'ar_sa': 'ar_SA.ISO8859-6', + 'ar_sd': 'ar_SD.ISO8859-6', + 'ar_ss': 'ar_SS.UTF-8', + 'ar_sy': 'ar_SY.ISO8859-6', + 'ar_tn': 'ar_TN.ISO8859-6', + 'ar_ye': 'ar_YE.ISO8859-6', + 'arabic': 'ar_AA.ISO8859-6', + 'as': 'as_IN.UTF-8', + 'as_in': 'as_IN.UTF-8', + 'ast_es': 'ast_ES.ISO8859-15', + 'ayc_pe': 'ayc_PE.UTF-8', + 'az': 'az_AZ.ISO8859-9E', + 'az_az': 'az_AZ.ISO8859-9E', + 'az_az.iso88599e': 'az_AZ.ISO8859-9E', + 'az_ir': 'az_IR.UTF-8', + 'be': 'be_BY.CP1251', + 'be@latin': 'be_BY.UTF-8@latin', + 'be_bg.utf8': 'bg_BG.UTF-8', + 'be_by': 'be_BY.CP1251', + 'be_by@latin': 'be_BY.UTF-8@latin', + 'bem_zm': 'bem_ZM.UTF-8', + 'ber_dz': 'ber_DZ.UTF-8', + 'ber_ma': 'ber_MA.UTF-8', + 'bg': 'bg_BG.CP1251', + 'bg_bg': 'bg_BG.CP1251', + 'bhb_in.utf8': 'bhb_IN.UTF-8', + 'bho_in': 'bho_IN.UTF-8', + 'bho_np': 'bho_NP.UTF-8', + 'bi_vu': 'bi_VU.UTF-8', + 'bn_bd': 'bn_BD.UTF-8', + 'bn_in': 'bn_IN.UTF-8', + 'bo_cn': 'bo_CN.UTF-8', + 'bo_in': 'bo_IN.UTF-8', + 'bokmal': 'nb_NO.ISO8859-1', + 'bokm\xe5l': 'nb_NO.ISO8859-1', + 'br': 'br_FR.ISO8859-1', + 'br_fr': 'br_FR.ISO8859-1', + 'brx_in': 'brx_IN.UTF-8', + 'bs': 'bs_BA.ISO8859-2', + 'bs_ba': 'bs_BA.ISO8859-2', + 'bulgarian': 'bg_BG.CP1251', + 'byn_er': 'byn_ER.UTF-8', + 'c': 'C', + 'c-french': 'fr_CA.ISO8859-1', + 'c.ascii': 'C', + 'c.en': 'C', + 'c.iso88591': 'en_US.ISO8859-1', + 'c.utf8': 'en_US.UTF-8', + 'c_c': 'C', + 'c_c.c': 'C', + 'ca': 'ca_ES.ISO8859-1', + 'ca_ad': 'ca_AD.ISO8859-1', + 'ca_es': 'ca_ES.ISO8859-1', + 'ca_es@valencia': 'ca_ES.UTF-8@valencia', + 'ca_fr': 'ca_FR.ISO8859-1', + 'ca_it': 'ca_IT.ISO8859-1', + 'catalan': 'ca_ES.ISO8859-1', + 'ce_ru': 'ce_RU.UTF-8', + 'cextend': 'en_US.ISO8859-1', + 'chinese-s': 'zh_CN.eucCN', + 'chinese-t': 'zh_TW.eucTW', + 'chr_us': 'chr_US.UTF-8', + 'ckb_iq': 'ckb_IQ.UTF-8', + 'cmn_tw': 'cmn_TW.UTF-8', + 'crh_ua': 'crh_UA.UTF-8', + 'croatian': 'hr_HR.ISO8859-2', + 'cs': 'cs_CZ.ISO8859-2', + 'cs_cs': 'cs_CZ.ISO8859-2', + 'cs_cz': 'cs_CZ.ISO8859-2', + 'csb_pl': 'csb_PL.UTF-8', + 'cv_ru': 'cv_RU.UTF-8', + 'cy': 'cy_GB.ISO8859-1', + 'cy_gb': 'cy_GB.ISO8859-1', + 'cz': 'cs_CZ.ISO8859-2', + 'cz_cz': 'cs_CZ.ISO8859-2', + 'czech': 'cs_CZ.ISO8859-2', + 'da': 'da_DK.ISO8859-1', + 'da_dk': 'da_DK.ISO8859-1', + 'danish': 'da_DK.ISO8859-1', + 'dansk': 'da_DK.ISO8859-1', + 'de': 'de_DE.ISO8859-1', + 'de_at': 'de_AT.ISO8859-1', + 'de_be': 'de_BE.ISO8859-1', + 'de_ch': 'de_CH.ISO8859-1', + 'de_de': 'de_DE.ISO8859-1', + 'de_it': 'de_IT.ISO8859-1', + 'de_li.utf8': 'de_LI.UTF-8', + 'de_lu': 'de_LU.ISO8859-1', + 'deutsch': 'de_DE.ISO8859-1', + 'doi_in': 'doi_IN.UTF-8', + 'dutch': 'nl_NL.ISO8859-1', + 'dutch.iso88591': 'nl_BE.ISO8859-1', + 'dv_mv': 'dv_MV.UTF-8', + 'dz_bt': 'dz_BT.UTF-8', + 'ee': 'ee_EE.ISO8859-4', + 'ee_ee': 'ee_EE.ISO8859-4', + 'eesti': 'et_EE.ISO8859-1', + 'el': 'el_GR.ISO8859-7', + 'el_cy': 'el_CY.ISO8859-7', + 'el_gr': 'el_GR.ISO8859-7', + 'el_gr@euro': 'el_GR.ISO8859-15', + 'en': 'en_US.ISO8859-1', + 'en_ag': 'en_AG.UTF-8', + 'en_au': 'en_AU.ISO8859-1', + 'en_be': 'en_BE.ISO8859-1', + 'en_bw': 'en_BW.ISO8859-1', + 'en_ca': 'en_CA.ISO8859-1', + 'en_dk': 'en_DK.ISO8859-1', + 'en_dl.utf8': 'en_DL.UTF-8', + 'en_gb': 'en_GB.ISO8859-1', + 'en_hk': 'en_HK.ISO8859-1', + 'en_ie': 'en_IE.ISO8859-1', + 'en_il': 'en_IL.UTF-8', + 'en_in': 'en_IN.ISO8859-1', + 'en_ng': 'en_NG.UTF-8', + 'en_nz': 'en_NZ.ISO8859-1', + 'en_ph': 'en_PH.ISO8859-1', + 'en_sc.utf8': 'en_SC.UTF-8', + 'en_sg': 'en_SG.ISO8859-1', + 'en_uk': 'en_GB.ISO8859-1', + 'en_us': 'en_US.ISO8859-1', + 'en_us@euro@euro': 'en_US.ISO8859-15', + 'en_za': 'en_ZA.ISO8859-1', + 'en_zm': 'en_ZM.UTF-8', + 'en_zw': 'en_ZW.ISO8859-1', + 'en_zw.utf8': 'en_ZS.UTF-8', + 'eng_gb': 'en_GB.ISO8859-1', + 'english': 'en_EN.ISO8859-1', + 'english.iso88591': 'en_US.ISO8859-1', + 'english_uk': 'en_GB.ISO8859-1', + 'english_united-states': 'en_US.ISO8859-1', + 'english_united-states.437': 'C', + 'english_us': 'en_US.ISO8859-1', + 'eo': 'eo_XX.ISO8859-3', + 'eo.utf8': 'eo.UTF-8', + 'eo_eo': 'eo_EO.ISO8859-3', + 'eo_us.utf8': 'eo_US.UTF-8', + 'eo_xx': 'eo_XX.ISO8859-3', + 'es': 'es_ES.ISO8859-1', + 'es_ar': 'es_AR.ISO8859-1', + 'es_bo': 'es_BO.ISO8859-1', + 'es_cl': 'es_CL.ISO8859-1', + 'es_co': 'es_CO.ISO8859-1', + 'es_cr': 'es_CR.ISO8859-1', + 'es_cu': 'es_CU.UTF-8', + 'es_do': 'es_DO.ISO8859-1', + 'es_ec': 'es_EC.ISO8859-1', + 'es_es': 'es_ES.ISO8859-1', + 'es_gt': 'es_GT.ISO8859-1', + 'es_hn': 'es_HN.ISO8859-1', + 'es_mx': 'es_MX.ISO8859-1', + 'es_ni': 'es_NI.ISO8859-1', + 'es_pa': 'es_PA.ISO8859-1', + 'es_pe': 'es_PE.ISO8859-1', + 'es_pr': 'es_PR.ISO8859-1', + 'es_py': 'es_PY.ISO8859-1', + 'es_sv': 'es_SV.ISO8859-1', + 'es_us': 'es_US.ISO8859-1', + 'es_uy': 'es_UY.ISO8859-1', + 'es_ve': 'es_VE.ISO8859-1', + 'estonian': 'et_EE.ISO8859-1', + 'et': 'et_EE.ISO8859-15', + 'et_ee': 'et_EE.ISO8859-15', + 'eu': 'eu_ES.ISO8859-1', + 'eu_es': 'eu_ES.ISO8859-1', + 'eu_fr': 'eu_FR.ISO8859-1', + 'fa': 'fa_IR.UTF-8', + 'fa_ir': 'fa_IR.UTF-8', + 'fa_ir.isiri3342': 'fa_IR.ISIRI-3342', + 'ff_sn': 'ff_SN.UTF-8', + 'fi': 'fi_FI.ISO8859-15', + 'fi_fi': 'fi_FI.ISO8859-15', + 'fil_ph': 'fil_PH.UTF-8', + 'finnish': 'fi_FI.ISO8859-1', + 'fo': 'fo_FO.ISO8859-1', + 'fo_fo': 'fo_FO.ISO8859-1', + 'fr': 'fr_FR.ISO8859-1', + 'fr_be': 'fr_BE.ISO8859-1', + 'fr_ca': 'fr_CA.ISO8859-1', + 'fr_ch': 'fr_CH.ISO8859-1', + 'fr_fr': 'fr_FR.ISO8859-1', + 'fr_lu': 'fr_LU.ISO8859-1', + 'fran\xe7ais': 'fr_FR.ISO8859-1', + 'fre_fr': 'fr_FR.ISO8859-1', + 'french': 'fr_FR.ISO8859-1', + 'french.iso88591': 'fr_CH.ISO8859-1', + 'french_france': 'fr_FR.ISO8859-1', + 'fur_it': 'fur_IT.UTF-8', + 'fy_de': 'fy_DE.UTF-8', + 'fy_nl': 'fy_NL.UTF-8', + 'ga': 'ga_IE.ISO8859-1', + 'ga_ie': 'ga_IE.ISO8859-1', + 'galego': 'gl_ES.ISO8859-1', + 'galician': 'gl_ES.ISO8859-1', + 'gd': 'gd_GB.ISO8859-1', + 'gd_gb': 'gd_GB.ISO8859-1', + 'ger_de': 'de_DE.ISO8859-1', + 'german': 'de_DE.ISO8859-1', + 'german.iso88591': 'de_CH.ISO8859-1', + 'german_germany': 'de_DE.ISO8859-1', + 'gez_er': 'gez_ER.UTF-8', + 'gez_et': 'gez_ET.UTF-8', + 'gl': 'gl_ES.ISO8859-1', + 'gl_es': 'gl_ES.ISO8859-1', + 'greek': 'el_GR.ISO8859-7', + 'gu_in': 'gu_IN.UTF-8', + 'gv': 'gv_GB.ISO8859-1', + 'gv_gb': 'gv_GB.ISO8859-1', + 'ha_ng': 'ha_NG.UTF-8', + 'hak_tw': 'hak_TW.UTF-8', + 'he': 'he_IL.ISO8859-8', + 'he_il': 'he_IL.ISO8859-8', + 'hebrew': 'he_IL.ISO8859-8', + 'hi': 'hi_IN.ISCII-DEV', + 'hi_in': 'hi_IN.ISCII-DEV', + 'hi_in.isciidev': 'hi_IN.ISCII-DEV', + 'hif_fj': 'hif_FJ.UTF-8', + 'hne': 'hne_IN.UTF-8', + 'hne_in': 'hne_IN.UTF-8', + 'hr': 'hr_HR.ISO8859-2', + 'hr_hr': 'hr_HR.ISO8859-2', + 'hrvatski': 'hr_HR.ISO8859-2', + 'hsb_de': 'hsb_DE.ISO8859-2', + 'ht_ht': 'ht_HT.UTF-8', + 'hu': 'hu_HU.ISO8859-2', + 'hu_hu': 'hu_HU.ISO8859-2', + 'hungarian': 'hu_HU.ISO8859-2', + 'hy_am': 'hy_AM.UTF-8', + 'hy_am.armscii8': 'hy_AM.ARMSCII_8', + 'ia': 'ia.UTF-8', + 'ia_fr': 'ia_FR.UTF-8', + 'icelandic': 'is_IS.ISO8859-1', + 'id': 'id_ID.ISO8859-1', + 'id_id': 'id_ID.ISO8859-1', + 'ig_ng': 'ig_NG.UTF-8', + 'ik_ca': 'ik_CA.UTF-8', + 'in': 'id_ID.ISO8859-1', + 'in_id': 'id_ID.ISO8859-1', + 'is': 'is_IS.ISO8859-1', + 'is_is': 'is_IS.ISO8859-1', + 'iso-8859-1': 'en_US.ISO8859-1', + 'iso-8859-15': 'en_US.ISO8859-15', + 'iso8859-1': 'en_US.ISO8859-1', + 'iso8859-15': 'en_US.ISO8859-15', + 'iso_8859_1': 'en_US.ISO8859-1', + 'iso_8859_15': 'en_US.ISO8859-15', + 'it': 'it_IT.ISO8859-1', + 'it_ch': 'it_CH.ISO8859-1', + 'it_it': 'it_IT.ISO8859-1', + 'italian': 'it_IT.ISO8859-1', + 'iu': 'iu_CA.NUNACOM-8', + 'iu_ca': 'iu_CA.NUNACOM-8', + 'iu_ca.nunacom8': 'iu_CA.NUNACOM-8', + 'iw': 'he_IL.ISO8859-8', + 'iw_il': 'he_IL.ISO8859-8', + 'iw_il.utf8': 'iw_IL.UTF-8', + 'ja': 'ja_JP.eucJP', + 'ja_jp': 'ja_JP.eucJP', + 'ja_jp.euc': 'ja_JP.eucJP', + 'ja_jp.mscode': 'ja_JP.SJIS', + 'ja_jp.pck': 'ja_JP.SJIS', + 'japan': 'ja_JP.eucJP', + 'japanese': 'ja_JP.eucJP', + 'japanese-euc': 'ja_JP.eucJP', + 'japanese.euc': 'ja_JP.eucJP', + 'jp_jp': 'ja_JP.eucJP', + 'ka': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', + 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', + 'kab_dz': 'kab_DZ.UTF-8', + 'kk_kz': 'kk_KZ.ptcp154', + 'kl': 'kl_GL.ISO8859-1', + 'kl_gl': 'kl_GL.ISO8859-1', + 'km_kh': 'km_KH.UTF-8', + 'kn': 'kn_IN.UTF-8', + 'kn_in': 'kn_IN.UTF-8', + 'ko': 'ko_KR.eucKR', + 'ko_kr': 'ko_KR.eucKR', + 'ko_kr.euc': 'ko_KR.eucKR', + 'kok_in': 'kok_IN.UTF-8', + 'korean': 'ko_KR.eucKR', + 'korean.euc': 'ko_KR.eucKR', + 'ks': 'ks_IN.UTF-8', + 'ks_in': 'ks_IN.UTF-8', + 'ks_in@devanagari.utf8': 'ks_IN.UTF-8@devanagari', + 'ku_tr': 'ku_TR.ISO8859-9', + 'kw': 'kw_GB.ISO8859-1', + 'kw_gb': 'kw_GB.ISO8859-1', + 'ky': 'ky_KG.UTF-8', + 'ky_kg': 'ky_KG.UTF-8', + 'lb_lu': 'lb_LU.UTF-8', + 'lg_ug': 'lg_UG.ISO8859-10', + 'li_be': 'li_BE.UTF-8', + 'li_nl': 'li_NL.UTF-8', + 'lij_it': 'lij_IT.UTF-8', + 'lithuanian': 'lt_LT.ISO8859-13', + 'ln_cd': 'ln_CD.UTF-8', + 'lo': 'lo_LA.MULELAO-1', + 'lo_la': 'lo_LA.MULELAO-1', + 'lo_la.cp1133': 'lo_LA.IBM-CP1133', + 'lo_la.ibmcp1133': 'lo_LA.IBM-CP1133', + 'lo_la.mulelao1': 'lo_LA.MULELAO-1', + 'lt': 'lt_LT.ISO8859-13', + 'lt_lt': 'lt_LT.ISO8859-13', + 'lv': 'lv_LV.ISO8859-13', + 'lv_lv': 'lv_LV.ISO8859-13', + 'lzh_tw': 'lzh_TW.UTF-8', + 'mag_in': 'mag_IN.UTF-8', + 'mai': 'mai_IN.UTF-8', + 'mai_in': 'mai_IN.UTF-8', + 'mai_np': 'mai_NP.UTF-8', + 'mfe_mu': 'mfe_MU.UTF-8', + 'mg_mg': 'mg_MG.ISO8859-15', + 'mhr_ru': 'mhr_RU.UTF-8', + 'mi': 'mi_NZ.ISO8859-1', + 'mi_nz': 'mi_NZ.ISO8859-1', + 'miq_ni': 'miq_NI.UTF-8', + 'mjw_in': 'mjw_IN.UTF-8', + 'mk': 'mk_MK.ISO8859-5', + 'mk_mk': 'mk_MK.ISO8859-5', + 'ml': 'ml_IN.UTF-8', + 'ml_in': 'ml_IN.UTF-8', + 'mn_mn': 'mn_MN.UTF-8', + 'mni_in': 'mni_IN.UTF-8', + 'mr': 'mr_IN.UTF-8', + 'mr_in': 'mr_IN.UTF-8', + 'ms': 'ms_MY.ISO8859-1', + 'ms_my': 'ms_MY.ISO8859-1', + 'mt': 'mt_MT.ISO8859-3', + 'mt_mt': 'mt_MT.ISO8859-3', + 'my_mm': 'my_MM.UTF-8', + 'nan_tw': 'nan_TW.UTF-8', + 'nb': 'nb_NO.ISO8859-1', + 'nb_no': 'nb_NO.ISO8859-1', + 'nds_de': 'nds_DE.UTF-8', + 'nds_nl': 'nds_NL.UTF-8', + 'ne_np': 'ne_NP.UTF-8', + 'nhn_mx': 'nhn_MX.UTF-8', + 'niu_nu': 'niu_NU.UTF-8', + 'niu_nz': 'niu_NZ.UTF-8', + 'nl': 'nl_NL.ISO8859-1', + 'nl_aw': 'nl_AW.UTF-8', + 'nl_be': 'nl_BE.ISO8859-1', + 'nl_nl': 'nl_NL.ISO8859-1', + 'nn': 'nn_NO.ISO8859-1', + 'nn_no': 'nn_NO.ISO8859-1', + 'no': 'no_NO.ISO8859-1', + 'no@nynorsk': 'ny_NO.ISO8859-1', + 'no_no': 'no_NO.ISO8859-1', + 'no_no.iso88591@bokmal': 'no_NO.ISO8859-1', + 'no_no.iso88591@nynorsk': 'no_NO.ISO8859-1', + 'norwegian': 'no_NO.ISO8859-1', + 'nr': 'nr_ZA.ISO8859-1', + 'nr_za': 'nr_ZA.ISO8859-1', + 'nso': 'nso_ZA.ISO8859-15', + 'nso_za': 'nso_ZA.ISO8859-15', + 'ny': 'ny_NO.ISO8859-1', + 'ny_no': 'ny_NO.ISO8859-1', + 'nynorsk': 'nn_NO.ISO8859-1', + 'oc': 'oc_FR.ISO8859-1', + 'oc_fr': 'oc_FR.ISO8859-1', + 'om_et': 'om_ET.UTF-8', + 'om_ke': 'om_KE.ISO8859-1', + 'or': 'or_IN.UTF-8', + 'or_in': 'or_IN.UTF-8', + 'os_ru': 'os_RU.UTF-8', + 'pa': 'pa_IN.UTF-8', + 'pa_in': 'pa_IN.UTF-8', + 'pa_pk': 'pa_PK.UTF-8', + 'pap_an': 'pap_AN.UTF-8', + 'pap_aw': 'pap_AW.UTF-8', + 'pap_cw': 'pap_CW.UTF-8', + 'pd': 'pd_US.ISO8859-1', + 'pd_de': 'pd_DE.ISO8859-1', + 'pd_us': 'pd_US.ISO8859-1', + 'ph': 'ph_PH.ISO8859-1', + 'ph_ph': 'ph_PH.ISO8859-1', + 'pl': 'pl_PL.ISO8859-2', + 'pl_pl': 'pl_PL.ISO8859-2', + 'polish': 'pl_PL.ISO8859-2', + 'portuguese': 'pt_PT.ISO8859-1', + 'portuguese_brazil': 'pt_BR.ISO8859-1', + 'posix': 'C', + 'posix-utf2': 'C', + 'pp': 'pp_AN.ISO8859-1', + 'pp_an': 'pp_AN.ISO8859-1', + 'ps_af': 'ps_AF.UTF-8', + 'pt': 'pt_PT.ISO8859-1', + 'pt_br': 'pt_BR.ISO8859-1', + 'pt_pt': 'pt_PT.ISO8859-1', + 'quz_pe': 'quz_PE.UTF-8', + 'raj_in': 'raj_IN.UTF-8', + 'ro': 'ro_RO.ISO8859-2', + 'ro_ro': 'ro_RO.ISO8859-2', + 'romanian': 'ro_RO.ISO8859-2', + 'ru': 'ru_RU.UTF-8', + 'ru_ru': 'ru_RU.UTF-8', + 'ru_ua': 'ru_UA.KOI8-U', + 'rumanian': 'ro_RO.ISO8859-2', + 'russian': 'ru_RU.KOI8-R', + 'rw': 'rw_RW.ISO8859-1', + 'rw_rw': 'rw_RW.ISO8859-1', + 'sa_in': 'sa_IN.UTF-8', + 'sat_in': 'sat_IN.UTF-8', + 'sc_it': 'sc_IT.UTF-8', + 'sd': 'sd_IN.UTF-8', + 'sd_in': 'sd_IN.UTF-8', + 'sd_in@devanagari.utf8': 'sd_IN.UTF-8@devanagari', + 'sd_pk': 'sd_PK.UTF-8', + 'se_no': 'se_NO.UTF-8', + 'serbocroatian': 'sr_RS.UTF-8@latin', + 'sgs_lt': 'sgs_LT.UTF-8', + 'sh': 'sr_RS.UTF-8@latin', + 'sh_ba.iso88592@bosnia': 'sr_CS.ISO8859-2', + 'sh_hr': 'sh_HR.ISO8859-2', + 'sh_hr.iso88592': 'hr_HR.ISO8859-2', + 'sh_sp': 'sr_CS.ISO8859-2', + 'sh_yu': 'sr_RS.UTF-8@latin', + 'shn_mm': 'shn_MM.UTF-8', + 'shs_ca': 'shs_CA.UTF-8', + 'si': 'si_LK.UTF-8', + 'si_lk': 'si_LK.UTF-8', + 'sid_et': 'sid_ET.UTF-8', + 'sinhala': 'si_LK.UTF-8', + 'sk': 'sk_SK.ISO8859-2', + 'sk_sk': 'sk_SK.ISO8859-2', + 'sl': 'sl_SI.ISO8859-2', + 'sl_cs': 'sl_CS.ISO8859-2', + 'sl_si': 'sl_SI.ISO8859-2', + 'slovak': 'sk_SK.ISO8859-2', + 'slovene': 'sl_SI.ISO8859-2', + 'slovenian': 'sl_SI.ISO8859-2', + 'sm_ws': 'sm_WS.UTF-8', + 'so_dj': 'so_DJ.ISO8859-1', + 'so_et': 'so_ET.UTF-8', + 'so_ke': 'so_KE.ISO8859-1', + 'so_so': 'so_SO.ISO8859-1', + 'sp': 'sr_CS.ISO8859-5', + 'sp_yu': 'sr_CS.ISO8859-5', + 'spanish': 'es_ES.ISO8859-1', + 'spanish_spain': 'es_ES.ISO8859-1', + 'sq': 'sq_AL.ISO8859-2', + 'sq_al': 'sq_AL.ISO8859-2', + 'sq_mk': 'sq_MK.UTF-8', + 'sr': 'sr_RS.UTF-8', + 'sr@cyrillic': 'sr_RS.UTF-8', + 'sr@latn': 'sr_CS.UTF-8@latin', + 'sr_cs': 'sr_CS.UTF-8', + 'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2', + 'sr_cs@latn': 'sr_CS.UTF-8@latin', + 'sr_me': 'sr_ME.UTF-8', + 'sr_rs': 'sr_RS.UTF-8', + 'sr_rs@latn': 'sr_RS.UTF-8@latin', + 'sr_sp': 'sr_CS.ISO8859-2', + 'sr_yu': 'sr_RS.UTF-8@latin', + 'sr_yu.cp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.iso88592': 'sr_CS.ISO8859-2', + 'sr_yu.iso88595': 'sr_CS.ISO8859-5', + 'sr_yu.iso88595@cyrillic': 'sr_CS.ISO8859-5', + 'sr_yu.microsoftcp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.utf8': 'sr_RS.UTF-8', + 'sr_yu.utf8@cyrillic': 'sr_RS.UTF-8', + 'sr_yu@cyrillic': 'sr_RS.UTF-8', + 'ss': 'ss_ZA.ISO8859-1', + 'ss_za': 'ss_ZA.ISO8859-1', + 'st': 'st_ZA.ISO8859-1', + 'st_za': 'st_ZA.ISO8859-1', + 'sv': 'sv_SE.ISO8859-1', + 'sv_fi': 'sv_FI.ISO8859-1', + 'sv_se': 'sv_SE.ISO8859-1', + 'sw_ke': 'sw_KE.UTF-8', + 'sw_tz': 'sw_TZ.UTF-8', + 'swedish': 'sv_SE.ISO8859-1', + 'szl_pl': 'szl_PL.UTF-8', + 'ta': 'ta_IN.TSCII-0', + 'ta_in': 'ta_IN.TSCII-0', + 'ta_in.tscii': 'ta_IN.TSCII-0', + 'ta_in.tscii0': 'ta_IN.TSCII-0', + 'ta_lk': 'ta_LK.UTF-8', + 'tcy_in.utf8': 'tcy_IN.UTF-8', + 'te': 'te_IN.UTF-8', + 'te_in': 'te_IN.UTF-8', + 'tg': 'tg_TJ.KOI8-C', + 'tg_tj': 'tg_TJ.KOI8-C', + 'th': 'th_TH.ISO8859-11', + 'th_th': 'th_TH.ISO8859-11', + 'th_th.tactis': 'th_TH.TIS620', + 'th_th.tis620': 'th_TH.TIS620', + 'thai': 'th_TH.ISO8859-11', + 'the_np': 'the_NP.UTF-8', + 'ti_er': 'ti_ER.UTF-8', + 'ti_et': 'ti_ET.UTF-8', + 'tig_er': 'tig_ER.UTF-8', + 'tk_tm': 'tk_TM.UTF-8', + 'tl': 'tl_PH.ISO8859-1', + 'tl_ph': 'tl_PH.ISO8859-1', + 'tn': 'tn_ZA.ISO8859-15', + 'tn_za': 'tn_ZA.ISO8859-15', + 'to_to': 'to_TO.UTF-8', + 'tpi_pg': 'tpi_PG.UTF-8', + 'tr': 'tr_TR.ISO8859-9', + 'tr_cy': 'tr_CY.ISO8859-9', + 'tr_tr': 'tr_TR.ISO8859-9', + 'ts': 'ts_ZA.ISO8859-1', + 'ts_za': 'ts_ZA.ISO8859-1', + 'tt': 'tt_RU.TATAR-CYR', + 'tt_ru': 'tt_RU.TATAR-CYR', + 'tt_ru.tatarcyr': 'tt_RU.TATAR-CYR', + 'tt_ru@iqtelif': 'tt_RU.UTF-8@iqtelif', + 'turkish': 'tr_TR.ISO8859-9', + 'ug_cn': 'ug_CN.UTF-8', + 'uk': 'uk_UA.KOI8-U', + 'uk_ua': 'uk_UA.KOI8-U', + 'univ': 'en_US.utf', + 'universal': 'en_US.utf', + 'universal.utf8@ucs4': 'en_US.UTF-8', + 'unm_us': 'unm_US.UTF-8', + 'ur': 'ur_PK.CP1256', + 'ur_in': 'ur_IN.UTF-8', + 'ur_pk': 'ur_PK.CP1256', + 'uz': 'uz_UZ.UTF-8', + 'uz_uz': 'uz_UZ.UTF-8', + 'uz_uz@cyrillic': 'uz_UZ.UTF-8', + 've': 've_ZA.UTF-8', + 've_za': 've_ZA.UTF-8', + 'vi': 'vi_VN.TCVN', + 'vi_vn': 'vi_VN.TCVN', + 'vi_vn.tcvn': 'vi_VN.TCVN', + 'vi_vn.tcvn5712': 'vi_VN.TCVN', + 'vi_vn.viscii': 'vi_VN.VISCII', + 'vi_vn.viscii111': 'vi_VN.VISCII', + 'wa': 'wa_BE.ISO8859-1', + 'wa_be': 'wa_BE.ISO8859-1', + 'wae_ch': 'wae_CH.UTF-8', + 'wal_et': 'wal_ET.UTF-8', + 'wo_sn': 'wo_SN.UTF-8', + 'xh': 'xh_ZA.ISO8859-1', + 'xh_za': 'xh_ZA.ISO8859-1', + 'yi': 'yi_US.CP1255', + 'yi_us': 'yi_US.CP1255', + 'yo_ng': 'yo_NG.UTF-8', + 'yue_hk': 'yue_HK.UTF-8', + 'yuw_pg': 'yuw_PG.UTF-8', + 'zh': 'zh_CN.eucCN', + 'zh_cn': 'zh_CN.gb2312', + 'zh_cn.big5': 'zh_TW.big5', + 'zh_cn.euc': 'zh_CN.eucCN', + 'zh_hk': 'zh_HK.big5hkscs', + 'zh_hk.big5hk': 'zh_HK.big5hkscs', + 'zh_sg': 'zh_SG.GB2312', + 'zh_sg.gbk': 'zh_SG.GBK', + 'zh_tw': 'zh_TW.big5', + 'zh_tw.euc': 'zh_TW.eucTW', + 'zh_tw.euctw': 'zh_TW.eucTW', + 'zu': 'zu_ZA.ISO8859-1', + 'zu_za': 'zu_ZA.ISO8859-1', +} + +# +# This maps Windows language identifiers to locale strings. +# +# This list has been updated from +# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_238z.asp +# to include every locale up to Windows Vista. +# +# NOTE: this mapping is incomplete. If your language is missing, please +# submit a bug report to the Python bug tracker at http://bugs.python.org/ +# Make sure you include the missing language identifier and the suggested +# locale code. +# + +windows_locale = { + 0x0436: "af_ZA", # Afrikaans + 0x041c: "sq_AL", # Albanian + 0x0484: "gsw_FR",# Alsatian - France + 0x045e: "am_ET", # Amharic - Ethiopia + 0x0401: "ar_SA", # Arabic - Saudi Arabia + 0x0801: "ar_IQ", # Arabic - Iraq + 0x0c01: "ar_EG", # Arabic - Egypt + 0x1001: "ar_LY", # Arabic - Libya + 0x1401: "ar_DZ", # Arabic - Algeria + 0x1801: "ar_MA", # Arabic - Morocco + 0x1c01: "ar_TN", # Arabic - Tunisia + 0x2001: "ar_OM", # Arabic - Oman + 0x2401: "ar_YE", # Arabic - Yemen + 0x2801: "ar_SY", # Arabic - Syria + 0x2c01: "ar_JO", # Arabic - Jordan + 0x3001: "ar_LB", # Arabic - Lebanon + 0x3401: "ar_KW", # Arabic - Kuwait + 0x3801: "ar_AE", # Arabic - United Arab Emirates + 0x3c01: "ar_BH", # Arabic - Bahrain + 0x4001: "ar_QA", # Arabic - Qatar + 0x042b: "hy_AM", # Armenian + 0x044d: "as_IN", # Assamese - India + 0x042c: "az_AZ", # Azeri - Latin + 0x082c: "az_AZ", # Azeri - Cyrillic + 0x046d: "ba_RU", # Bashkir + 0x042d: "eu_ES", # Basque - Russia + 0x0423: "be_BY", # Belarusian + 0x0445: "bn_IN", # Begali + 0x201a: "bs_BA", # Bosnian - Cyrillic + 0x141a: "bs_BA", # Bosnian - Latin + 0x047e: "br_FR", # Breton - France + 0x0402: "bg_BG", # Bulgarian +# 0x0455: "my_MM", # Burmese - Not supported + 0x0403: "ca_ES", # Catalan + 0x0004: "zh_CHS",# Chinese - Simplified + 0x0404: "zh_TW", # Chinese - Taiwan + 0x0804: "zh_CN", # Chinese - PRC + 0x0c04: "zh_HK", # Chinese - Hong Kong S.A.R. + 0x1004: "zh_SG", # Chinese - Singapore + 0x1404: "zh_MO", # Chinese - Macao S.A.R. + 0x7c04: "zh_CHT",# Chinese - Traditional + 0x0483: "co_FR", # Corsican - France + 0x041a: "hr_HR", # Croatian + 0x101a: "hr_BA", # Croatian - Bosnia + 0x0405: "cs_CZ", # Czech + 0x0406: "da_DK", # Danish + 0x048c: "gbz_AF",# Dari - Afghanistan + 0x0465: "div_MV",# Divehi - Maldives + 0x0413: "nl_NL", # Dutch - The Netherlands + 0x0813: "nl_BE", # Dutch - Belgium + 0x0409: "en_US", # English - United States + 0x0809: "en_GB", # English - United Kingdom + 0x0c09: "en_AU", # English - Australia + 0x1009: "en_CA", # English - Canada + 0x1409: "en_NZ", # English - New Zealand + 0x1809: "en_IE", # English - Ireland + 0x1c09: "en_ZA", # English - South Africa + 0x2009: "en_JA", # English - Jamaica + 0x2409: "en_CB", # English - Caribbean + 0x2809: "en_BZ", # English - Belize + 0x2c09: "en_TT", # English - Trinidad + 0x3009: "en_ZW", # English - Zimbabwe + 0x3409: "en_PH", # English - Philippines + 0x4009: "en_IN", # English - India + 0x4409: "en_MY", # English - Malaysia + 0x4809: "en_IN", # English - Singapore + 0x0425: "et_EE", # Estonian + 0x0438: "fo_FO", # Faroese + 0x0464: "fil_PH",# Filipino + 0x040b: "fi_FI", # Finnish + 0x040c: "fr_FR", # French - France + 0x080c: "fr_BE", # French - Belgium + 0x0c0c: "fr_CA", # French - Canada + 0x100c: "fr_CH", # French - Switzerland + 0x140c: "fr_LU", # French - Luxembourg + 0x180c: "fr_MC", # French - Monaco + 0x0462: "fy_NL", # Frisian - Netherlands + 0x0456: "gl_ES", # Galician + 0x0437: "ka_GE", # Georgian + 0x0407: "de_DE", # German - Germany + 0x0807: "de_CH", # German - Switzerland + 0x0c07: "de_AT", # German - Austria + 0x1007: "de_LU", # German - Luxembourg + 0x1407: "de_LI", # German - Liechtenstein + 0x0408: "el_GR", # Greek + 0x046f: "kl_GL", # Greenlandic - Greenland + 0x0447: "gu_IN", # Gujarati + 0x0468: "ha_NG", # Hausa - Latin + 0x040d: "he_IL", # Hebrew + 0x0439: "hi_IN", # Hindi + 0x040e: "hu_HU", # Hungarian + 0x040f: "is_IS", # Icelandic + 0x0421: "id_ID", # Indonesian + 0x045d: "iu_CA", # Inuktitut - Syllabics + 0x085d: "iu_CA", # Inuktitut - Latin + 0x083c: "ga_IE", # Irish - Ireland + 0x0410: "it_IT", # Italian - Italy + 0x0810: "it_CH", # Italian - Switzerland + 0x0411: "ja_JP", # Japanese + 0x044b: "kn_IN", # Kannada - India + 0x043f: "kk_KZ", # Kazakh + 0x0453: "kh_KH", # Khmer - Cambodia + 0x0486: "qut_GT",# K'iche - Guatemala + 0x0487: "rw_RW", # Kinyarwanda - Rwanda + 0x0457: "kok_IN",# Konkani + 0x0412: "ko_KR", # Korean + 0x0440: "ky_KG", # Kyrgyz + 0x0454: "lo_LA", # Lao - Lao PDR + 0x0426: "lv_LV", # Latvian + 0x0427: "lt_LT", # Lithuanian + 0x082e: "dsb_DE",# Lower Sorbian - Germany + 0x046e: "lb_LU", # Luxembourgish + 0x042f: "mk_MK", # FYROM Macedonian + 0x043e: "ms_MY", # Malay - Malaysia + 0x083e: "ms_BN", # Malay - Brunei Darussalam + 0x044c: "ml_IN", # Malayalam - India + 0x043a: "mt_MT", # Maltese + 0x0481: "mi_NZ", # Maori + 0x047a: "arn_CL",# Mapudungun + 0x044e: "mr_IN", # Marathi + 0x047c: "moh_CA",# Mohawk - Canada + 0x0450: "mn_MN", # Mongolian - Cyrillic + 0x0850: "mn_CN", # Mongolian - PRC + 0x0461: "ne_NP", # Nepali + 0x0414: "nb_NO", # Norwegian - Bokmal + 0x0814: "nn_NO", # Norwegian - Nynorsk + 0x0482: "oc_FR", # Occitan - France + 0x0448: "or_IN", # Oriya - India + 0x0463: "ps_AF", # Pashto - Afghanistan + 0x0429: "fa_IR", # Persian + 0x0415: "pl_PL", # Polish + 0x0416: "pt_BR", # Portuguese - Brazil + 0x0816: "pt_PT", # Portuguese - Portugal + 0x0446: "pa_IN", # Punjabi + 0x046b: "quz_BO",# Quechua (Bolivia) + 0x086b: "quz_EC",# Quechua (Ecuador) + 0x0c6b: "quz_PE",# Quechua (Peru) + 0x0418: "ro_RO", # Romanian - Romania + 0x0417: "rm_CH", # Romansh + 0x0419: "ru_RU", # Russian + 0x243b: "smn_FI",# Sami Finland + 0x103b: "smj_NO",# Sami Norway + 0x143b: "smj_SE",# Sami Sweden + 0x043b: "se_NO", # Sami Northern Norway + 0x083b: "se_SE", # Sami Northern Sweden + 0x0c3b: "se_FI", # Sami Northern Finland + 0x203b: "sms_FI",# Sami Skolt + 0x183b: "sma_NO",# Sami Southern Norway + 0x1c3b: "sma_SE",# Sami Southern Sweden + 0x044f: "sa_IN", # Sanskrit + 0x0c1a: "sr_SP", # Serbian - Cyrillic + 0x1c1a: "sr_BA", # Serbian - Bosnia Cyrillic + 0x081a: "sr_SP", # Serbian - Latin + 0x181a: "sr_BA", # Serbian - Bosnia Latin + 0x045b: "si_LK", # Sinhala - Sri Lanka + 0x046c: "ns_ZA", # Northern Sotho + 0x0432: "tn_ZA", # Setswana - Southern Africa + 0x041b: "sk_SK", # Slovak + 0x0424: "sl_SI", # Slovenian + 0x040a: "es_ES", # Spanish - Spain + 0x080a: "es_MX", # Spanish - Mexico + 0x0c0a: "es_ES", # Spanish - Spain (Modern) + 0x100a: "es_GT", # Spanish - Guatemala + 0x140a: "es_CR", # Spanish - Costa Rica + 0x180a: "es_PA", # Spanish - Panama + 0x1c0a: "es_DO", # Spanish - Dominican Republic + 0x200a: "es_VE", # Spanish - Venezuela + 0x240a: "es_CO", # Spanish - Colombia + 0x280a: "es_PE", # Spanish - Peru + 0x2c0a: "es_AR", # Spanish - Argentina + 0x300a: "es_EC", # Spanish - Ecuador + 0x340a: "es_CL", # Spanish - Chile + 0x380a: "es_UR", # Spanish - Uruguay + 0x3c0a: "es_PY", # Spanish - Paraguay + 0x400a: "es_BO", # Spanish - Bolivia + 0x440a: "es_SV", # Spanish - El Salvador + 0x480a: "es_HN", # Spanish - Honduras + 0x4c0a: "es_NI", # Spanish - Nicaragua + 0x500a: "es_PR", # Spanish - Puerto Rico + 0x540a: "es_US", # Spanish - United States +# 0x0430: "", # Sutu - Not supported + 0x0441: "sw_KE", # Swahili + 0x041d: "sv_SE", # Swedish - Sweden + 0x081d: "sv_FI", # Swedish - Finland + 0x045a: "syr_SY",# Syriac + 0x0428: "tg_TJ", # Tajik - Cyrillic + 0x085f: "tmz_DZ",# Tamazight - Latin + 0x0449: "ta_IN", # Tamil + 0x0444: "tt_RU", # Tatar + 0x044a: "te_IN", # Telugu + 0x041e: "th_TH", # Thai + 0x0851: "bo_BT", # Tibetan - Bhutan + 0x0451: "bo_CN", # Tibetan - PRC + 0x041f: "tr_TR", # Turkish + 0x0442: "tk_TM", # Turkmen - Cyrillic + 0x0480: "ug_CN", # Uighur - Arabic + 0x0422: "uk_UA", # Ukrainian + 0x042e: "wen_DE",# Upper Sorbian - Germany + 0x0420: "ur_PK", # Urdu + 0x0820: "ur_IN", # Urdu - India + 0x0443: "uz_UZ", # Uzbek - Latin + 0x0843: "uz_UZ", # Uzbek - Cyrillic + 0x042a: "vi_VN", # Vietnamese + 0x0452: "cy_GB", # Welsh + 0x0488: "wo_SN", # Wolof - Senegal + 0x0434: "xh_ZA", # Xhosa - South Africa + 0x0485: "sah_RU",# Yakut - Cyrillic + 0x0478: "ii_CN", # Yi - PRC + 0x046a: "yo_NG", # Yoruba - Nigeria + 0x0435: "zu_ZA", # Zulu +} + +def _print_locale(): + + """ Test function. + """ + categories = {} + def _init_categories(categories=categories): + for k,v in globals().items(): + if k[:3] == 'LC_': + categories[k] = v + _init_categories() + del categories['LC_ALL'] + + print('Locale defaults as determined by getdefaultlocale():') + print('-'*72) + lang, enc = getdefaultlocale() + print('Language: ', lang or '(undefined)') + print('Encoding: ', enc or '(undefined)') + print() + + print('Locale settings on startup:') + print('-'*72) + for name,category in categories.items(): + print(name, '...') + lang, enc = getlocale(category) + print(' Language: ', lang or '(undefined)') + print(' Encoding: ', enc or '(undefined)') + print() + + print() + print('Locale settings after calling resetlocale():') + print('-'*72) + resetlocale() + for name,category in categories.items(): + print(name, '...') + lang, enc = getlocale(category) + print(' Language: ', lang or '(undefined)') + print(' Encoding: ', enc or '(undefined)') + print() + + try: + setlocale(LC_ALL, "") + except: + print('NOTE:') + print('setlocale(LC_ALL, "") does not support the default locale') + print('given in the OS environment variables.') + else: + print() + print('Locale settings after calling setlocale(LC_ALL, ""):') + print('-'*72) + for name,category in categories.items(): + print(name, '...') + lang, enc = getlocale(category) + print(' Language: ', lang or '(undefined)') + print(' Encoding: ', enc or '(undefined)') + print() + +### + +try: + LC_MESSAGES +except NameError: + pass +else: + __all__.append("LC_MESSAGES") + +if __name__=='__main__': + print('Locale aliasing:') + print() + _print_locale() + print() + print('Number formatting:') + print() + _test() diff --git a/Lib/no-global-site-packages.txt b/Lib/no-global-site-packages.txt new file mode 100644 index 0000000..e69de29 diff --git a/Lib/ntpath.py b/Lib/ntpath.py new file mode 100644 index 0000000..2182ec7 --- /dev/null +++ b/Lib/ntpath.py @@ -0,0 +1,671 @@ +# Module 'ntpath' -- common operations on WinNT/Win95 pathnames +"""Common pathname manipulations, WindowsNT/95 version. + +Instead of importing this module directly, import os and refer to this +module as os.path. +""" + +# strings representing various path-related bits and pieces +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = '.' +pardir = '..' +extsep = '.' +sep = '\\' +pathsep = ';' +altsep = '/' +defpath = '.;C:\\bin' +devnull = 'nul' + +import os +import sys +import stat +import genericpath +from genericpath import * + +__all__ = ["normcase","isabs","join","splitdrive","split","splitext", + "basename","dirname","commonprefix","getsize","getmtime", + "getatime","getctime", "islink","exists","lexists","isdir","isfile", + "ismount", "expanduser","expandvars","normpath","abspath", + "curdir","pardir","sep","pathsep","defpath","altsep", + "extsep","devnull","realpath","supports_unicode_filenames","relpath", + "samefile", "sameopenfile", "samestat", "commonpath"] + +def _get_bothseps(path): + if isinstance(path, bytes): + return b'\\/' + else: + return '\\/' + +# Normalize the case of a pathname and map slashes to backslashes. +# Other normalizations (such as optimizing '../' away) are not done +# (this is done by normpath). + +def normcase(s): + """Normalize case of pathname. + + Makes all characters lowercase and all slashes into backslashes.""" + s = os.fspath(s) + try: + if isinstance(s, bytes): + return s.replace(b'/', b'\\').lower() + else: + return s.replace('/', '\\').lower() + except (TypeError, AttributeError): + if not isinstance(s, (bytes, str)): + raise TypeError("normcase() argument must be str or bytes, " + "not %r" % s.__class__.__name__) from None + raise + + +# Return whether a path is absolute. +# Trivial in Posix, harder on Windows. +# For Windows it is absolute if it starts with a slash or backslash (current +# volume), or if a pathname after the volume-letter-and-colon or UNC-resource +# starts with a slash or backslash. + +def isabs(s): + """Test whether a path is absolute""" + s = os.fspath(s) + s = splitdrive(s)[1] + return len(s) > 0 and s[0] in _get_bothseps(s) + + +# Join two (or more) paths. +def join(path, *paths): + path = os.fspath(path) + if isinstance(path, bytes): + sep = b'\\' + seps = b'\\/' + colon = b':' + else: + sep = '\\' + seps = '\\/' + colon = ':' + try: + if not paths: + path[:0] + sep #23780: Ensure compatible data type even if p is null. + result_drive, result_path = splitdrive(path) + for p in map(os.fspath, paths): + p_drive, p_path = splitdrive(p) + if p_path and p_path[0] in seps: + # Second path is absolute + if p_drive or not result_drive: + result_drive = p_drive + result_path = p_path + continue + elif p_drive and p_drive != result_drive: + if p_drive.lower() != result_drive.lower(): + # Different drives => ignore the first path entirely + result_drive = p_drive + result_path = p_path + continue + # Same drive in different case + result_drive = p_drive + # Second path is relative to the first + if result_path and result_path[-1] not in seps: + result_path = result_path + sep + result_path = result_path + p_path + ## add separator between UNC and non-absolute path + if (result_path and result_path[0] not in seps and + result_drive and result_drive[-1:] != colon): + return result_drive + sep + result_path + return result_drive + result_path + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', path, *paths) + raise + + +# Split a path in a drive specification (a drive letter followed by a +# colon) and the path specification. +# It is always true that drivespec + pathspec == p +def splitdrive(p): + """Split a pathname into drive/UNC sharepoint and relative path specifiers. + Returns a 2-tuple (drive_or_unc, path); either part may be empty. + + If you assign + result = splitdrive(p) + It is always true that: + result[0] + result[1] == p + + If the path contained a drive letter, drive_or_unc will contain everything + up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir") + + If the path contained a UNC path, the drive_or_unc will contain the host name + and share up to but not including the fourth directory separator character. + e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir") + + Paths cannot contain both a drive letter and a UNC path. + + """ + p = os.fspath(p) + if len(p) >= 2: + if isinstance(p, bytes): + sep = b'\\' + altsep = b'/' + colon = b':' + else: + sep = '\\' + altsep = '/' + colon = ':' + normp = p.replace(altsep, sep) + if (normp[0:2] == sep*2) and (normp[2:3] != sep): + # is a UNC path: + # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path + # \\machine\mountpoint\directory\etc\... + # directory ^^^^^^^^^^^^^^^ + index = normp.find(sep, 2) + if index == -1: + return p[:0], p + index2 = normp.find(sep, index + 1) + # a UNC path can't have two slashes in a row + # (after the initial two) + if index2 == index + 1: + return p[:0], p + if index2 == -1: + index2 = len(p) + return p[:index2], p[index2:] + if normp[1:2] == colon: + return p[:2], p[2:] + return p[:0], p + + +# Split a path in head (everything up to the last '/') and tail (the +# rest). After the trailing '/' is stripped, the invariant +# join(head, tail) == p holds. +# The resulting head won't end in '/' unless it is the root. + +def split(p): + """Split a pathname. + + Return tuple (head, tail) where tail is everything after the final slash. + Either part may be empty.""" + p = os.fspath(p) + seps = _get_bothseps(p) + d, p = splitdrive(p) + # set i to index beyond p's last slash + i = len(p) + while i and p[i-1] not in seps: + i -= 1 + head, tail = p[:i], p[i:] # now tail has no slashes + # remove trailing slashes from head, unless it's all slashes + head = head.rstrip(seps) or head + return d + head, tail + + +# Split a path in root and extension. +# The extension is everything starting at the last dot in the last +# pathname component; the root is everything before that. +# It is always true that root + ext == p. + +def splitext(p): + p = os.fspath(p) + if isinstance(p, bytes): + return genericpath._splitext(p, b'\\', b'/', b'.') + else: + return genericpath._splitext(p, '\\', '/', '.') +splitext.__doc__ = genericpath._splitext.__doc__ + + +# Return the tail (basename) part of a path. + +def basename(p): + """Returns the final component of a pathname""" + return split(p)[1] + + +# Return the head (dirname) part of a path. + +def dirname(p): + """Returns the directory component of a pathname""" + return split(p)[0] + +# Is a path a symbolic link? +# This will always return false on systems where os.lstat doesn't exist. + +def islink(path): + """Test whether a path is a symbolic link. + This will always return false for Windows prior to 6.0. + """ + try: + st = os.lstat(path) + except (OSError, AttributeError): + return False + return stat.S_ISLNK(st.st_mode) + +# Being true for dangling symbolic links is also useful. + +def lexists(path): + """Test whether a path exists. Returns True for broken symbolic links""" + try: + st = os.lstat(path) + except OSError: + return False + return True + +# Is a path a mount point? +# Any drive letter root (eg c:\) +# Any share UNC (eg \\server\share) +# Any volume mounted on a filesystem folder +# +# No one method detects all three situations. Historically we've lexically +# detected drive letter roots and share UNCs. The canonical approach to +# detecting mounted volumes (querying the reparse tag) fails for the most +# common case: drive letter roots. The alternative which uses GetVolumePathName +# fails if the drive letter is the result of a SUBST. +try: + from nt import _getvolumepathname +except ImportError: + _getvolumepathname = None +def ismount(path): + """Test whether a path is a mount point (a drive root, the root of a + share, or a mounted volume)""" + path = os.fspath(path) + seps = _get_bothseps(path) + path = abspath(path) + root, rest = splitdrive(path) + if root and root[0] in seps: + return (not rest) or (rest in seps) + if rest in seps: + return True + + if _getvolumepathname: + return path.rstrip(seps) == _getvolumepathname(path).rstrip(seps) + else: + return False + + +# Expand paths beginning with '~' or '~user'. +# '~' means $HOME; '~user' means that user's home directory. +# If the path doesn't begin with '~', or if the user or $HOME is unknown, +# the path is returned unchanged (leaving error reporting to whatever +# function is called with the expanded path as argument). +# See also module 'glob' for expansion of *, ? and [...] in pathnames. +# (A function should also be defined to do full *sh-style environment +# variable expansion.) + +def expanduser(path): + """Expand ~ and ~user constructs. + + If user or $HOME is unknown, do nothing.""" + path = os.fspath(path) + if isinstance(path, bytes): + tilde = b'~' + else: + tilde = '~' + if not path.startswith(tilde): + return path + i, n = 1, len(path) + while i < n and path[i] not in _get_bothseps(path): + i += 1 + + if 'HOME' in os.environ: + userhome = os.environ['HOME'] + elif 'USERPROFILE' in os.environ: + userhome = os.environ['USERPROFILE'] + elif not 'HOMEPATH' in os.environ: + return path + else: + try: + drive = os.environ['HOMEDRIVE'] + except KeyError: + drive = '' + userhome = join(drive, os.environ['HOMEPATH']) + + if isinstance(path, bytes): + userhome = os.fsencode(userhome) + + if i != 1: #~user + userhome = join(dirname(userhome), path[1:i]) + + return userhome + path[i:] + + +# Expand paths containing shell variable substitutions. +# The following rules apply: +# - no expansion within single quotes +# - '$$' is translated into '$' +# - '%%' is translated into '%' if '%%' are not seen in %var1%%var2% +# - ${varname} is accepted. +# - $varname is accepted. +# - %varname% is accepted. +# - varnames can be made out of letters, digits and the characters '_-' +# (though is not verified in the ${varname} and %varname% cases) +# XXX With COMMAND.COM you can use any characters in a variable name, +# XXX except '^|<>='. + +def expandvars(path): + """Expand shell variables of the forms $var, ${var} and %var%. + + Unknown variables are left unchanged.""" + path = os.fspath(path) + if isinstance(path, bytes): + if b'$' not in path and b'%' not in path: + return path + import string + varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii') + quote = b'\'' + percent = b'%' + brace = b'{' + rbrace = b'}' + dollar = b'$' + environ = getattr(os, 'environb', None) + else: + if '$' not in path and '%' not in path: + return path + import string + varchars = string.ascii_letters + string.digits + '_-' + quote = '\'' + percent = '%' + brace = '{' + rbrace = '}' + dollar = '$' + environ = os.environ + res = path[:0] + index = 0 + pathlen = len(path) + while index < pathlen: + c = path[index:index+1] + if c == quote: # no expansion within single quotes + path = path[index + 1:] + pathlen = len(path) + try: + index = path.index(c) + res += c + path[:index + 1] + except ValueError: + res += c + path + index = pathlen - 1 + elif c == percent: # variable or '%' + if path[index + 1:index + 2] == percent: + res += c + index += 1 + else: + path = path[index+1:] + pathlen = len(path) + try: + index = path.index(percent) + except ValueError: + res += percent + path + index = pathlen - 1 + else: + var = path[:index] + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = percent + var + percent + res += value + elif c == dollar: # variable or '$$' + if path[index + 1:index + 2] == dollar: + res += c + index += 1 + elif path[index + 1:index + 2] == brace: + path = path[index+2:] + pathlen = len(path) + try: + index = path.index(rbrace) + except ValueError: + res += dollar + brace + path + index = pathlen - 1 + else: + var = path[:index] + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = dollar + brace + var + rbrace + res += value + else: + var = path[:0] + index += 1 + c = path[index:index + 1] + while c and c in varchars: + var += c + index += 1 + c = path[index:index + 1] + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = dollar + var + res += value + if c: + index -= 1 + else: + res += c + index += 1 + return res + + +# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B. +# Previously, this function also truncated pathnames to 8+3 format, +# but as this module is called "ntpath", that's obviously wrong! + +def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + path = os.fspath(path) + if isinstance(path, bytes): + sep = b'\\' + altsep = b'/' + curdir = b'.' + pardir = b'..' + special_prefixes = (b'\\\\.\\', b'\\\\?\\') + else: + sep = '\\' + altsep = '/' + curdir = '.' + pardir = '..' + special_prefixes = ('\\\\.\\', '\\\\?\\') + if path.startswith(special_prefixes): + # in the case of paths with these prefixes: + # \\.\ -> device names + # \\?\ -> literal paths + # do not do any normalization, but return the path unchanged + return path + path = path.replace(altsep, sep) + prefix, path = splitdrive(path) + + # collapse initial backslashes + if path.startswith(sep): + prefix += sep + path = path.lstrip(sep) + + comps = path.split(sep) + i = 0 + while i < len(comps): + if not comps[i] or comps[i] == curdir: + del comps[i] + elif comps[i] == pardir: + if i > 0 and comps[i-1] != pardir: + del comps[i-1:i+1] + i -= 1 + elif i == 0 and prefix.endswith(sep): + del comps[i] + else: + i += 1 + else: + i += 1 + # If the path is now empty, substitute '.' + if not prefix and not comps: + comps.append(curdir) + return prefix + sep.join(comps) + + +# Return an absolute path. +try: + from nt import _getfullpathname + +except ImportError: # not running on Windows - mock up something sensible + def abspath(path): + """Return the absolute version of a path.""" + path = os.fspath(path) + if not isabs(path): + if isinstance(path, bytes): + cwd = os.getcwdb() + else: + cwd = os.getcwd() + path = join(cwd, path) + return normpath(path) + +else: # use native Windows method on Windows + def abspath(path): + """Return the absolute version of a path.""" + + if path: # Empty path must return current working directory. + path = os.fspath(path) + try: + path = _getfullpathname(path) + except OSError: + pass # Bad path - return unchanged. + elif isinstance(path, bytes): + path = os.getcwdb() + else: + path = os.getcwd() + return normpath(path) + +# realpath is a no-op on systems without islink support +realpath = abspath +# Win9x family and earlier have no Unicode filename support. +supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and + sys.getwindowsversion()[3] >= 2) + +def relpath(path, start=None): + """Return a relative version of a path""" + path = os.fspath(path) + if isinstance(path, bytes): + sep = b'\\' + curdir = b'.' + pardir = b'..' + else: + sep = '\\' + curdir = '.' + pardir = '..' + + if start is None: + start = curdir + + if not path: + raise ValueError("no path specified") + + start = os.fspath(start) + try: + start_abs = abspath(normpath(start)) + path_abs = abspath(normpath(path)) + start_drive, start_rest = splitdrive(start_abs) + path_drive, path_rest = splitdrive(path_abs) + if normcase(start_drive) != normcase(path_drive): + raise ValueError("path is on mount %r, start on mount %r" % ( + path_drive, start_drive)) + + start_list = [x for x in start_rest.split(sep) if x] + path_list = [x for x in path_rest.split(sep) if x] + # Work out how much of the filepath is shared by start and path. + i = 0 + for e1, e2 in zip(start_list, path_list): + if normcase(e1) != normcase(e2): + break + i += 1 + + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir + return join(*rel_list) + except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning): + genericpath._check_arg_types('relpath', path, start) + raise + + +# Return the longest common sub-path of the sequence of paths given as input. +# The function is case-insensitive and 'separator-insensitive', i.e. if the +# only difference between two paths is the use of '\' versus '/' as separator, +# they are deemed to be equal. +# +# However, the returned path will have the standard '\' separator (even if the +# given paths had the alternative '/' separator) and will have the case of the +# first path given in the sequence. Additionally, any trailing separator is +# stripped from the returned path. + +def commonpath(paths): + """Given a sequence of path names, returns the longest common sub-path.""" + + if not paths: + raise ValueError('commonpath() arg is an empty sequence') + + paths = tuple(map(os.fspath, paths)) + if isinstance(paths[0], bytes): + sep = b'\\' + altsep = b'/' + curdir = b'.' + else: + sep = '\\' + altsep = '/' + curdir = '.' + + try: + drivesplits = [splitdrive(p.replace(altsep, sep).lower()) for p in paths] + split_paths = [p.split(sep) for d, p in drivesplits] + + try: + isabs, = set(p[:1] == sep for d, p in drivesplits) + except ValueError: + raise ValueError("Can't mix absolute and relative paths") from None + + # Check that all drive letters or UNC paths match. The check is made only + # now otherwise type errors for mixing strings and bytes would not be + # caught. + if len(set(d for d, p in drivesplits)) != 1: + raise ValueError("Paths don't have the same drive") + + drive, path = splitdrive(paths[0].replace(altsep, sep)) + common = path.split(sep) + common = [c for c in common if c and c != curdir] + + split_paths = [[c for c in s if c and c != curdir] for s in split_paths] + s1 = min(split_paths) + s2 = max(split_paths) + for i, c in enumerate(s1): + if c != s2[i]: + common = common[:i] + break + else: + common = common[:len(s1)] + + prefix = drive + sep if isabs else drive + return prefix + sep.join(common) + except (TypeError, AttributeError): + genericpath._check_arg_types('commonpath', *paths) + raise + + +# determine if two files are in fact the same file +try: + # GetFinalPathNameByHandle is available starting with Windows 6.0. + # Windows XP and non-Windows OS'es will mock _getfinalpathname. + if sys.getwindowsversion()[:2] >= (6, 0): + from nt import _getfinalpathname + else: + raise ImportError +except (AttributeError, ImportError): + # On Windows XP and earlier, two files are the same if their absolute + # pathnames are the same. + # Non-Windows operating systems fake this method with an XP + # approximation. + def _getfinalpathname(f): + return normcase(abspath(f)) + + +try: + # The genericpath.isdir implementation uses os.stat and checks the mode + # attribute to tell whether or not the path is a directory. + # This is overkill on Windows - just pass the path to GetFileAttributes + # and check the attribute from there. + from nt import _isdir as isdir +except ImportError: + # Use genericpath.isdir as imported above. + pass diff --git a/Lib/operator.py b/Lib/operator.py new file mode 100644 index 0000000..0e2e53e --- /dev/null +++ b/Lib/operator.py @@ -0,0 +1,464 @@ +""" +Operator Interface + +This module exports a set of functions corresponding to the intrinsic +operators of Python. For example, operator.add(x, y) is equivalent +to the expression x+y. The function names are those used for special +methods; variants without leading and trailing '__' are also provided +for convenience. + +This is the pure Python implementation of the module. +""" + +__all__ = ['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf', + 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand', + 'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul', + 'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', + 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', + 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod', + 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', + 'setitem', 'sub', 'truediv', 'truth', 'xor'] + +from builtins import abs as _abs + + +# Comparison Operations *******************************************************# + +def lt(a, b): + "Same as a < b." + return a < b + +def le(a, b): + "Same as a <= b." + return a <= b + +def eq(a, b): + "Same as a == b." + return a == b + +def ne(a, b): + "Same as a != b." + return a != b + +def ge(a, b): + "Same as a >= b." + return a >= b + +def gt(a, b): + "Same as a > b." + return a > b + +# Logical Operations **********************************************************# + +def not_(a): + "Same as not a." + return not a + +def truth(a): + "Return True if a is true, False otherwise." + return True if a else False + +def is_(a, b): + "Same as a is b." + return a is b + +def is_not(a, b): + "Same as a is not b." + return a is not b + +# Mathematical/Bitwise Operations *********************************************# + +def abs(a): + "Same as abs(a)." + return _abs(a) + +def add(a, b): + "Same as a + b." + return a + b + +def and_(a, b): + "Same as a & b." + return a & b + +def floordiv(a, b): + "Same as a // b." + return a // b + +def index(a): + "Same as a.__index__()." + return a.__index__() + +def inv(a): + "Same as ~a." + return ~a +invert = inv + +def lshift(a, b): + "Same as a << b." + return a << b + +def mod(a, b): + "Same as a % b." + return a % b + +def mul(a, b): + "Same as a * b." + return a * b + +def matmul(a, b): + "Same as a @ b." + return a @ b + +def neg(a): + "Same as -a." + return -a + +def or_(a, b): + "Same as a | b." + return a | b + +def pos(a): + "Same as +a." + return +a + +def pow(a, b): + "Same as a ** b." + return a ** b + +def rshift(a, b): + "Same as a >> b." + return a >> b + +def sub(a, b): + "Same as a - b." + return a - b + +def truediv(a, b): + "Same as a / b." + return a / b + +def xor(a, b): + "Same as a ^ b." + return a ^ b + +# Sequence Operations *********************************************************# + +def concat(a, b): + "Same as a + b, for a and b sequences." + if not hasattr(a, '__getitem__'): + msg = "'%s' object can't be concatenated" % type(a).__name__ + raise TypeError(msg) + return a + b + +def contains(a, b): + "Same as b in a (note reversed operands)." + return b in a + +def countOf(a, b): + "Return the number of times b occurs in a." + count = 0 + for i in a: + if i == b: + count += 1 + return count + +def delitem(a, b): + "Same as del a[b]." + del a[b] + +def getitem(a, b): + "Same as a[b]." + return a[b] + +def indexOf(a, b): + "Return the first index of b in a." + for i, j in enumerate(a): + if j == b: + return i + else: + raise ValueError('sequence.index(x): x not in sequence') + +def setitem(a, b, c): + "Same as a[b] = c." + a[b] = c + +def length_hint(obj, default=0): + """ + Return an estimate of the number of items in obj. + This is useful for presizing containers when building from an iterable. + + If the object supports len(), the result will be exact. Otherwise, it may + over- or under-estimate by an arbitrary amount. The result will be an + integer >= 0. + """ + if not isinstance(default, int): + msg = ("'%s' object cannot be interpreted as an integer" % + type(default).__name__) + raise TypeError(msg) + + try: + return len(obj) + except TypeError: + pass + + try: + hint = type(obj).__length_hint__ + except AttributeError: + return default + + try: + val = hint(obj) + except TypeError: + return default + if val is NotImplemented: + return default + if not isinstance(val, int): + msg = ('__length_hint__ must be integer, not %s' % + type(val).__name__) + raise TypeError(msg) + if val < 0: + msg = '__length_hint__() should return >= 0' + raise ValueError(msg) + return val + +# Generalized Lookup Objects **************************************************# + +class attrgetter: + """ + Return a callable object that fetches the given attribute(s) from its operand. + After f = attrgetter('name'), the call f(r) returns r.name. + After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date). + After h = attrgetter('name.first', 'name.last'), the call h(r) returns + (r.name.first, r.name.last). + """ + __slots__ = ('_attrs', '_call') + + def __init__(self, attr, *attrs): + if not attrs: + if not isinstance(attr, str): + raise TypeError('attribute name must be a string') + self._attrs = (attr,) + names = attr.split('.') + def func(obj): + for name in names: + obj = getattr(obj, name) + return obj + self._call = func + else: + self._attrs = (attr,) + attrs + getters = tuple(map(attrgetter, self._attrs)) + def func(obj): + return tuple(getter(obj) for getter in getters) + self._call = func + + def __call__(self, obj): + return self._call(obj) + + def __repr__(self): + return '%s.%s(%s)' % (self.__class__.__module__, + self.__class__.__qualname__, + ', '.join(map(repr, self._attrs))) + + def __reduce__(self): + return self.__class__, self._attrs + +class itemgetter: + """ + Return a callable object that fetches the given item(s) from its operand. + After f = itemgetter(2), the call f(r) returns r[2]. + After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]) + """ + __slots__ = ('_items', '_call') + + def __init__(self, item, *items): + if not items: + self._items = (item,) + def func(obj): + return obj[item] + self._call = func + else: + self._items = items = (item,) + items + def func(obj): + return tuple(obj[i] for i in items) + self._call = func + + def __call__(self, obj): + return self._call(obj) + + def __repr__(self): + return '%s.%s(%s)' % (self.__class__.__module__, + self.__class__.__name__, + ', '.join(map(repr, self._items))) + + def __reduce__(self): + return self.__class__, self._items + +class methodcaller: + """ + Return a callable object that calls the given method on its operand. + After f = methodcaller('name'), the call f(r) returns r.name(). + After g = methodcaller('name', 'date', foo=1), the call g(r) returns + r.name('date', foo=1). + """ + __slots__ = ('_name', '_args', '_kwargs') + + def __init__(*args, **kwargs): + if len(args) < 2: + msg = "methodcaller needs at least one argument, the method name" + raise TypeError(msg) + self = args[0] + self._name = args[1] + if not isinstance(self._name, str): + raise TypeError('method name must be a string') + self._args = args[2:] + self._kwargs = kwargs + + def __call__(self, obj): + return getattr(obj, self._name)(*self._args, **self._kwargs) + + def __repr__(self): + args = [repr(self._name)] + args.extend(map(repr, self._args)) + args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items()) + return '%s.%s(%s)' % (self.__class__.__module__, + self.__class__.__name__, + ', '.join(args)) + + def __reduce__(self): + if not self._kwargs: + return self.__class__, (self._name,) + self._args + else: + from functools import partial + return partial(self.__class__, self._name, **self._kwargs), self._args + + +# In-place Operations *********************************************************# + +def iadd(a, b): + "Same as a += b." + a += b + return a + +def iand(a, b): + "Same as a &= b." + a &= b + return a + +def iconcat(a, b): + "Same as a += b, for a and b sequences." + if not hasattr(a, '__getitem__'): + msg = "'%s' object can't be concatenated" % type(a).__name__ + raise TypeError(msg) + a += b + return a + +def ifloordiv(a, b): + "Same as a //= b." + a //= b + return a + +def ilshift(a, b): + "Same as a <<= b." + a <<= b + return a + +def imod(a, b): + "Same as a %= b." + a %= b + return a + +def imul(a, b): + "Same as a *= b." + a *= b + return a + +def imatmul(a, b): + "Same as a @= b." + a @= b + return a + +def ior(a, b): + "Same as a |= b." + a |= b + return a + +def ipow(a, b): + "Same as a **= b." + a **=b + return a + +def irshift(a, b): + "Same as a >>= b." + a >>= b + return a + +def isub(a, b): + "Same as a -= b." + a -= b + return a + +def itruediv(a, b): + "Same as a /= b." + a /= b + return a + +def ixor(a, b): + "Same as a ^= b." + a ^= b + return a + + +try: + from _operator import * +except ImportError: + pass +else: + from _operator import __doc__ + +# All of these "__func__ = func" assignments have to happen after importing +# from _operator to make sure they're set to the right function +__lt__ = lt +__le__ = le +__eq__ = eq +__ne__ = ne +__ge__ = ge +__gt__ = gt +__not__ = not_ +__abs__ = abs +__add__ = add +__and__ = and_ +__floordiv__ = floordiv +__index__ = index +__inv__ = inv +__invert__ = invert +__lshift__ = lshift +__mod__ = mod +__mul__ = mul +__matmul__ = matmul +__neg__ = neg +__or__ = or_ +__pos__ = pos +__pow__ = pow +__rshift__ = rshift +__sub__ = sub +__truediv__ = truediv +__xor__ = xor +__concat__ = concat +__contains__ = contains +__delitem__ = delitem +__getitem__ = getitem +__setitem__ = setitem +__iadd__ = iadd +__iand__ = iand +__iconcat__ = iconcat +__ifloordiv__ = ifloordiv +__ilshift__ = ilshift +__imod__ = imod +__imul__ = imul +__imatmul__ = imatmul +__ior__ = ior +__ipow__ = ipow +__irshift__ = irshift +__isub__ = isub +__itruediv__ = itruediv +__ixor__ = ixor diff --git a/Lib/orig-prefix.txt b/Lib/orig-prefix.txt new file mode 100644 index 0000000..58964ea --- /dev/null +++ b/Lib/orig-prefix.txt @@ -0,0 +1 @@ +c:\users\envy 17\appdata\local\programs\python\python37 \ No newline at end of file diff --git a/Lib/os.py b/Lib/os.py new file mode 100644 index 0000000..499e628 --- /dev/null +++ b/Lib/os.py @@ -0,0 +1,1078 @@ +r"""OS routines for NT or Posix depending on what system we're on. + +This exports: + - all functions from posix or nt, e.g. unlink, stat, etc. + - os.path is either posixpath or ntpath + - os.name is either 'posix' or 'nt' + - os.curdir is a string representing the current directory (always '.') + - os.pardir is a string representing the parent directory (always '..') + - os.sep is the (or a most common) pathname separator ('/' or '\\') + - os.extsep is the extension separator (always '.') + - os.altsep is the alternate pathname separator (None or '/') + - os.pathsep is the component separator used in $PATH etc + - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') + - os.defpath is the default search path for executables + - os.devnull is the file path of the null device ('/dev/null', etc.) + +Programs that import and use 'os' stand a better chance of being +portable between different platforms. Of course, they must then +only use functions that are defined by all platforms (e.g., unlink +and opendir), and leave all pathname manipulation to os.path +(e.g., split and join). +""" + +#' +import abc +import sys +import stat as st + +_names = sys.builtin_module_names + +# Note: more names are added to __all__ later. +__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", + "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR", + "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen", + "popen", "extsep"] + +def _exists(name): + return name in globals() + +def _get_exports_list(module): + try: + return list(module.__all__) + except AttributeError: + return [n for n in dir(module) if n[0] != '_'] + +# Any new dependencies of the os module and/or changes in path separator +# requires updating importlib as well. +if 'posix' in _names: + name = 'posix' + linesep = '\n' + from posix import * + try: + from posix import _exit + __all__.append('_exit') + except ImportError: + pass + import posixpath as path + + try: + from posix import _have_functions + except ImportError: + pass + + import posix + __all__.extend(_get_exports_list(posix)) + del posix + +elif 'nt' in _names: + name = 'nt' + linesep = '\r\n' + from nt import * + try: + from nt import _exit + __all__.append('_exit') + except ImportError: + pass + import ntpath as path + + import nt + __all__.extend(_get_exports_list(nt)) + del nt + + try: + from nt import _have_functions + except ImportError: + pass + +else: + raise ImportError('no os specific module found') + +sys.modules['os.path'] = path +from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, + devnull) + +del _names + + +if _exists("_have_functions"): + _globals = globals() + def _add(str, fn): + if (fn in _globals) and (str in _have_functions): + _set.add(_globals[fn]) + + _set = set() + _add("HAVE_FACCESSAT", "access") + _add("HAVE_FCHMODAT", "chmod") + _add("HAVE_FCHOWNAT", "chown") + _add("HAVE_FSTATAT", "stat") + _add("HAVE_FUTIMESAT", "utime") + _add("HAVE_LINKAT", "link") + _add("HAVE_MKDIRAT", "mkdir") + _add("HAVE_MKFIFOAT", "mkfifo") + _add("HAVE_MKNODAT", "mknod") + _add("HAVE_OPENAT", "open") + _add("HAVE_READLINKAT", "readlink") + _add("HAVE_RENAMEAT", "rename") + _add("HAVE_SYMLINKAT", "symlink") + _add("HAVE_UNLINKAT", "unlink") + _add("HAVE_UNLINKAT", "rmdir") + _add("HAVE_UTIMENSAT", "utime") + supports_dir_fd = _set + + _set = set() + _add("HAVE_FACCESSAT", "access") + supports_effective_ids = _set + + _set = set() + _add("HAVE_FCHDIR", "chdir") + _add("HAVE_FCHMOD", "chmod") + _add("HAVE_FCHOWN", "chown") + _add("HAVE_FDOPENDIR", "listdir") + _add("HAVE_FDOPENDIR", "scandir") + _add("HAVE_FEXECVE", "execve") + _set.add(stat) # fstat always works + _add("HAVE_FTRUNCATE", "truncate") + _add("HAVE_FUTIMENS", "utime") + _add("HAVE_FUTIMES", "utime") + _add("HAVE_FPATHCONF", "pathconf") + if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3 + _add("HAVE_FSTATVFS", "statvfs") + supports_fd = _set + + _set = set() + _add("HAVE_FACCESSAT", "access") + # Some platforms don't support lchmod(). Often the function exists + # anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP. + # (No, I don't know why that's a good design.) ./configure will detect + # this and reject it--so HAVE_LCHMOD still won't be defined on such + # platforms. This is Very Helpful. + # + # However, sometimes platforms without a working lchmod() *do* have + # fchmodat(). (Examples: Linux kernel 3.2 with glibc 2.15, + # OpenIndiana 3.x.) And fchmodat() has a flag that theoretically makes + # it behave like lchmod(). So in theory it would be a suitable + # replacement for lchmod(). But when lchmod() doesn't work, fchmodat()'s + # flag doesn't work *either*. Sadly ./configure isn't sophisticated + # enough to detect this condition--it only determines whether or not + # fchmodat() minimally works. + # + # Therefore we simply ignore fchmodat() when deciding whether or not + # os.chmod supports follow_symlinks. Just checking lchmod() is + # sufficient. After all--if you have a working fchmodat(), your + # lchmod() almost certainly works too. + # + # _add("HAVE_FCHMODAT", "chmod") + _add("HAVE_FCHOWNAT", "chown") + _add("HAVE_FSTATAT", "stat") + _add("HAVE_LCHFLAGS", "chflags") + _add("HAVE_LCHMOD", "chmod") + if _exists("lchown"): # mac os x10.3 + _add("HAVE_LCHOWN", "chown") + _add("HAVE_LINKAT", "link") + _add("HAVE_LUTIMES", "utime") + _add("HAVE_LSTAT", "stat") + _add("HAVE_FSTATAT", "stat") + _add("HAVE_UTIMENSAT", "utime") + _add("MS_WINDOWS", "stat") + supports_follow_symlinks = _set + + del _set + del _have_functions + del _globals + del _add + + +# Python uses fixed values for the SEEK_ constants; they are mapped +# to native constants if necessary in posixmodule.c +# Other possible SEEK values are directly imported from posixmodule.c +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + +# Super directory utilities. +# (Inspired by Eric Raymond; the doc strings are mostly his) + +def makedirs(name, mode=0o777, exist_ok=False): + """makedirs(name [, mode=0o777][, exist_ok=False]) + + Super-mkdir; create a leaf directory and all intermediate ones. Works like + mkdir, except that any intermediate path segment (not just the rightmost) + will be created if it does not exist. If the target directory already + exists, raise an OSError if exist_ok is False. Otherwise no exception is + raised. This is recursive. + + """ + head, tail = path.split(name) + if not tail: + head, tail = path.split(head) + if head and tail and not path.exists(head): + try: + makedirs(head, exist_ok=exist_ok) + except FileExistsError: + # Defeats race condition when another thread created the path + pass + cdir = curdir + if isinstance(tail, bytes): + cdir = bytes(curdir, 'ASCII') + if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists + return + try: + mkdir(name, mode) + except OSError: + # Cannot rely on checking for EEXIST, since the operating system + # could give priority to other errors like EACCES or EROFS + if not exist_ok or not path.isdir(name): + raise + +def removedirs(name): + """removedirs(name) + + Super-rmdir; remove a leaf directory and all empty intermediate + ones. Works like rmdir except that, if the leaf directory is + successfully removed, directories corresponding to rightmost path + segments will be pruned away until either the whole path is + consumed or an error occurs. Errors during this latter phase are + ignored -- they generally mean that a directory was not empty. + + """ + rmdir(name) + head, tail = path.split(name) + if not tail: + head, tail = path.split(head) + while head and tail: + try: + rmdir(head) + except OSError: + break + head, tail = path.split(head) + +def renames(old, new): + """renames(old, new) + + Super-rename; create directories as necessary and delete any left + empty. Works like rename, except creation of any intermediate + directories needed to make the new pathname good is attempted + first. After the rename, directories corresponding to rightmost + path segments of the old name will be pruned until either the + whole path is consumed or a nonempty directory is found. + + Note: this function can fail with the new directory structure made + if you lack permissions needed to unlink the leaf directory or + file. + + """ + head, tail = path.split(new) + if head and tail and not path.exists(head): + makedirs(head) + rename(old, new) + head, tail = path.split(old) + if head and tail: + try: + removedirs(head) + except OSError: + pass + +__all__.extend(["makedirs", "removedirs", "renames"]) + +def walk(top, topdown=True, onerror=None, followlinks=False): + """Directory tree generator. + + For each directory in the directory tree rooted at top (including top + itself, but excluding '.' and '..'), yields a 3-tuple + + dirpath, dirnames, filenames + + dirpath is a string, the path to the directory. dirnames is a list of + the names of the subdirectories in dirpath (excluding '.' and '..'). + filenames is a list of the names of the non-directory files in dirpath. + Note that the names in the lists are just names, with no path components. + To get a full path (which begins with top) to a file or directory in + dirpath, do os.path.join(dirpath, name). + + If optional arg 'topdown' is true or not specified, the triple for a + directory is generated before the triples for any of its subdirectories + (directories are generated top down). If topdown is false, the triple + for a directory is generated after the triples for all of its + subdirectories (directories are generated bottom up). + + When topdown is true, the caller can modify the dirnames list in-place + (e.g., via del or slice assignment), and walk will only recurse into the + subdirectories whose names remain in dirnames; this can be used to prune the + search, or to impose a specific order of visiting. Modifying dirnames when + topdown is false is ineffective, since the directories in dirnames have + already been generated by the time dirnames itself is generated. No matter + the value of topdown, the list of subdirectories is retrieved before the + tuples for the directory and its subdirectories are generated. + + By default errors from the os.scandir() call are ignored. If + optional arg 'onerror' is specified, it should be a function; it + will be called with one argument, an OSError instance. It can + report the error to continue with the walk, or raise the exception + to abort the walk. Note that the filename is available as the + filename attribute of the exception object. + + By default, os.walk does not follow symbolic links to subdirectories on + systems that support them. In order to get this functionality, set the + optional argument 'followlinks' to true. + + Caution: if you pass a relative pathname for top, don't change the + current working directory between resumptions of walk. walk never + changes the current directory, and assumes that the client doesn't + either. + + Example: + + import os + from os.path import join, getsize + for root, dirs, files in os.walk('python/Lib/email'): + print(root, "consumes", end="") + print(sum([getsize(join(root, name)) for name in files]), end="") + print("bytes in", len(files), "non-directory files") + if 'CVS' in dirs: + dirs.remove('CVS') # don't visit CVS directories + + """ + top = fspath(top) + dirs = [] + nondirs = [] + walk_dirs = [] + + # We may not have read permission for top, in which case we can't + # get a list of the files the directory contains. os.walk + # always suppressed the exception then, rather than blow up for a + # minor reason when (say) a thousand readable directories are still + # left to visit. That logic is copied here. + try: + # Note that scandir is global in this module due + # to earlier import-*. + scandir_it = scandir(top) + except OSError as error: + if onerror is not None: + onerror(error) + return + + with scandir_it: + while True: + try: + try: + entry = next(scandir_it) + except StopIteration: + break + except OSError as error: + if onerror is not None: + onerror(error) + return + + try: + is_dir = entry.is_dir() + except OSError: + # If is_dir() raises an OSError, consider that the entry is not + # a directory, same behaviour than os.path.isdir(). + is_dir = False + + if is_dir: + dirs.append(entry.name) + else: + nondirs.append(entry.name) + + if not topdown and is_dir: + # Bottom-up: recurse into sub-directory, but exclude symlinks to + # directories if followlinks is False + if followlinks: + walk_into = True + else: + try: + is_symlink = entry.is_symlink() + except OSError: + # If is_symlink() raises an OSError, consider that the + # entry is not a symbolic link, same behaviour than + # os.path.islink(). + is_symlink = False + walk_into = not is_symlink + + if walk_into: + walk_dirs.append(entry.path) + + # Yield before recursion if going top down + if topdown: + yield top, dirs, nondirs + + # Recurse into sub-directories + islink, join = path.islink, path.join + for dirname in dirs: + new_path = join(top, dirname) + # Issue #23605: os.path.islink() is used instead of caching + # entry.is_symlink() result during the loop on os.scandir() because + # the caller can replace the directory entry during the "yield" + # above. + if followlinks or not islink(new_path): + yield from walk(new_path, topdown, onerror, followlinks) + else: + # Recurse into sub-directories + for new_path in walk_dirs: + yield from walk(new_path, topdown, onerror, followlinks) + # Yield after recursion if going bottom up + yield top, dirs, nondirs + +__all__.append("walk") + +if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd: + + def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=None): + """Directory tree generator. + + This behaves exactly like walk(), except that it yields a 4-tuple + + dirpath, dirnames, filenames, dirfd + + `dirpath`, `dirnames` and `filenames` are identical to walk() output, + and `dirfd` is a file descriptor referring to the directory `dirpath`. + + The advantage of fwalk() over walk() is that it's safe against symlink + races (when follow_symlinks is False). + + If dir_fd is not None, it should be a file descriptor open to a directory, + and top should be relative; top will then be relative to that directory. + (dir_fd is always supported for fwalk.) + + Caution: + Since fwalk() yields file descriptors, those are only valid until the + next iteration step, so you should dup() them if you want to keep them + for a longer period. + + Example: + + import os + for root, dirs, files, rootfd in os.fwalk('python/Lib/email'): + print(root, "consumes", end="") + print(sum([os.stat(name, dir_fd=rootfd).st_size for name in files]), + end="") + print("bytes in", len(files), "non-directory files") + if 'CVS' in dirs: + dirs.remove('CVS') # don't visit CVS directories + """ + if not isinstance(top, int) or not hasattr(top, '__index__'): + top = fspath(top) + # Note: To guard against symlink races, we use the standard + # lstat()/open()/fstat() trick. + if not follow_symlinks: + orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd) + topfd = open(top, O_RDONLY, dir_fd=dir_fd) + try: + if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and + path.samestat(orig_st, stat(topfd)))): + yield from _fwalk(topfd, top, isinstance(top, bytes), + topdown, onerror, follow_symlinks) + finally: + close(topfd) + + def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks): + # Note: This uses O(depth of the directory tree) file descriptors: if + # necessary, it can be adapted to only require O(1) FDs, see issue + # #13734. + + scandir_it = scandir(topfd) + dirs = [] + nondirs = [] + entries = None if topdown or follow_symlinks else [] + for entry in scandir_it: + name = entry.name + if isbytes: + name = fsencode(name) + try: + if entry.is_dir(): + dirs.append(name) + if entries is not None: + entries.append(entry) + else: + nondirs.append(name) + except OSError: + try: + # Add dangling symlinks, ignore disappeared files + if entry.is_symlink(): + nondirs.append(name) + except OSError: + pass + + if topdown: + yield toppath, dirs, nondirs, topfd + + for name in dirs if entries is None else zip(dirs, entries): + try: + if not follow_symlinks: + if topdown: + orig_st = stat(name, dir_fd=topfd, follow_symlinks=False) + else: + assert entries is not None + name, entry = name + orig_st = entry.stat(follow_symlinks=False) + dirfd = open(name, O_RDONLY, dir_fd=topfd) + except OSError as err: + if onerror is not None: + onerror(err) + continue + try: + if follow_symlinks or path.samestat(orig_st, stat(dirfd)): + dirpath = path.join(toppath, name) + yield from _fwalk(dirfd, dirpath, isbytes, + topdown, onerror, follow_symlinks) + finally: + close(dirfd) + + if not topdown: + yield toppath, dirs, nondirs, topfd + + __all__.append("fwalk") + +# Make sure os.environ exists, at least +try: + environ +except NameError: + environ = {} + +def execl(file, *args): + """execl(file, *args) + + Execute the executable file with argument list args, replacing the + current process. """ + execv(file, args) + +def execle(file, *args): + """execle(file, *args, env) + + Execute the executable file with argument list args and + environment env, replacing the current process. """ + env = args[-1] + execve(file, args[:-1], env) + +def execlp(file, *args): + """execlp(file, *args) + + Execute the executable file (which is searched for along $PATH) + with argument list args, replacing the current process. """ + execvp(file, args) + +def execlpe(file, *args): + """execlpe(file, *args, env) + + Execute the executable file (which is searched for along $PATH) + with argument list args and environment env, replacing the current + process. """ + env = args[-1] + execvpe(file, args[:-1], env) + +def execvp(file, args): + """execvp(file, args) + + Execute the executable file (which is searched for along $PATH) + with argument list args, replacing the current process. + args may be a list or tuple of strings. """ + _execvpe(file, args) + +def execvpe(file, args, env): + """execvpe(file, args, env) + + Execute the executable file (which is searched for along $PATH) + with argument list args and environment env , replacing the + current process. + args may be a list or tuple of strings. """ + _execvpe(file, args, env) + +__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) + +def _execvpe(file, args, env=None): + if env is not None: + exec_func = execve + argrest = (args, env) + else: + exec_func = execv + argrest = (args,) + env = environ + + if path.dirname(file): + exec_func(file, *argrest) + return + saved_exc = None + path_list = get_exec_path(env) + if name != 'nt': + file = fsencode(file) + path_list = map(fsencode, path_list) + for dir in path_list: + fullname = path.join(dir, file) + try: + exec_func(fullname, *argrest) + except (FileNotFoundError, NotADirectoryError) as e: + last_exc = e + except OSError as e: + last_exc = e + if saved_exc is None: + saved_exc = e + if saved_exc is not None: + raise saved_exc + raise last_exc + + +def get_exec_path(env=None): + """Returns the sequence of directories that will be searched for the + named executable (similar to a shell) when launching a process. + + *env* must be an environment variable dict or None. If *env* is None, + os.environ will be used. + """ + # Use a local import instead of a global import to limit the number of + # modules loaded at startup: the os module is always loaded at startup by + # Python. It may also avoid a bootstrap issue. + import warnings + + if env is None: + env = environ + + # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a + # BytesWarning when using python -b or python -bb: ignore the warning + with warnings.catch_warnings(): + warnings.simplefilter("ignore", BytesWarning) + + try: + path_list = env.get('PATH') + except TypeError: + path_list = None + + if supports_bytes_environ: + try: + path_listb = env[b'PATH'] + except (KeyError, TypeError): + pass + else: + if path_list is not None: + raise ValueError( + "env cannot contain 'PATH' and b'PATH' keys") + path_list = path_listb + + if path_list is not None and isinstance(path_list, bytes): + path_list = fsdecode(path_list) + + if path_list is None: + path_list = defpath + return path_list.split(pathsep) + + +# Change environ to automatically call putenv(), unsetenv if they exist. +from _collections_abc import MutableMapping + +class _Environ(MutableMapping): + def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv): + self.encodekey = encodekey + self.decodekey = decodekey + self.encodevalue = encodevalue + self.decodevalue = decodevalue + self.putenv = putenv + self.unsetenv = unsetenv + self._data = data + + def __getitem__(self, key): + try: + value = self._data[self.encodekey(key)] + except KeyError: + # raise KeyError with the original key value + raise KeyError(key) from None + return self.decodevalue(value) + + def __setitem__(self, key, value): + key = self.encodekey(key) + value = self.encodevalue(value) + self.putenv(key, value) + self._data[key] = value + + def __delitem__(self, key): + encodedkey = self.encodekey(key) + self.unsetenv(encodedkey) + try: + del self._data[encodedkey] + except KeyError: + # raise KeyError with the original key value + raise KeyError(key) from None + + def __iter__(self): + # list() from dict object is an atomic operation + keys = list(self._data) + for key in keys: + yield self.decodekey(key) + + def __len__(self): + return len(self._data) + + def __repr__(self): + return 'environ({{{}}})'.format(', '.join( + ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value)) + for key, value in self._data.items()))) + + def copy(self): + return dict(self) + + def setdefault(self, key, value): + if key not in self: + self[key] = value + return self[key] + +try: + _putenv = putenv +except NameError: + _putenv = lambda key, value: None +else: + if "putenv" not in __all__: + __all__.append("putenv") + +try: + _unsetenv = unsetenv +except NameError: + _unsetenv = lambda key: _putenv(key, "") +else: + if "unsetenv" not in __all__: + __all__.append("unsetenv") + +def _createenviron(): + if name == 'nt': + # Where Env Var Names Must Be UPPERCASE + def check_str(value): + if not isinstance(value, str): + raise TypeError("str expected, not %s" % type(value).__name__) + return value + encode = check_str + decode = str + def encodekey(key): + return encode(key).upper() + data = {} + for key, value in environ.items(): + data[encodekey(key)] = value + else: + # Where Env Var Names Can Be Mixed Case + encoding = sys.getfilesystemencoding() + def encode(value): + if not isinstance(value, str): + raise TypeError("str expected, not %s" % type(value).__name__) + return value.encode(encoding, 'surrogateescape') + def decode(value): + return value.decode(encoding, 'surrogateescape') + encodekey = encode + data = environ + return _Environ(data, + encodekey, decode, + encode, decode, + _putenv, _unsetenv) + +# unicode environ +environ = _createenviron() +del _createenviron + + +def getenv(key, default=None): + """Get an environment variable, return None if it doesn't exist. + The optional second argument can specify an alternate default. + key, default and the result are str.""" + return environ.get(key, default) + +supports_bytes_environ = (name != 'nt') +__all__.extend(("getenv", "supports_bytes_environ")) + +if supports_bytes_environ: + def _check_bytes(value): + if not isinstance(value, bytes): + raise TypeError("bytes expected, not %s" % type(value).__name__) + return value + + # bytes environ + environb = _Environ(environ._data, + _check_bytes, bytes, + _check_bytes, bytes, + _putenv, _unsetenv) + del _check_bytes + + def getenvb(key, default=None): + """Get an environment variable, return None if it doesn't exist. + The optional second argument can specify an alternate default. + key, default and the result are bytes.""" + return environb.get(key, default) + + __all__.extend(("environb", "getenvb")) + +def _fscodec(): + encoding = sys.getfilesystemencoding() + errors = sys.getfilesystemencodeerrors() + + def fsencode(filename): + """Encode filename (an os.PathLike, bytes, or str) to the filesystem + encoding with 'surrogateescape' error handler, return bytes unchanged. + On Windows, use 'strict' error handler if the file system encoding is + 'mbcs' (which is the default encoding). + """ + filename = fspath(filename) # Does type-checking of `filename`. + if isinstance(filename, str): + return filename.encode(encoding, errors) + else: + return filename + + def fsdecode(filename): + """Decode filename (an os.PathLike, bytes, or str) from the filesystem + encoding with 'surrogateescape' error handler, return str unchanged. On + Windows, use 'strict' error handler if the file system encoding is + 'mbcs' (which is the default encoding). + """ + filename = fspath(filename) # Does type-checking of `filename`. + if isinstance(filename, bytes): + return filename.decode(encoding, errors) + else: + return filename + + return fsencode, fsdecode + +fsencode, fsdecode = _fscodec() +del _fscodec + +# Supply spawn*() (probably only for Unix) +if _exists("fork") and not _exists("spawnv") and _exists("execv"): + + P_WAIT = 0 + P_NOWAIT = P_NOWAITO = 1 + + __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"]) + + # XXX Should we support P_DETACH? I suppose it could fork()**2 + # and close the std I/O streams. Also, P_OVERLAY is the same + # as execv*()? + + def _spawnvef(mode, file, args, env, func): + # Internal helper; func is the exec*() function to use + if not isinstance(args, (tuple, list)): + raise TypeError('argv must be a tuple or a list') + if not args or not args[0]: + raise ValueError('argv first element cannot be empty') + pid = fork() + if not pid: + # Child + try: + if env is None: + func(file, args) + else: + func(file, args, env) + except: + _exit(127) + else: + # Parent + if mode == P_NOWAIT: + return pid # Caller is responsible for waiting! + while 1: + wpid, sts = waitpid(pid, 0) + if WIFSTOPPED(sts): + continue + elif WIFSIGNALED(sts): + return -WTERMSIG(sts) + elif WIFEXITED(sts): + return WEXITSTATUS(sts) + else: + raise OSError("Not stopped, signaled or exited???") + + def spawnv(mode, file, args): + """spawnv(mode, file, args) -> integer + +Execute file with arguments from args in a subprocess. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + return _spawnvef(mode, file, args, None, execv) + + def spawnve(mode, file, args, env): + """spawnve(mode, file, args, env) -> integer + +Execute file with arguments from args in a subprocess with the +specified environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + return _spawnvef(mode, file, args, env, execve) + + # Note: spawnvp[e] isn't currently supported on Windows + + def spawnvp(mode, file, args): + """spawnvp(mode, file, args) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + return _spawnvef(mode, file, args, None, execvp) + + def spawnvpe(mode, file, args, env): + """spawnvpe(mode, file, args, env) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess with the supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + return _spawnvef(mode, file, args, env, execvpe) + + + __all__.extend(["spawnv", "spawnve", "spawnvp", "spawnvpe"]) + + +if _exists("spawnv"): + # These aren't supplied by the basic Windows code + # but can be easily implemented in Python + + def spawnl(mode, file, *args): + """spawnl(mode, file, *args) -> integer + +Execute file with arguments from args in a subprocess. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + return spawnv(mode, file, args) + + def spawnle(mode, file, *args): + """spawnle(mode, file, *args, env) -> integer + +Execute file with arguments from args in a subprocess with the +supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + env = args[-1] + return spawnve(mode, file, args[:-1], env) + + + __all__.extend(["spawnl", "spawnle"]) + + +if _exists("spawnvp"): + # At the moment, Windows doesn't implement spawnvp[e], + # so it won't have spawnlp[e] either. + def spawnlp(mode, file, *args): + """spawnlp(mode, file, *args) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess with the supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + return spawnvp(mode, file, args) + + def spawnlpe(mode, file, *args): + """spawnlpe(mode, file, *args, env) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess with the supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ + env = args[-1] + return spawnvpe(mode, file, args[:-1], env) + + + __all__.extend(["spawnlp", "spawnlpe"]) + + +# Supply os.popen() +def popen(cmd, mode="r", buffering=-1): + if not isinstance(cmd, str): + raise TypeError("invalid cmd type (%s, expected string)" % type(cmd)) + if mode not in ("r", "w"): + raise ValueError("invalid mode %r" % mode) + if buffering == 0 or buffering is None: + raise ValueError("popen() does not support unbuffered streams") + import subprocess, io + if mode == "r": + proc = subprocess.Popen(cmd, + shell=True, + stdout=subprocess.PIPE, + bufsize=buffering) + return _wrap_close(io.TextIOWrapper(proc.stdout), proc) + else: + proc = subprocess.Popen(cmd, + shell=True, + stdin=subprocess.PIPE, + bufsize=buffering) + return _wrap_close(io.TextIOWrapper(proc.stdin), proc) + +# Helper for popen() -- a proxy for a file whose close waits for the process +class _wrap_close: + def __init__(self, stream, proc): + self._stream = stream + self._proc = proc + def close(self): + self._stream.close() + returncode = self._proc.wait() + if returncode == 0: + return None + if name == 'nt': + return returncode + else: + return returncode << 8 # Shift left to match old behavior + def __enter__(self): + return self + def __exit__(self, *args): + self.close() + def __getattr__(self, name): + return getattr(self._stream, name) + def __iter__(self): + return iter(self._stream) + +# Supply os.fdopen() +def fdopen(fd, *args, **kwargs): + if not isinstance(fd, int): + raise TypeError("invalid fd type (%s, expected integer)" % type(fd)) + import io + return io.open(fd, *args, **kwargs) + + +# For testing purposes, make sure the function is available when the C +# implementation exists. +def _fspath(path): + """Return the path representation of a path-like object. + + If str or bytes is passed in, it is returned unchanged. Otherwise the + os.PathLike interface is used to get the path representation. If the + path representation is not str or bytes, TypeError is raised. If the + provided path is not str, bytes, or os.PathLike, TypeError is raised. + """ + if isinstance(path, (str, bytes)): + return path + + # Work from the object's type to match method resolution of other magic + # methods. + path_type = type(path) + try: + path_repr = path_type.__fspath__(path) + except AttributeError: + if hasattr(path_type, '__fspath__'): + raise + else: + raise TypeError("expected str, bytes or os.PathLike object, " + "not " + path_type.__name__) + if isinstance(path_repr, (str, bytes)): + return path_repr + else: + raise TypeError("expected {}.__fspath__() to return str or bytes, " + "not {}".format(path_type.__name__, + type(path_repr).__name__)) + +# If there is no C implementation, make the pure Python version the +# implementation as transparently as possible. +if not _exists('fspath'): + fspath = _fspath + fspath.__name__ = "fspath" + + +class PathLike(abc.ABC): + + """Abstract base class for implementing the file system path protocol.""" + + @abc.abstractmethod + def __fspath__(self): + """Return the file system path representation of the object.""" + raise NotImplementedError + + @classmethod + def __subclasshook__(cls, subclass): + return hasattr(subclass, '__fspath__') diff --git a/Lib/posixpath.py b/Lib/posixpath.py new file mode 100644 index 0000000..e92186c --- /dev/null +++ b/Lib/posixpath.py @@ -0,0 +1,522 @@ +"""Common operations on Posix pathnames. + +Instead of importing this module directly, import os and refer to +this module as os.path. The "os.path" name is an alias for this +module on Posix systems; on other systems (e.g. Mac, Windows), +os.path provides the same operations in a manner specific to that +platform, and is an alias to another module (e.g. macpath, ntpath). + +Some of this can actually be useful on non-Posix systems too, e.g. +for manipulation of the pathname component of URLs. +""" + +# Strings representing various path-related bits and pieces. +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = '.' +pardir = '..' +extsep = '.' +sep = '/' +pathsep = ':' +defpath = ':/bin:/usr/bin' +altsep = None +devnull = '/dev/null' + +import os +import sys +import stat +import genericpath +from genericpath import * + +__all__ = ["normcase","isabs","join","splitdrive","split","splitext", + "basename","dirname","commonprefix","getsize","getmtime", + "getatime","getctime","islink","exists","lexists","isdir","isfile", + "ismount", "expanduser","expandvars","normpath","abspath", + "samefile","sameopenfile","samestat", + "curdir","pardir","sep","pathsep","defpath","altsep","extsep", + "devnull","realpath","supports_unicode_filenames","relpath", + "commonpath"] + + +def _get_sep(path): + if isinstance(path, bytes): + return b'/' + else: + return '/' + +# Normalize the case of a pathname. Trivial in Posix, string.lower on Mac. +# On MS-DOS this may also turn slashes into backslashes; however, other +# normalizations (such as optimizing '../' away) are not allowed +# (another function should be defined to do that). + +def normcase(s): + """Normalize case of pathname. Has no effect under Posix""" + s = os.fspath(s) + if not isinstance(s, (bytes, str)): + raise TypeError("normcase() argument must be str or bytes, " + "not '{}'".format(s.__class__.__name__)) + return s + + +# Return whether a path is absolute. +# Trivial in Posix, harder on the Mac or MS-DOS. + +def isabs(s): + """Test whether a path is absolute""" + s = os.fspath(s) + sep = _get_sep(s) + return s.startswith(sep) + + +# Join pathnames. +# Ignore the previous parts if a part is absolute. +# Insert a '/' unless the first part is empty or already ends in '/'. + +def join(a, *p): + """Join two or more pathname components, inserting '/' as needed. + If any component is an absolute path, all previous path components + will be discarded. An empty last part will result in a path that + ends with a separator.""" + a = os.fspath(a) + sep = _get_sep(a) + path = a + try: + if not p: + path[:0] + sep #23780: Ensure compatible data type even if p is null. + for b in map(os.fspath, p): + if b.startswith(sep): + path = b + elif not path or path.endswith(sep): + path += b + else: + path += sep + b + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', a, *p) + raise + return path + + +# Split a path in head (everything up to the last '/') and tail (the +# rest). If the path ends in '/', tail will be empty. If there is no +# '/' in the path, head will be empty. +# Trailing '/'es are stripped from head unless it is the root. + +def split(p): + """Split a pathname. Returns tuple "(head, tail)" where "tail" is + everything after the final slash. Either part may be empty.""" + p = os.fspath(p) + sep = _get_sep(p) + i = p.rfind(sep) + 1 + head, tail = p[:i], p[i:] + if head and head != sep*len(head): + head = head.rstrip(sep) + return head, tail + + +# Split a path in root and extension. +# The extension is everything starting at the last dot in the last +# pathname component; the root is everything before that. +# It is always true that root + ext == p. + +def splitext(p): + p = os.fspath(p) + if isinstance(p, bytes): + sep = b'/' + extsep = b'.' + else: + sep = '/' + extsep = '.' + return genericpath._splitext(p, sep, None, extsep) +splitext.__doc__ = genericpath._splitext.__doc__ + +# Split a pathname into a drive specification and the rest of the +# path. Useful on DOS/Windows/NT; on Unix, the drive is always empty. + +def splitdrive(p): + """Split a pathname into drive and path. On Posix, drive is always + empty.""" + p = os.fspath(p) + return p[:0], p + + +# Return the tail (basename) part of a path, same as split(path)[1]. + +def basename(p): + """Returns the final component of a pathname""" + p = os.fspath(p) + sep = _get_sep(p) + i = p.rfind(sep) + 1 + return p[i:] + + +# Return the head (dirname) part of a path, same as split(path)[0]. + +def dirname(p): + """Returns the directory component of a pathname""" + p = os.fspath(p) + sep = _get_sep(p) + i = p.rfind(sep) + 1 + head = p[:i] + if head and head != sep*len(head): + head = head.rstrip(sep) + return head + + +# Is a path a symbolic link? +# This will always return false on systems where os.lstat doesn't exist. + +def islink(path): + """Test whether a path is a symbolic link""" + try: + st = os.lstat(path) + except (OSError, AttributeError): + return False + return stat.S_ISLNK(st.st_mode) + +# Being true for dangling symbolic links is also useful. + +def lexists(path): + """Test whether a path exists. Returns True for broken symbolic links""" + try: + os.lstat(path) + except OSError: + return False + return True + + +# Is a path a mount point? +# (Does this work for all UNIXes? Is it even guaranteed to work by Posix?) + +def ismount(path): + """Test whether a path is a mount point""" + try: + s1 = os.lstat(path) + except OSError: + # It doesn't exist -- so not a mount point. :-) + return False + else: + # A symlink can never be a mount point + if stat.S_ISLNK(s1.st_mode): + return False + + if isinstance(path, bytes): + parent = join(path, b'..') + else: + parent = join(path, '..') + parent = realpath(parent) + try: + s2 = os.lstat(parent) + except OSError: + return False + + dev1 = s1.st_dev + dev2 = s2.st_dev + if dev1 != dev2: + return True # path/.. on a different device as path + ino1 = s1.st_ino + ino2 = s2.st_ino + if ino1 == ino2: + return True # path/.. is the same i-node as path + return False + + +# Expand paths beginning with '~' or '~user'. +# '~' means $HOME; '~user' means that user's home directory. +# If the path doesn't begin with '~', or if the user or $HOME is unknown, +# the path is returned unchanged (leaving error reporting to whatever +# function is called with the expanded path as argument). +# See also module 'glob' for expansion of *, ? and [...] in pathnames. +# (A function should also be defined to do full *sh-style environment +# variable expansion.) + +def expanduser(path): + """Expand ~ and ~user constructions. If user or $HOME is unknown, + do nothing.""" + path = os.fspath(path) + if isinstance(path, bytes): + tilde = b'~' + else: + tilde = '~' + if not path.startswith(tilde): + return path + sep = _get_sep(path) + i = path.find(sep, 1) + if i < 0: + i = len(path) + if i == 1: + if 'HOME' not in os.environ: + import pwd + userhome = pwd.getpwuid(os.getuid()).pw_dir + else: + userhome = os.environ['HOME'] + else: + import pwd + name = path[1:i] + if isinstance(name, bytes): + name = str(name, 'ASCII') + try: + pwent = pwd.getpwnam(name) + except KeyError: + return path + userhome = pwent.pw_dir + if isinstance(path, bytes): + userhome = os.fsencode(userhome) + root = b'/' + else: + root = '/' + userhome = userhome.rstrip(root) + return (userhome + path[i:]) or root + + +# Expand paths containing shell variable substitutions. +# This expands the forms $variable and ${variable} only. +# Non-existent variables are left unchanged. + +_varprog = None +_varprogb = None + +def expandvars(path): + """Expand shell variables of form $var and ${var}. Unknown variables + are left unchanged.""" + path = os.fspath(path) + global _varprog, _varprogb + if isinstance(path, bytes): + if b'$' not in path: + return path + if not _varprogb: + import re + _varprogb = re.compile(br'\$(\w+|\{[^}]*\})', re.ASCII) + search = _varprogb.search + start = b'{' + end = b'}' + environ = getattr(os, 'environb', None) + else: + if '$' not in path: + return path + if not _varprog: + import re + _varprog = re.compile(r'\$(\w+|\{[^}]*\})', re.ASCII) + search = _varprog.search + start = '{' + end = '}' + environ = os.environ + i = 0 + while True: + m = search(path, i) + if not m: + break + i, j = m.span(0) + name = m.group(1) + if name.startswith(start) and name.endswith(end): + name = name[1:-1] + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(name)]) + else: + value = environ[name] + except KeyError: + i = j + else: + tail = path[j:] + path = path[:i] + value + i = len(path) + path += tail + return path + + +# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. +# It should be understood that this may change the meaning of the path +# if it contains symbolic links! + +def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + path = os.fspath(path) + if isinstance(path, bytes): + sep = b'/' + empty = b'' + dot = b'.' + dotdot = b'..' + else: + sep = '/' + empty = '' + dot = '.' + dotdot = '..' + if path == empty: + return dot + initial_slashes = path.startswith(sep) + # POSIX allows one or two initial slashes, but treats three or more + # as single slash. + if (initial_slashes and + path.startswith(sep*2) and not path.startswith(sep*3)): + initial_slashes = 2 + comps = path.split(sep) + new_comps = [] + for comp in comps: + if comp in (empty, dot): + continue + if (comp != dotdot or (not initial_slashes and not new_comps) or + (new_comps and new_comps[-1] == dotdot)): + new_comps.append(comp) + elif new_comps: + new_comps.pop() + comps = new_comps + path = sep.join(comps) + if initial_slashes: + path = sep*initial_slashes + path + return path or dot + + +def abspath(path): + """Return an absolute path.""" + path = os.fspath(path) + if not isabs(path): + if isinstance(path, bytes): + cwd = os.getcwdb() + else: + cwd = os.getcwd() + path = join(cwd, path) + return normpath(path) + + +# Return a canonical path (i.e. the absolute location of a file on the +# filesystem). + +def realpath(filename): + """Return the canonical path of the specified filename, eliminating any +symbolic links encountered in the path.""" + filename = os.fspath(filename) + path, ok = _joinrealpath(filename[:0], filename, {}) + return abspath(path) + +# Join two paths, normalizing and eliminating any symbolic links +# encountered in the second path. +def _joinrealpath(path, rest, seen): + if isinstance(path, bytes): + sep = b'/' + curdir = b'.' + pardir = b'..' + else: + sep = '/' + curdir = '.' + pardir = '..' + + if isabs(rest): + rest = rest[1:] + path = sep + + while rest: + name, _, rest = rest.partition(sep) + if not name or name == curdir: + # current dir + continue + if name == pardir: + # parent dir + if path: + path, name = split(path) + if name == pardir: + path = join(path, pardir, pardir) + else: + path = pardir + continue + newpath = join(path, name) + if not islink(newpath): + path = newpath + continue + # Resolve the symbolic link + if newpath in seen: + # Already seen this path + path = seen[newpath] + if path is not None: + # use cached value + continue + # The symlink is not resolved, so we must have a symlink loop. + # Return already resolved part + rest of the path unchanged. + return join(newpath, rest), False + seen[newpath] = None # not resolved symlink + path, ok = _joinrealpath(path, os.readlink(newpath), seen) + if not ok: + return join(path, rest), False + seen[newpath] = path # resolved symlink + + return path, True + + +supports_unicode_filenames = (sys.platform == 'darwin') + +def relpath(path, start=None): + """Return a relative version of a path""" + + if not path: + raise ValueError("no path specified") + + path = os.fspath(path) + if isinstance(path, bytes): + curdir = b'.' + sep = b'/' + pardir = b'..' + else: + curdir = '.' + sep = '/' + pardir = '..' + + if start is None: + start = curdir + else: + start = os.fspath(start) + + try: + start_list = [x for x in abspath(start).split(sep) if x] + path_list = [x for x in abspath(path).split(sep) if x] + # Work out how much of the filepath is shared by start and path. + i = len(commonprefix([start_list, path_list])) + + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir + return join(*rel_list) + except (TypeError, AttributeError, BytesWarning, DeprecationWarning): + genericpath._check_arg_types('relpath', path, start) + raise + + +# Return the longest common sub-path of the sequence of paths given as input. +# The paths are not normalized before comparing them (this is the +# responsibility of the caller). Any trailing separator is stripped from the +# returned path. + +def commonpath(paths): + """Given a sequence of path names, returns the longest common sub-path.""" + + if not paths: + raise ValueError('commonpath() arg is an empty sequence') + + paths = tuple(map(os.fspath, paths)) + if isinstance(paths[0], bytes): + sep = b'/' + curdir = b'.' + else: + sep = '/' + curdir = '.' + + try: + split_paths = [path.split(sep) for path in paths] + + try: + isabs, = set(p[:1] == sep for p in paths) + except ValueError: + raise ValueError("Can't mix absolute and relative paths") from None + + split_paths = [[c for c in s if c and c != curdir] for s in split_paths] + s1 = min(split_paths) + s2 = max(split_paths) + common = s1 + for i, c in enumerate(s1): + if c != s2[i]: + common = s1[:i] + break + + prefix = sep if isabs else sep[:0] + return prefix + sep.join(common) + except (TypeError, AttributeError): + genericpath._check_arg_types('commonpath', *paths) + raise diff --git a/Lib/random.py b/Lib/random.py new file mode 100644 index 0000000..0bc2417 --- /dev/null +++ b/Lib/random.py @@ -0,0 +1,775 @@ +"""Random variable generators. + + integers + -------- + uniform within range + + sequences + --------- + pick random element + pick random sample + pick weighted random sample + generate random permutation + + distributions on the real line: + ------------------------------ + uniform + triangular + normal (Gaussian) + lognormal + negative exponential + gamma + beta + pareto + Weibull + + distributions on the circle (angles 0 to 2pi) + --------------------------------------------- + circular uniform + von Mises + +General notes on the underlying Mersenne Twister core generator: + +* The period is 2**19937-1. +* It is one of the most extensively tested generators in existence. +* The random() method is implemented in C, executes in a single Python step, + and is, therefore, threadsafe. + +""" + +from warnings import warn as _warn +from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType +from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil +from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin +from os import urandom as _urandom +from _collections_abc import Set as _Set, Sequence as _Sequence +from hashlib import sha512 as _sha512 +import itertools as _itertools +import bisect as _bisect +import os as _os + +__all__ = ["Random","seed","random","uniform","randint","choice","sample", + "randrange","shuffle","normalvariate","lognormvariate", + "expovariate","vonmisesvariate","gammavariate","triangular", + "gauss","betavariate","paretovariate","weibullvariate", + "getstate","setstate", "getrandbits", "choices", + "SystemRandom"] + +NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0) +TWOPI = 2.0*_pi +LOG4 = _log(4.0) +SG_MAGICCONST = 1.0 + _log(4.5) +BPF = 53 # Number of bits in a float +RECIP_BPF = 2**-BPF + + +# Translated by Guido van Rossum from C source provided by +# Adrian Baddeley. Adapted by Raymond Hettinger for use with +# the Mersenne Twister and os.urandom() core generators. + +import _random + +class Random(_random.Random): + """Random number generator base class used by bound module functions. + + Used to instantiate instances of Random to get generators that don't + share state. + + Class Random can also be subclassed if you want to use a different basic + generator of your own devising: in that case, override the following + methods: random(), seed(), getstate(), and setstate(). + Optionally, implement a getrandbits() method so that randrange() + can cover arbitrarily large ranges. + + """ + + VERSION = 3 # used by getstate/setstate + + def __init__(self, x=None): + """Initialize an instance. + + Optional argument x controls seeding, as for Random.seed(). + """ + + self.seed(x) + self.gauss_next = None + + def seed(self, a=None, version=2): + """Initialize internal state from hashable object. + + None or no argument seeds from current time or from an operating + system specific randomness source if available. + + If *a* is an int, all bits are used. + + For version 2 (the default), all of the bits are used if *a* is a str, + bytes, or bytearray. For version 1 (provided for reproducing random + sequences from older versions of Python), the algorithm for str and + bytes generates a narrower range of seeds. + + """ + + if version == 1 and isinstance(a, (str, bytes)): + a = a.decode('latin-1') if isinstance(a, bytes) else a + x = ord(a[0]) << 7 if a else 0 + for c in map(ord, a): + x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF + x ^= len(a) + a = -2 if x == -1 else x + + if version == 2 and isinstance(a, (str, bytes, bytearray)): + if isinstance(a, str): + a = a.encode() + a += _sha512(a).digest() + a = int.from_bytes(a, 'big') + + super().seed(a) + self.gauss_next = None + + def getstate(self): + """Return internal state; can be passed to setstate() later.""" + return self.VERSION, super().getstate(), self.gauss_next + + def setstate(self, state): + """Restore internal state from object returned by getstate().""" + version = state[0] + if version == 3: + version, internalstate, self.gauss_next = state + super().setstate(internalstate) + elif version == 2: + version, internalstate, self.gauss_next = state + # In version 2, the state was saved as signed ints, which causes + # inconsistencies between 32/64-bit systems. The state is + # really unsigned 32-bit ints, so we convert negative ints from + # version 2 to positive longs for version 3. + try: + internalstate = tuple(x % (2**32) for x in internalstate) + except ValueError as e: + raise TypeError from e + super().setstate(internalstate) + else: + raise ValueError("state with version %s passed to " + "Random.setstate() of version %s" % + (version, self.VERSION)) + +## ---- Methods below this point do not need to be overridden when +## ---- subclassing for the purpose of using a different core generator. + +## -------------------- pickle support ------------------- + + # Issue 17489: Since __reduce__ was defined to fix #759889 this is no + # longer called; we leave it here because it has been here since random was + # rewritten back in 2001 and why risk breaking something. + def __getstate__(self): # for pickle + return self.getstate() + + def __setstate__(self, state): # for pickle + self.setstate(state) + + def __reduce__(self): + return self.__class__, (), self.getstate() + +## -------------------- integer methods ------------------- + + def randrange(self, start, stop=None, step=1, _int=int): + """Choose a random item from range(start, stop[, step]). + + This fixes the problem with randint() which includes the + endpoint; in Python this is usually not what you want. + + """ + + # This code is a bit messy to make it fast for the + # common case while still doing adequate error checking. + istart = _int(start) + if istart != start: + raise ValueError("non-integer arg 1 for randrange()") + if stop is None: + if istart > 0: + return self._randbelow(istart) + raise ValueError("empty range for randrange()") + + # stop argument supplied. + istop = _int(stop) + if istop != stop: + raise ValueError("non-integer stop for randrange()") + width = istop - istart + if step == 1 and width > 0: + return istart + self._randbelow(width) + if step == 1: + raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width)) + + # Non-unit step argument supplied. + istep = _int(step) + if istep != step: + raise ValueError("non-integer step for randrange()") + if istep > 0: + n = (width + istep - 1) // istep + elif istep < 0: + n = (width + istep + 1) // istep + else: + raise ValueError("zero step for randrange()") + + if n <= 0: + raise ValueError("empty range for randrange()") + + return istart + istep*self._randbelow(n) + + def randint(self, a, b): + """Return random integer in range [a, b], including both end points. + """ + + return self.randrange(a, b+1) + + def _randbelow(self, n, int=int, maxsize=1<= n: + r = getrandbits(k) + return r + # There's an overridden random() method but no new getrandbits() method, + # so we can only use random() from here. + if n >= maxsize: + _warn("Underlying random() generator does not supply \n" + "enough bits to choose from a population range this large.\n" + "To remove the range limitation, add a getrandbits() method.") + return int(random() * n) + if n == 0: + raise ValueError("Boundary cannot be zero") + rem = maxsize % n + limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0 + r = random() + while r >= limit: + r = random() + return int(r*maxsize) % n + +## -------------------- sequence methods ------------------- + + def choice(self, seq): + """Choose a random element from a non-empty sequence.""" + try: + i = self._randbelow(len(seq)) + except ValueError: + raise IndexError('Cannot choose from an empty sequence') from None + return seq[i] + + def shuffle(self, x, random=None): + """Shuffle list x in place, and return None. + + Optional argument random is a 0-argument function returning a + random float in [0.0, 1.0); if it is the default None, the + standard random.random will be used. + + """ + + if random is None: + randbelow = self._randbelow + for i in reversed(range(1, len(x))): + # pick an element in x[:i+1] with which to exchange x[i] + j = randbelow(i+1) + x[i], x[j] = x[j], x[i] + else: + _int = int + for i in reversed(range(1, len(x))): + # pick an element in x[:i+1] with which to exchange x[i] + j = _int(random() * (i+1)) + x[i], x[j] = x[j], x[i] + + def sample(self, population, k): + """Chooses k unique random elements from a population sequence or set. + + Returns a new list containing elements from the population while + leaving the original population unchanged. The resulting list is + in selection order so that all sub-slices will also be valid random + samples. This allows raffle winners (the sample) to be partitioned + into grand prize and second place winners (the subslices). + + Members of the population need not be hashable or unique. If the + population contains repeats, then each occurrence is a possible + selection in the sample. + + To choose a sample in a range of integers, use range as an argument. + This is especially fast and space efficient for sampling from a + large population: sample(range(10000000), 60) + """ + + # Sampling without replacement entails tracking either potential + # selections (the pool) in a list or previous selections in a set. + + # When the number of selections is small compared to the + # population, then tracking selections is efficient, requiring + # only a small set and an occasional reselection. For + # a larger number of selections, the pool tracking method is + # preferred since the list takes less space than the + # set and it doesn't suffer from frequent reselections. + + if isinstance(population, _Set): + population = tuple(population) + if not isinstance(population, _Sequence): + raise TypeError("Population must be a sequence or set. For dicts, use list(d).") + randbelow = self._randbelow + n = len(population) + if not 0 <= k <= n: + raise ValueError("Sample larger than population or is negative") + result = [None] * k + setsize = 21 # size of a small set minus size of an empty list + if k > 5: + setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets + if n <= setsize: + # An n-length list is smaller than a k-length set + pool = list(population) + for i in range(k): # invariant: non-selected at [0,n-i) + j = randbelow(n-i) + result[i] = pool[j] + pool[j] = pool[n-i-1] # move non-selected item into vacancy + else: + selected = set() + selected_add = selected.add + for i in range(k): + j = randbelow(n) + while j in selected: + j = randbelow(n) + selected_add(j) + result[i] = population[j] + return result + + def choices(self, population, weights=None, *, cum_weights=None, k=1): + """Return a k sized list of population elements chosen with replacement. + + If the relative weights or cumulative weights are not specified, + the selections are made with equal probability. + + """ + random = self.random + if cum_weights is None: + if weights is None: + _int = int + total = len(population) + return [population[_int(random() * total)] for i in range(k)] + cum_weights = list(_itertools.accumulate(weights)) + elif weights is not None: + raise TypeError('Cannot specify both weights and cumulative weights') + if len(cum_weights) != len(population): + raise ValueError('The number of weights does not match the population') + bisect = _bisect.bisect + total = cum_weights[-1] + return [population[bisect(cum_weights, random() * total)] for i in range(k)] + +## -------------------- real-valued distributions ------------------- + +## -------------------- uniform distribution ------------------- + + def uniform(self, a, b): + "Get a random number in the range [a, b) or [a, b] depending on rounding." + return a + (b-a) * self.random() + +## -------------------- triangular -------------------- + + def triangular(self, low=0.0, high=1.0, mode=None): + """Triangular distribution. + + Continuous distribution bounded by given lower and upper limits, + and having a given mode value in-between. + + http://en.wikipedia.org/wiki/Triangular_distribution + + """ + u = self.random() + try: + c = 0.5 if mode is None else (mode - low) / (high - low) + except ZeroDivisionError: + return low + if u > c: + u = 1.0 - u + c = 1.0 - c + low, high = high, low + return low + (high - low) * _sqrt(u * c) + +## -------------------- normal distribution -------------------- + + def normalvariate(self, mu, sigma): + """Normal distribution. + + mu is the mean, and sigma is the standard deviation. + + """ + # mu = mean, sigma = standard deviation + + # Uses Kinderman and Monahan method. Reference: Kinderman, + # A.J. and Monahan, J.F., "Computer generation of random + # variables using the ratio of uniform deviates", ACM Trans + # Math Software, 3, (1977), pp257-260. + + random = self.random + while 1: + u1 = random() + u2 = 1.0 - random() + z = NV_MAGICCONST*(u1-0.5)/u2 + zz = z*z/4.0 + if zz <= -_log(u2): + break + return mu + z*sigma + +## -------------------- lognormal distribution -------------------- + + def lognormvariate(self, mu, sigma): + """Log normal distribution. + + If you take the natural logarithm of this distribution, you'll get a + normal distribution with mean mu and standard deviation sigma. + mu can have any value, and sigma must be greater than zero. + + """ + return _exp(self.normalvariate(mu, sigma)) + +## -------------------- exponential distribution -------------------- + + def expovariate(self, lambd): + """Exponential distribution. + + lambd is 1.0 divided by the desired mean. It should be + nonzero. (The parameter would be called "lambda", but that is + a reserved word in Python.) Returned values range from 0 to + positive infinity if lambd is positive, and from negative + infinity to 0 if lambd is negative. + + """ + # lambd: rate lambd = 1/mean + # ('lambda' is a Python reserved word) + + # we use 1-random() instead of random() to preclude the + # possibility of taking the log of zero. + return -_log(1.0 - self.random())/lambd + +## -------------------- von Mises distribution -------------------- + + def vonmisesvariate(self, mu, kappa): + """Circular data distribution. + + mu is the mean angle, expressed in radians between 0 and 2*pi, and + kappa is the concentration parameter, which must be greater than or + equal to zero. If kappa is equal to zero, this distribution reduces + to a uniform random angle over the range 0 to 2*pi. + + """ + # mu: mean angle (in radians between 0 and 2*pi) + # kappa: concentration parameter kappa (>= 0) + # if kappa = 0 generate uniform random angle + + # Based upon an algorithm published in: Fisher, N.I., + # "Statistical Analysis of Circular Data", Cambridge + # University Press, 1993. + + # Thanks to Magnus Kessler for a correction to the + # implementation of step 4. + + random = self.random + if kappa <= 1e-6: + return TWOPI * random() + + s = 0.5 / kappa + r = s + _sqrt(1.0 + s * s) + + while 1: + u1 = random() + z = _cos(_pi * u1) + + d = z / (r + z) + u2 = random() + if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d): + break + + q = 1.0 / r + f = (q + z) / (1.0 + q * z) + u3 = random() + if u3 > 0.5: + theta = (mu + _acos(f)) % TWOPI + else: + theta = (mu - _acos(f)) % TWOPI + + return theta + +## -------------------- gamma distribution -------------------- + + def gammavariate(self, alpha, beta): + """Gamma distribution. Not the gamma function! + + Conditions on the parameters are alpha > 0 and beta > 0. + + The probability distribution function is: + + x ** (alpha - 1) * math.exp(-x / beta) + pdf(x) = -------------------------------------- + math.gamma(alpha) * beta ** alpha + + """ + + # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 + + # Warning: a few older sources define the gamma distribution in terms + # of alpha > -1.0 + if alpha <= 0.0 or beta <= 0.0: + raise ValueError('gammavariate: alpha and beta must be > 0.0') + + random = self.random + if alpha > 1.0: + + # Uses R.C.H. Cheng, "The generation of Gamma + # variables with non-integral shape parameters", + # Applied Statistics, (1977), 26, No. 1, p71-74 + + ainv = _sqrt(2.0 * alpha - 1.0) + bbb = alpha - LOG4 + ccc = alpha + ainv + + while 1: + u1 = random() + if not 1e-7 < u1 < .9999999: + continue + u2 = 1.0 - random() + v = _log(u1/(1.0-u1))/ainv + x = alpha*_exp(v) + z = u1*u1*u2 + r = bbb+ccc*v-x + if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z): + return x * beta + + elif alpha == 1.0: + # expovariate(1/beta) + u = random() + while u <= 1e-7: + u = random() + return -_log(u) * beta + + else: # alpha is between 0 and 1 (exclusive) + + # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle + + while 1: + u = random() + b = (_e + alpha)/_e + p = b*u + if p <= 1.0: + x = p ** (1.0/alpha) + else: + x = -_log((b-p)/alpha) + u1 = random() + if p > 1.0: + if u1 <= x ** (alpha - 1.0): + break + elif u1 <= _exp(-x): + break + return x * beta + +## -------------------- Gauss (faster alternative) -------------------- + + def gauss(self, mu, sigma): + """Gaussian distribution. + + mu is the mean, and sigma is the standard deviation. This is + slightly faster than the normalvariate() function. + + Not thread-safe without a lock around calls. + + """ + + # When x and y are two variables from [0, 1), uniformly + # distributed, then + # + # cos(2*pi*x)*sqrt(-2*log(1-y)) + # sin(2*pi*x)*sqrt(-2*log(1-y)) + # + # are two *independent* variables with normal distribution + # (mu = 0, sigma = 1). + # (Lambert Meertens) + # (corrected version; bug discovered by Mike Miller, fixed by LM) + + # Multithreading note: When two threads call this function + # simultaneously, it is possible that they will receive the + # same return value. The window is very small though. To + # avoid this, you have to use a lock around all calls. (I + # didn't want to slow this down in the serial case by using a + # lock here.) + + random = self.random + z = self.gauss_next + self.gauss_next = None + if z is None: + x2pi = random() * TWOPI + g2rad = _sqrt(-2.0 * _log(1.0 - random())) + z = _cos(x2pi) * g2rad + self.gauss_next = _sin(x2pi) * g2rad + + return mu + z*sigma + +## -------------------- beta -------------------- +## See +## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html +## for Ivan Frohne's insightful analysis of why the original implementation: +## +## def betavariate(self, alpha, beta): +## # Discrete Event Simulation in C, pp 87-88. +## +## y = self.expovariate(alpha) +## z = self.expovariate(1.0/beta) +## return z/(y+z) +## +## was dead wrong, and how it probably got that way. + + def betavariate(self, alpha, beta): + """Beta distribution. + + Conditions on the parameters are alpha > 0 and beta > 0. + Returned values range between 0 and 1. + + """ + + # This version due to Janne Sinkkonen, and matches all the std + # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution"). + y = self.gammavariate(alpha, 1.0) + if y == 0: + return 0.0 + else: + return y / (y + self.gammavariate(beta, 1.0)) + +## -------------------- Pareto -------------------- + + def paretovariate(self, alpha): + """Pareto distribution. alpha is the shape parameter.""" + # Jain, pg. 495 + + u = 1.0 - self.random() + return 1.0 / u ** (1.0/alpha) + +## -------------------- Weibull -------------------- + + def weibullvariate(self, alpha, beta): + """Weibull distribution. + + alpha is the scale parameter and beta is the shape parameter. + + """ + # Jain, pg. 499; bug fix courtesy Bill Arms + + u = 1.0 - self.random() + return alpha * (-_log(u)) ** (1.0/beta) + +## --------------- Operating System Random Source ------------------ + +class SystemRandom(Random): + """Alternate random number generator using sources provided + by the operating system (such as /dev/urandom on Unix or + CryptGenRandom on Windows). + + Not available on all systems (see os.urandom() for details). + """ + + def random(self): + """Get the next random number in the range [0.0, 1.0).""" + return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF + + def getrandbits(self, k): + """getrandbits(k) -> x. Generates an int with k random bits.""" + if k <= 0: + raise ValueError('number of bits must be greater than zero') + if k != int(k): + raise TypeError('number of bits should be an integer') + numbytes = (k + 7) // 8 # bits / 8 and rounded up + x = int.from_bytes(_urandom(numbytes), 'big') + return x >> (numbytes * 8 - k) # trim excess bits + + def seed(self, *args, **kwds): + "Stub method. Not used for a system random number generator." + return None + + def _notimplemented(self, *args, **kwds): + "Method should not be called for a system random number generator." + raise NotImplementedError('System entropy source does not have state.') + getstate = setstate = _notimplemented + +## -------------------- test program -------------------- + +def _test_generator(n, func, args): + import time + print(n, 'times', func.__name__) + total = 0.0 + sqsum = 0.0 + smallest = 1e10 + largest = -1e10 + t0 = time.time() + for i in range(n): + x = func(*args) + total += x + sqsum = sqsum + x*x + smallest = min(x, smallest) + largest = max(x, largest) + t1 = time.time() + print(round(t1-t0, 3), 'sec,', end=' ') + avg = total/n + stddev = _sqrt(sqsum/n - avg*avg) + print('avg %g, stddev %g, min %g, max %g\n' % \ + (avg, stddev, smallest, largest)) + + +def _test(N=2000): + _test_generator(N, random, ()) + _test_generator(N, normalvariate, (0.0, 1.0)) + _test_generator(N, lognormvariate, (0.0, 1.0)) + _test_generator(N, vonmisesvariate, (0.0, 1.0)) + _test_generator(N, gammavariate, (0.01, 1.0)) + _test_generator(N, gammavariate, (0.1, 1.0)) + _test_generator(N, gammavariate, (0.1, 2.0)) + _test_generator(N, gammavariate, (0.5, 1.0)) + _test_generator(N, gammavariate, (0.9, 1.0)) + _test_generator(N, gammavariate, (1.0, 1.0)) + _test_generator(N, gammavariate, (2.0, 1.0)) + _test_generator(N, gammavariate, (20.0, 1.0)) + _test_generator(N, gammavariate, (200.0, 1.0)) + _test_generator(N, gauss, (0.0, 1.0)) + _test_generator(N, betavariate, (3.0, 3.0)) + _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0)) + +# Create one instance, seeded from current time, and export its methods +# as module-level functions. The functions share state across all uses +#(both in the user's code and in the Python libraries), but that's fine +# for most programs and is easier for the casual user than making them +# instantiate their own Random() instance. + +_inst = Random() +seed = _inst.seed +random = _inst.random +uniform = _inst.uniform +triangular = _inst.triangular +randint = _inst.randint +choice = _inst.choice +randrange = _inst.randrange +sample = _inst.sample +shuffle = _inst.shuffle +choices = _inst.choices +normalvariate = _inst.normalvariate +lognormvariate = _inst.lognormvariate +expovariate = _inst.expovariate +vonmisesvariate = _inst.vonmisesvariate +gammavariate = _inst.gammavariate +gauss = _inst.gauss +betavariate = _inst.betavariate +paretovariate = _inst.paretovariate +weibullvariate = _inst.weibullvariate +getstate = _inst.getstate +setstate = _inst.setstate +getrandbits = _inst.getrandbits + +if hasattr(_os, "fork"): + _os.register_at_fork(after_in_child=_inst.seed) + + +if __name__ == '__main__': + _test() diff --git a/Lib/re.py b/Lib/re.py new file mode 100644 index 0000000..94d4865 --- /dev/null +++ b/Lib/re.py @@ -0,0 +1,366 @@ +# +# Secret Labs' Regular Expression Engine +# +# re-compatible interface for the sre matching engine +# +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. +# +# This version of the SRE library can be redistributed under CNRI's +# Python 1.6 license. For any other use, please contact Secret Labs +# AB (info@pythonware.com). +# +# Portions of this engine have been developed in cooperation with +# CNRI. Hewlett-Packard provided funding for 1.6 integration and +# other compatibility work. +# + +r"""Support for regular expressions (RE). + +This module provides regular expression matching operations similar to +those found in Perl. It supports both 8-bit and Unicode strings; both +the pattern and the strings being processed can contain null bytes and +characters outside the US ASCII range. + +Regular expressions can contain both special and ordinary characters. +Most ordinary characters, like "A", "a", or "0", are the simplest +regular expressions; they simply match themselves. You can +concatenate ordinary characters, so last matches the string 'last'. + +The special characters are: + "." Matches any character except a newline. + "^" Matches the start of the string. + "$" Matches the end of the string or just before the newline at + the end of the string. + "*" Matches 0 or more (greedy) repetitions of the preceding RE. + Greedy means that it will match as many repetitions as possible. + "+" Matches 1 or more (greedy) repetitions of the preceding RE. + "?" Matches 0 or 1 (greedy) of the preceding RE. + *?,+?,?? Non-greedy versions of the previous three special characters. + {m,n} Matches from m to n repetitions of the preceding RE. + {m,n}? Non-greedy version of the above. + "\\" Either escapes special characters or signals a special sequence. + [] Indicates a set of characters. + A "^" as the first character indicates a complementing set. + "|" A|B, creates an RE that will match either A or B. + (...) Matches the RE inside the parentheses. + The contents can be retrieved or matched later in the string. + (?aiLmsux) Set the A, I, L, M, S, U, or X flag for the RE (see below). + (?:...) Non-grouping version of regular parentheses. + (?P...) The substring matched by the group is accessible by name. + (?P=name) Matches the text matched earlier by the group named name. + (?#...) A comment; ignored. + (?=...) Matches if ... matches next, but doesn't consume the string. + (?!...) Matches if ... doesn't match next. + (?<=...) Matches if preceded by ... (must be fixed length). + (?= _MAXCACHE: + # Drop the oldest item + try: + del _cache[next(iter(_cache))] + except (StopIteration, RuntimeError, KeyError): + pass + _cache[type(pattern), pattern, flags] = p + return p + +@functools.lru_cache(_MAXCACHE) +def _compile_repl(repl, pattern): + # internal: compile replacement pattern + return sre_parse.parse_template(repl, pattern) + +def _expand(pattern, match, template): + # internal: Match.expand implementation hook + template = sre_parse.parse_template(template, pattern) + return sre_parse.expand_template(template, match) + +def _subx(pattern, template): + # internal: Pattern.sub/subn implementation helper + template = _compile_repl(template, pattern) + if not template[0] and len(template[1]) == 1: + # literal replacement + return template[1][0] + def filter(match, template=template): + return sre_parse.expand_template(template, match) + return filter + +# register myself for pickling + +import copyreg + +def _pickle(p): + return _compile, (p.pattern, p.flags) + +copyreg.pickle(Pattern, _pickle, _compile) + +# -------------------------------------------------------------------- +# experimental stuff (see python-dev discussions for details) + +class Scanner: + def __init__(self, lexicon, flags=0): + from sre_constants import BRANCH, SUBPATTERN + if isinstance(flags, RegexFlag): + flags = flags.value + self.lexicon = lexicon + # combine phrases into a compound pattern + p = [] + s = sre_parse.Pattern() + s.flags = flags + for phrase, action in lexicon: + gid = s.opengroup() + p.append(sre_parse.SubPattern(s, [ + (SUBPATTERN, (gid, 0, 0, sre_parse.parse(phrase, flags))), + ])) + s.closegroup(gid, p[-1]) + p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) + self.scanner = sre_compile.compile(p) + def scan(self, string): + result = [] + append = result.append + match = self.scanner.scanner(string).match + i = 0 + while True: + m = match() + if not m: + break + j = m.end() + if i == j: + break + action = self.lexicon[m.lastindex-1][1] + if callable(action): + self.match = m + action = action(self, m.group()) + if action is not None: + append(action) + i = j + return result, string[i:] diff --git a/Lib/reprlib.py b/Lib/reprlib.py new file mode 100644 index 0000000..616b343 --- /dev/null +++ b/Lib/reprlib.py @@ -0,0 +1,161 @@ +"""Redo the builtin repr() (representation) but with limits on most sizes.""" + +__all__ = ["Repr", "repr", "recursive_repr"] + +import builtins +from itertools import islice +from _thread import get_ident + +def recursive_repr(fillvalue='...'): + 'Decorator to make a repr function return fillvalue for a recursive call' + + def decorating_function(user_function): + repr_running = set() + + def wrapper(self): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + result = user_function(self) + finally: + repr_running.discard(key) + return result + + # Can't use functools.wraps() here because of bootstrap issues + wrapper.__module__ = getattr(user_function, '__module__') + wrapper.__doc__ = getattr(user_function, '__doc__') + wrapper.__name__ = getattr(user_function, '__name__') + wrapper.__qualname__ = getattr(user_function, '__qualname__') + wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + return wrapper + + return decorating_function + +class Repr: + + def __init__(self): + self.maxlevel = 6 + self.maxtuple = 6 + self.maxlist = 6 + self.maxarray = 5 + self.maxdict = 4 + self.maxset = 6 + self.maxfrozenset = 6 + self.maxdeque = 6 + self.maxstring = 30 + self.maxlong = 40 + self.maxother = 30 + + def repr(self, x): + return self.repr1(x, self.maxlevel) + + def repr1(self, x, level): + typename = type(x).__name__ + if ' ' in typename: + parts = typename.split() + typename = '_'.join(parts) + if hasattr(self, 'repr_' + typename): + return getattr(self, 'repr_' + typename)(x, level) + else: + return self.repr_instance(x, level) + + def _repr_iterable(self, x, level, left, right, maxiter, trail=''): + n = len(x) + if level <= 0 and n: + s = '...' + else: + newlevel = level - 1 + repr1 = self.repr1 + pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] + if n > maxiter: pieces.append('...') + s = ', '.join(pieces) + if n == 1 and trail: right = trail + right + return '%s%s%s' % (left, s, right) + + def repr_tuple(self, x, level): + return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',') + + def repr_list(self, x, level): + return self._repr_iterable(x, level, '[', ']', self.maxlist) + + def repr_array(self, x, level): + if not x: + return "array('%s')" % x.typecode + header = "array('%s', [" % x.typecode + return self._repr_iterable(x, level, header, '])', self.maxarray) + + def repr_set(self, x, level): + if not x: + return 'set()' + x = _possibly_sorted(x) + return self._repr_iterable(x, level, '{', '}', self.maxset) + + def repr_frozenset(self, x, level): + if not x: + return 'frozenset()' + x = _possibly_sorted(x) + return self._repr_iterable(x, level, 'frozenset({', '})', + self.maxfrozenset) + + def repr_deque(self, x, level): + return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque) + + def repr_dict(self, x, level): + n = len(x) + if n == 0: return '{}' + if level <= 0: return '{...}' + newlevel = level - 1 + repr1 = self.repr1 + pieces = [] + for key in islice(_possibly_sorted(x), self.maxdict): + keyrepr = repr1(key, newlevel) + valrepr = repr1(x[key], newlevel) + pieces.append('%s: %s' % (keyrepr, valrepr)) + if n > self.maxdict: pieces.append('...') + s = ', '.join(pieces) + return '{%s}' % (s,) + + def repr_str(self, x, level): + s = builtins.repr(x[:self.maxstring]) + if len(s) > self.maxstring: + i = max(0, (self.maxstring-3)//2) + j = max(0, self.maxstring-3-i) + s = builtins.repr(x[:i] + x[len(x)-j:]) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def repr_int(self, x, level): + s = builtins.repr(x) # XXX Hope this isn't too slow... + if len(s) > self.maxlong: + i = max(0, (self.maxlong-3)//2) + j = max(0, self.maxlong-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def repr_instance(self, x, level): + try: + s = builtins.repr(x) + # Bugs in x.__repr__() can cause arbitrary + # exceptions -- then make up something + except Exception: + return '<%s instance at %#x>' % (x.__class__.__name__, id(x)) + if len(s) > self.maxother: + i = max(0, (self.maxother-3)//2) + j = max(0, self.maxother-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + +def _possibly_sorted(x): + # Since not all sequences of items can be sorted and comparison + # functions may raise arbitrary exceptions, return an unsorted + # sequence in that case. + try: + return sorted(x) + except Exception: + return list(x) + +aRepr = Repr() +repr = aRepr.repr diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py new file mode 100644 index 0000000..bca4a7b --- /dev/null +++ b/Lib/rlcompleter.py @@ -0,0 +1,205 @@ +"""Word completion for GNU readline. + +The completer completes keywords, built-ins and globals in a selectable +namespace (which defaults to __main__); when completing NAME.NAME..., it +evaluates (!) the expression up to the last dot and completes its attributes. + +It's very cool to do "import sys" type "sys.", hit the completion key (twice), +and see the list of names defined by the sys module! + +Tip: to use the tab key as the completion key, call + + readline.parse_and_bind("tab: complete") + +Notes: + +- Exceptions raised by the completer function are *ignored* (and generally cause + the completion to fail). This is a feature -- since readline sets the tty + device in raw (or cbreak) mode, printing a traceback wouldn't work well + without some complicated hoopla to save, reset and restore the tty state. + +- The evaluation of the NAME.NAME... form may cause arbitrary application + defined code to be executed if an object with a __getattr__ hook is found. + Since it is the responsibility of the application (or the user) to enable this + feature, I consider this an acceptable risk. More complicated expressions + (e.g. function calls or indexing operations) are *not* evaluated. + +- When the original stdin is not a tty device, GNU readline is never + used, and this module (and the readline module) are silently inactive. + +""" + +import atexit +import builtins +import __main__ + +__all__ = ["Completer"] + +class Completer: + def __init__(self, namespace = None): + """Create a new completer for the command line. + + Completer([namespace]) -> completer instance. + + If unspecified, the default namespace where completions are performed + is __main__ (technically, __main__.__dict__). Namespaces should be + given as dictionaries. + + Completer instances should be used as the completion mechanism of + readline via the set_completer() call: + + readline.set_completer(Completer(my_namespace).complete) + """ + + if namespace and not isinstance(namespace, dict): + raise TypeError('namespace must be a dictionary') + + # Don't bind to namespace quite yet, but flag whether the user wants a + # specific namespace or to use __main__.__dict__. This will allow us + # to bind to __main__.__dict__ at completion time, not now. + if namespace is None: + self.use_main_ns = 1 + else: + self.use_main_ns = 0 + self.namespace = namespace + + def complete(self, text, state): + """Return the next possible completion for 'text'. + + This is called successively with state == 0, 1, 2, ... until it + returns None. The completion should begin with 'text'. + + """ + if self.use_main_ns: + self.namespace = __main__.__dict__ + + if not text.strip(): + if state == 0: + if _readline_available: + readline.insert_text('\t') + readline.redisplay() + return '' + else: + return '\t' + else: + return None + + if state == 0: + if "." in text: + self.matches = self.attr_matches(text) + else: + self.matches = self.global_matches(text) + try: + return self.matches[state] + except IndexError: + return None + + def _callable_postfix(self, val, word): + if callable(val): + word = word + "(" + return word + + def global_matches(self, text): + """Compute matches when text is a simple name. + + Return a list of all keywords, built-in functions and names currently + defined in self.namespace that match. + + """ + import keyword + matches = [] + seen = {"__builtins__"} + n = len(text) + for word in keyword.kwlist: + if word[:n] == text: + seen.add(word) + if word in {'finally', 'try'}: + word = word + ':' + elif word not in {'False', 'None', 'True', + 'break', 'continue', 'pass', + 'else'}: + word = word + ' ' + matches.append(word) + for nspace in [self.namespace, builtins.__dict__]: + for word, val in nspace.items(): + if word[:n] == text and word not in seen: + seen.add(word) + matches.append(self._callable_postfix(val, word)) + return matches + + def attr_matches(self, text): + """Compute matches when text contains a dot. + + Assuming the text is of the form NAME.NAME....[NAME], and is + evaluable in self.namespace, it will be evaluated and its attributes + (as revealed by dir()) are used as possible completions. (For class + instances, class members are also considered.) + + WARNING: this can still invoke arbitrary C code, if an object + with a __getattr__ hook is evaluated. + + """ + import re + m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) + if not m: + return [] + expr, attr = m.group(1, 3) + try: + thisobject = eval(expr, self.namespace) + except Exception: + return [] + + # get the content of the object, except __builtins__ + words = set(dir(thisobject)) + words.discard("__builtins__") + + if hasattr(thisobject, '__class__'): + words.add('__class__') + words.update(get_class_members(thisobject.__class__)) + matches = [] + n = len(attr) + if attr == '': + noprefix = '_' + elif attr == '_': + noprefix = '__' + else: + noprefix = None + while True: + for word in words: + if (word[:n] == attr and + not (noprefix and word[:n+1] == noprefix)): + match = "%s.%s" % (expr, word) + try: + val = getattr(thisobject, word) + except Exception: + pass # Include even if attribute not set + else: + match = self._callable_postfix(val, match) + matches.append(match) + if matches or not noprefix: + break + if noprefix == '_': + noprefix = '__' + else: + noprefix = None + matches.sort() + return matches + +def get_class_members(klass): + ret = dir(klass) + if hasattr(klass,'__bases__'): + for base in klass.__bases__: + ret = ret + get_class_members(base) + return ret + +try: + import readline +except ImportError: + _readline_available = False +else: + readline.set_completer(Completer().complete) + # Release references early at shutdown (the readline module's + # contents are quasi-immortal, and the completer function holds a + # reference to globals). + atexit.register(lambda: readline.set_completer(None)) + _readline_available = True diff --git a/Lib/shutil.py b/Lib/shutil.py new file mode 100644 index 0000000..3c02776 --- /dev/null +++ b/Lib/shutil.py @@ -0,0 +1,1169 @@ +"""Utility functions for copying and archiving files and directory trees. + +XXX The functions here don't copy the resource fork or other metadata on Mac. + +""" + +import os +import sys +import stat +import fnmatch +import collections +import errno + +try: + import zlib + del zlib + _ZLIB_SUPPORTED = True +except ImportError: + _ZLIB_SUPPORTED = False + +try: + import bz2 + del bz2 + _BZ2_SUPPORTED = True +except ImportError: + _BZ2_SUPPORTED = False + +try: + import lzma + del lzma + _LZMA_SUPPORTED = True +except ImportError: + _LZMA_SUPPORTED = False + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", + "copytree", "move", "rmtree", "Error", "SpecialFileError", + "ExecError", "make_archive", "get_archive_formats", + "register_archive_format", "unregister_archive_format", + "get_unpack_formats", "register_unpack_format", + "unregister_unpack_format", "unpack_archive", + "ignore_patterns", "chown", "which", "get_terminal_size", + "SameFileError"] + # disk_usage is added later, if available on the platform + +class Error(OSError): + pass + +class SameFileError(Error): + """Raised when source and destination are the same file.""" + +class SpecialFileError(OSError): + """Raised when trying to do a kind of operation (e.g. copying) which is + not supported on a special file (e.g. a named pipe)""" + +class ExecError(OSError): + """Raised when a command could not be executed""" + +class ReadError(OSError): + """Raised when an archive cannot be read""" + +class RegistryError(Exception): + """Raised when a registry operation with the archiving + and unpacking registries fails""" + + +def copyfileobj(fsrc, fdst, length=16*1024): + """copy data from file-like object fsrc to file-like object fdst""" + while 1: + buf = fsrc.read(length) + if not buf: + break + fdst.write(buf) + +def _samefile(src, dst): + # Macintosh, Unix. + if hasattr(os.path, 'samefile'): + try: + return os.path.samefile(src, dst) + except OSError: + return False + + # All other platforms: check for same pathname. + return (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + +def copyfile(src, dst, *, follow_symlinks=True): + """Copy data from src to dst. + + If follow_symlinks is not set and src is a symbolic link, a new + symlink will be created instead of copying the file it points to. + + """ + if _samefile(src, dst): + raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) + + for fn in [src, dst]: + try: + st = os.stat(fn) + except OSError: + # File most likely does not exist + pass + else: + # XXX What about other special files? (sockets, devices...) + if stat.S_ISFIFO(st.st_mode): + raise SpecialFileError("`%s` is a named pipe" % fn) + + if not follow_symlinks and os.path.islink(src): + os.symlink(os.readlink(src), dst) + else: + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + return dst + +def copymode(src, dst, *, follow_symlinks=True): + """Copy mode bits from src to dst. + + If follow_symlinks is not set, symlinks aren't followed if and only + if both `src` and `dst` are symlinks. If `lchmod` isn't available + (e.g. Linux) this method does nothing. + + """ + if not follow_symlinks and os.path.islink(src) and os.path.islink(dst): + if hasattr(os, 'lchmod'): + stat_func, chmod_func = os.lstat, os.lchmod + else: + return + elif hasattr(os, 'chmod'): + stat_func, chmod_func = os.stat, os.chmod + else: + return + + st = stat_func(src) + chmod_func(dst, stat.S_IMODE(st.st_mode)) + +if hasattr(os, 'listxattr'): + def _copyxattr(src, dst, *, follow_symlinks=True): + """Copy extended filesystem attributes from `src` to `dst`. + + Overwrite existing attributes. + + If `follow_symlinks` is false, symlinks won't be followed. + + """ + + try: + names = os.listxattr(src, follow_symlinks=follow_symlinks) + except OSError as e: + if e.errno not in (errno.ENOTSUP, errno.ENODATA): + raise + return + for name in names: + try: + value = os.getxattr(src, name, follow_symlinks=follow_symlinks) + os.setxattr(dst, name, value, follow_symlinks=follow_symlinks) + except OSError as e: + if e.errno not in (errno.EPERM, errno.ENOTSUP, errno.ENODATA): + raise +else: + def _copyxattr(*args, **kwargs): + pass + +def copystat(src, dst, *, follow_symlinks=True): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst. + + If the optional flag `follow_symlinks` is not set, symlinks aren't followed if and + only if both `src` and `dst` are symlinks. + + """ + def _nop(*args, ns=None, follow_symlinks=None): + pass + + # follow symlinks (aka don't not follow symlinks) + follow = follow_symlinks or not (os.path.islink(src) and os.path.islink(dst)) + if follow: + # use the real function if it exists + def lookup(name): + return getattr(os, name, _nop) + else: + # use the real function only if it exists + # *and* it supports follow_symlinks + def lookup(name): + fn = getattr(os, name, _nop) + if fn in os.supports_follow_symlinks: + return fn + return _nop + + st = lookup("stat")(src, follow_symlinks=follow) + mode = stat.S_IMODE(st.st_mode) + lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns), + follow_symlinks=follow) + try: + lookup("chmod")(dst, mode, follow_symlinks=follow) + except NotImplementedError: + # if we got a NotImplementedError, it's because + # * follow_symlinks=False, + # * lchown() is unavailable, and + # * either + # * fchownat() is unavailable or + # * fchownat() doesn't implement AT_SYMLINK_NOFOLLOW. + # (it returned ENOSUP.) + # therefore we're out of options--we simply cannot chown the + # symlink. give up, suppress the error. + # (which is what shutil always did in this circumstance.) + pass + if hasattr(st, 'st_flags'): + try: + lookup("chflags")(dst, st.st_flags, follow_symlinks=follow) + except OSError as why: + for err in 'EOPNOTSUPP', 'ENOTSUP': + if hasattr(errno, err) and why.errno == getattr(errno, err): + break + else: + raise + _copyxattr(src, dst, follow_symlinks=follow) + +def copy(src, dst, *, follow_symlinks=True): + """Copy data and mode bits ("cp src dst"). Return the file's destination. + + The destination may be a directory. + + If follow_symlinks is false, symlinks won't be followed. This + resembles GNU's "cp -P src dst". + + If source and destination are the same file, a SameFileError will be + raised. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst, follow_symlinks=follow_symlinks) + copymode(src, dst, follow_symlinks=follow_symlinks) + return dst + +def copy2(src, dst, *, follow_symlinks=True): + """Copy data and all stat info ("cp -p src dst"). Return the file's + destination." + + The destination may be a directory. + + If follow_symlinks is false, symlinks won't be followed. This + resembles GNU's "cp -P src dst". + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst, follow_symlinks=follow_symlinks) + copystat(src, dst, follow_symlinks=follow_symlinks) + return dst + +def ignore_patterns(*patterns): + """Function that can be used as copytree() ignore parameter. + + Patterns is a sequence of glob-style patterns + that are used to exclude files""" + def _ignore_patterns(path, names): + ignored_names = [] + for pattern in patterns: + ignored_names.extend(fnmatch.filter(names, pattern)) + return set(ignored_names) + return _ignore_patterns + +def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks=False): + """Recursively copy a directory tree. + + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. If the file pointed by the symlink doesn't + exist, an exception will be added in the list of errors raised in + an Error exception at the end of the copy process. + + You can set the optional ignore_dangling_symlinks flag to true if you + want to silence this exception. Notice that this has no effect on + platforms that don't support os.symlink. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + The optional copy_function argument is a callable that will be used + to copy each file. It will be called with the source path and the + destination path as arguments. By default, copy2() is used, but any + function that supports the same signature (like copy()) can be used. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.islink(srcname): + linkto = os.readlink(srcname) + if symlinks: + # We can't just leave it to `copy_function` because legacy + # code with a custom `copy_function` may rely on copytree + # doing the right thing. + os.symlink(linkto, dstname) + copystat(srcname, dstname, follow_symlinks=not symlinks) + else: + # ignore dangling symlink if the flag is on + if not os.path.exists(linkto) and ignore_dangling_symlinks: + continue + # otherwise let the copy occurs. copy2 will raise an error + if os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, + copy_function) + else: + copy_function(srcname, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, copy_function) + else: + # Will raise a SpecialFileError for unsupported file types + copy_function(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error as err: + errors.extend(err.args[0]) + except OSError as why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError as why: + # Copying file access times may fail on Windows + if getattr(why, 'winerror', None) is None: + errors.append((src, dst, str(why))) + if errors: + raise Error(errors) + return dst + +# version vulnerable to race conditions +def _rmtree_unsafe(path, onerror): + try: + with os.scandir(path) as scandir_it: + entries = list(scandir_it) + except OSError: + onerror(os.scandir, path, sys.exc_info()) + entries = [] + for entry in entries: + fullname = entry.path + try: + is_dir = entry.is_dir(follow_symlinks=False) + except OSError: + is_dir = False + if is_dir: + try: + if entry.is_symlink(): + # This can only happen if someone replaces + # a directory with a symlink after the call to + # os.scandir or entry.is_dir above. + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, fullname, sys.exc_info()) + continue + _rmtree_unsafe(fullname, onerror) + else: + try: + os.unlink(fullname) + except OSError: + onerror(os.unlink, fullname, sys.exc_info()) + try: + os.rmdir(path) + except OSError: + onerror(os.rmdir, path, sys.exc_info()) + +# Version using fd-based APIs to protect against races +def _rmtree_safe_fd(topfd, path, onerror): + try: + with os.scandir(topfd) as scandir_it: + entries = list(scandir_it) + except OSError as err: + err.filename = path + onerror(os.scandir, path, sys.exc_info()) + return + for entry in entries: + fullname = os.path.join(path, entry.name) + try: + is_dir = entry.is_dir(follow_symlinks=False) + if is_dir: + orig_st = entry.stat(follow_symlinks=False) + is_dir = stat.S_ISDIR(orig_st.st_mode) + except OSError: + is_dir = False + if is_dir: + try: + dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd) + except OSError: + onerror(os.open, fullname, sys.exc_info()) + else: + try: + if os.path.samestat(orig_st, os.fstat(dirfd)): + _rmtree_safe_fd(dirfd, fullname, onerror) + try: + os.rmdir(entry.name, dir_fd=topfd) + except OSError: + onerror(os.rmdir, fullname, sys.exc_info()) + else: + try: + # This can only happen if someone replaces + # a directory with a symlink after the call to + # os.scandir or stat.S_ISDIR above. + raise OSError("Cannot call rmtree on a symbolic " + "link") + except OSError: + onerror(os.path.islink, fullname, sys.exc_info()) + finally: + os.close(dirfd) + else: + try: + os.unlink(entry.name, dir_fd=topfd) + except OSError: + onerror(os.unlink, fullname, sys.exc_info()) + +_use_fd_functions = ({os.open, os.stat, os.unlink, os.rmdir} <= + os.supports_dir_fd and + os.scandir in os.supports_fd and + os.stat in os.supports_follow_symlinks) + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is platform and implementation dependent; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + if _use_fd_functions: + # While the unsafe rmtree works fine on bytes, the fd based does not. + if isinstance(path, bytes): + path = os.fsdecode(path) + # Note: To guard against symlink races, we use the standard + # lstat()/open()/fstat() trick. + try: + orig_st = os.lstat(path) + except Exception: + onerror(os.lstat, path, sys.exc_info()) + return + try: + fd = os.open(path, os.O_RDONLY) + except Exception: + onerror(os.lstat, path, sys.exc_info()) + return + try: + if os.path.samestat(orig_st, os.fstat(fd)): + _rmtree_safe_fd(fd, path, onerror) + try: + os.rmdir(path) + except OSError: + onerror(os.rmdir, path, sys.exc_info()) + else: + try: + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + finally: + os.close(fd) + else: + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return + return _rmtree_unsafe(path, onerror) + +# Allow introspection of whether or not the hardening against symlink +# attacks is supported on the current platform +rmtree.avoids_symlink_attacks = _use_fd_functions + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + sep = os.path.sep + (os.path.altsep or '') + return os.path.basename(path.rstrip(sep)) + +def move(src, dst, copy_function=copy2): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. Return the file or directory's + destination. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. Symlinks are + recreated under the new name if os.rename() fails because of cross + filesystem renames. + + The optional `copy_function` argument is a callable that will be used + to copy the source or it will be delegated to `copytree`. + By default, copy2() is used, but any function that supports the same + signature (like copy()) can be used. + + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error("Destination path '%s' already exists" % real_dst) + try: + os.rename(src, real_dst) + except OSError: + if os.path.islink(src): + linkto = os.readlink(src) + os.symlink(linkto, real_dst) + os.unlink(src) + elif os.path.isdir(src): + if _destinsrc(src, dst): + raise Error("Cannot move a directory '%s' into itself" + " '%s'." % (src, dst)) + copytree(src, real_dst, copy_function=copy_function, + symlinks=True) + rmtree(src) + else: + copy_function(src, real_dst) + os.unlink(src) + return real_dst + +def _destinsrc(src, dst): + src = os.path.abspath(src) + dst = os.path.abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", "xz", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", ".bz2", or ".xz"). + + Returns the output filename. + """ + if compress is None: + tar_compression = '' + elif _ZLIB_SUPPORTED and compress == 'gzip': + tar_compression = 'gz' + elif _BZ2_SUPPORTED and compress == 'bzip2': + tar_compression = 'bz2' + elif _LZMA_SUPPORTED and compress == 'xz': + tar_compression = 'xz' + else: + raise ValueError("bad value for 'compress', or compression format not " + "supported : {0}".format(compress)) + + import tarfile # late import for breaking circular dependency + + compress_ext = '.' + tar_compression if compress else '' + archive_name = base_name + '.tar' + compress_ext + archive_dir = os.path.dirname(archive_name) + + if archive_dir and not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # creating the tarball + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Returns the + name of the output zip file. + """ + import zipfile # late import for breaking circular dependency + + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if archive_dir and not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + with zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) as zf: + path = os.path.normpath(base_dir) + if path != os.curdir: + zf.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in sorted(dirnames): + path = os.path.normpath(os.path.join(dirpath, name)) + zf.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zf.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + + return zip_filename + +_ARCHIVE_FORMATS = { + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), +} + +if _ZLIB_SUPPORTED: + _ARCHIVE_FORMATS['gztar'] = (_make_tarball, [('compress', 'gzip')], + "gzip'ed tar-file") + _ARCHIVE_FORMATS['zip'] = (_make_zipfile, [], "ZIP file") + +if _BZ2_SUPPORTED: + _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], + "bzip2'ed tar-file") + +if _LZMA_SUPPORTED: + _ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')], + "xz'ed tar-file") + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not callable(function): + raise TypeError('The %s object is not callable' % function) + if not isinstance(extra_args, (tuple, list)): + raise TypeError('extra_args needs to be a sequence') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2: + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "gztar", + "bztar", or "xztar". Or any other registered format. + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError("unknown archive format '%s'" % format) from None + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + + +def get_unpack_formats(): + """Returns a list of supported formats for unpacking. + + Each element of the returned sequence is a tuple + (name, extensions, description) + """ + formats = [(name, info[0], info[3]) for name, info in + _UNPACK_FORMATS.items()] + formats.sort() + return formats + +def _check_unpack_options(extensions, function, extra_args): + """Checks what gets registered as an unpacker.""" + # first make sure no other unpacker is registered for this extension + existing_extensions = {} + for name, info in _UNPACK_FORMATS.items(): + for ext in info[0]: + existing_extensions[ext] = name + + for extension in extensions: + if extension in existing_extensions: + msg = '%s is already registered for "%s"' + raise RegistryError(msg % (extension, + existing_extensions[extension])) + + if not callable(function): + raise TypeError('The registered function must be a callable') + + +def register_unpack_format(name, extensions, function, extra_args=None, + description=''): + """Registers an unpack format. + + `name` is the name of the format. `extensions` is a list of extensions + corresponding to the format. + + `function` is the callable that will be + used to unpack archives. The callable will receive archives to unpack. + If it's unable to handle an archive, it needs to raise a ReadError + exception. + + If provided, `extra_args` is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_unpack_formats() function. + """ + if extra_args is None: + extra_args = [] + _check_unpack_options(extensions, function, extra_args) + _UNPACK_FORMATS[name] = extensions, function, extra_args, description + +def unregister_unpack_format(name): + """Removes the pack format from the registry.""" + del _UNPACK_FORMATS[name] + +def _ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + +def _unpack_zipfile(filename, extract_dir): + """Unpack zip `filename` to `extract_dir` + """ + import zipfile # late import for breaking circular dependency + + if not zipfile.is_zipfile(filename): + raise ReadError("%s is not a zip file" % filename) + + zip = zipfile.ZipFile(filename) + try: + for info in zip.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name: + continue + + target = os.path.join(extract_dir, *name.split('/')) + if not target: + continue + + _ensure_directory(target) + if not name.endswith('/'): + # file + data = zip.read(info.filename) + f = open(target, 'wb') + try: + f.write(data) + finally: + f.close() + del data + finally: + zip.close() + +def _unpack_tarfile(filename, extract_dir): + """Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir` + """ + import tarfile # late import for breaking circular dependency + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise ReadError( + "%s is not a compressed or uncompressed tar file" % filename) + try: + tarobj.extractall(extract_dir) + finally: + tarobj.close() + +_UNPACK_FORMATS = { + 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file"), +} + +if _ZLIB_SUPPORTED: + _UNPACK_FORMATS['gztar'] = (['.tar.gz', '.tgz'], _unpack_tarfile, [], + "gzip'ed tar-file") + +if _BZ2_SUPPORTED: + _UNPACK_FORMATS['bztar'] = (['.tar.bz2', '.tbz2'], _unpack_tarfile, [], + "bzip2'ed tar-file") + +if _LZMA_SUPPORTED: + _UNPACK_FORMATS['xztar'] = (['.tar.xz', '.txz'], _unpack_tarfile, [], + "xz'ed tar-file") + +def _find_unpack_format(filename): + for name, info in _UNPACK_FORMATS.items(): + for extension in info[0]: + if filename.endswith(extension): + return name + return None + +def unpack_archive(filename, extract_dir=None, format=None): + """Unpack an archive. + + `filename` is the name of the archive. + + `extract_dir` is the name of the target directory, where the archive + is unpacked. If not provided, the current working directory is used. + + `format` is the archive format: one of "zip", "tar", "gztar", "bztar", + or "xztar". Or any other registered format. If not provided, + unpack_archive will use the filename extension and see if an unpacker + was registered for that extension. + + In case none is found, a ValueError is raised. + """ + if extract_dir is None: + extract_dir = os.getcwd() + + extract_dir = os.fspath(extract_dir) + filename = os.fspath(filename) + + if format is not None: + try: + format_info = _UNPACK_FORMATS[format] + except KeyError: + raise ValueError("Unknown unpack format '{0}'".format(format)) from None + + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) + else: + # we need to look at the registered unpackers supported extensions + format = _find_unpack_format(filename) + if format is None: + raise ReadError("Unknown archive format '{0}'".format(filename)) + + func = _UNPACK_FORMATS[format][1] + kwargs = dict(_UNPACK_FORMATS[format][2]) + func(filename, extract_dir, **kwargs) + + +if hasattr(os, 'statvfs'): + + __all__.append('disk_usage') + _ntuple_diskusage = collections.namedtuple('usage', 'total used free') + _ntuple_diskusage.total.__doc__ = 'Total space in bytes' + _ntuple_diskusage.used.__doc__ = 'Used space in bytes' + _ntuple_diskusage.free.__doc__ = 'Free space in bytes' + + def disk_usage(path): + """Return disk usage statistics about the given path. + + Returned value is a named tuple with attributes 'total', 'used' and + 'free', which are the amount of total, used and free space, in bytes. + """ + st = os.statvfs(path) + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + used = (st.f_blocks - st.f_bfree) * st.f_frsize + return _ntuple_diskusage(total, used, free) + +elif os.name == 'nt': + + import nt + __all__.append('disk_usage') + _ntuple_diskusage = collections.namedtuple('usage', 'total used free') + + def disk_usage(path): + """Return disk usage statistics about the given path. + + Returned values is a named tuple with attributes 'total', 'used' and + 'free', which are the amount of total, used and free space, in bytes. + """ + total, free = nt._getdiskusage(path) + used = total - free + return _ntuple_diskusage(total, used, free) + + +def chown(path, user=None, group=None): + """Change owner user and group of the given path. + + user and group can be the uid/gid or the user/group names, and in that case, + they are converted to their respective uid/gid. + """ + + if user is None and group is None: + raise ValueError("user and/or group must be set") + + _user = user + _group = group + + # -1 means don't change it + if user is None: + _user = -1 + # user can either be an int (the uid) or a string (the system username) + elif isinstance(user, str): + _user = _get_uid(user) + if _user is None: + raise LookupError("no such user: {!r}".format(user)) + + if group is None: + _group = -1 + elif not isinstance(group, int): + _group = _get_gid(group) + if _group is None: + raise LookupError("no such group: {!r}".format(group)) + + os.chown(path, _user, _group) + +def get_terminal_size(fallback=(80, 24)): + """Get the size of the terminal window. + + For each of the two dimensions, the environment variable, COLUMNS + and LINES respectively, is checked. If the variable is defined and + the value is a positive integer, it is used. + + When COLUMNS or LINES is not defined, which is the common case, + the terminal connected to sys.__stdout__ is queried + by invoking os.get_terminal_size. + + If the terminal size cannot be successfully queried, either because + the system doesn't support querying, or because we are not + connected to a terminal, the value given in fallback parameter + is used. Fallback defaults to (80, 24) which is the default + size used by many terminal emulators. + + The value returned is a named tuple of type os.terminal_size. + """ + # columns, lines are the working values + try: + columns = int(os.environ['COLUMNS']) + except (KeyError, ValueError): + columns = 0 + + try: + lines = int(os.environ['LINES']) + except (KeyError, ValueError): + lines = 0 + + # only query if necessary + if columns <= 0 or lines <= 0: + try: + size = os.get_terminal_size(sys.__stdout__.fileno()) + except (AttributeError, ValueError, OSError): + # stdout is None, closed, detached, or not a terminal, or + # os.get_terminal_size() is unsupported + size = os.terminal_size(fallback) + if columns <= 0: + columns = size.columns + if lines <= 0: + lines = size.lines + + return os.terminal_size((columns, lines)) + +def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None diff --git a/Lib/site-packages/Flask-1.0.2.dist-info/INSTALLER b/Lib/site-packages/Flask-1.0.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/Flask-1.0.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/Flask-1.0.2.dist-info/LICENSE.txt b/Lib/site-packages/Flask-1.0.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..8f9252f --- /dev/null +++ b/Lib/site-packages/Flask-1.0.2.dist-info/LICENSE.txt @@ -0,0 +1,31 @@ +Copyright © 2010 by the Pallets team. + +Some rights reserved. + +Redistribution and use in source and binary forms of the software as +well as documentation, with or without modification, are permitted +provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/Lib/site-packages/Flask-1.0.2.dist-info/METADATA b/Lib/site-packages/Flask-1.0.2.dist-info/METADATA new file mode 100644 index 0000000..c600e73 --- /dev/null +++ b/Lib/site-packages/Flask-1.0.2.dist-info/METADATA @@ -0,0 +1,130 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 1.0.2 +Summary: A simple framework for building complex web applications. +Home-page: https://www.palletsprojects.com/p/flask/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets team +Maintainer-email: contact@palletsprojects.com +License: BSD +Project-URL: Documentation, http://flask.pocoo.org/docs/ +Project-URL: Code, https://github.com/pallets/flask +Project-URL: Issue tracker, https://github.com/pallets/flask/issues +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Flask +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Provides-Extra: dev +Provides-Extra: docs +Provides-Extra: dotenv +Requires-Dist: Werkzeug (>=0.14) +Requires-Dist: Jinja2 (>=2.10) +Requires-Dist: itsdangerous (>=0.24) +Requires-Dist: click (>=5.1) +Provides-Extra: dev +Requires-Dist: pytest (>=3); extra == 'dev' +Requires-Dist: coverage; extra == 'dev' +Requires-Dist: tox; extra == 'dev' +Requires-Dist: sphinx; extra == 'dev' +Requires-Dist: pallets-sphinx-themes; extra == 'dev' +Requires-Dist: sphinxcontrib-log-cabinet; extra == 'dev' +Provides-Extra: docs +Requires-Dist: sphinx; extra == 'docs' +Requires-Dist: pallets-sphinx-themes; extra == 'docs' +Requires-Dist: sphinxcontrib-log-cabinet; extra == 'docs' +Provides-Extra: dotenv +Requires-Dist: python-dotenv; extra == 'dotenv' + +Flask +===== + +Flask is a lightweight `WSGI`_ web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around `Werkzeug`_ +and `Jinja`_ and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Flask + + +A Simple Example +---------------- + +.. code-block:: python + + from flask import Flask + + app = Flask(__name__) + + @app.route('/') + def hello(): + return 'Hello, World!' + +.. code-block:: text + + $ FLASK_APP=hello.py flask run + * Serving Flask app "hello" + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + + +Donate +------ + +The Pallets organization develops and supports Flask and the libraries +it uses. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://psfmember.org/civicrm/contribute/transact?reset=1&id=20 + + +Links +----- + +* Website: https://www.palletsprojects.com/p/flask/ +* Documentation: http://flask.pocoo.org/docs/ +* License: `BSD `_ +* Releases: https://pypi.org/project/Flask/ +* Code: https://github.com/pallets/flask +* Issue tracker: https://github.com/pallets/flask/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/flask + * Windows: https://ci.appveyor.com/project/pallets/flask + +* Test coverage: https://codecov.io/gh/pallets/flask + +.. _WSGI: https://wsgi.readthedocs.io +.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/ +.. _Jinja: https://www.palletsprojects.com/p/jinja/ +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + diff --git a/Lib/site-packages/Flask-1.0.2.dist-info/RECORD b/Lib/site-packages/Flask-1.0.2.dist-info/RECORD new file mode 100644 index 0000000..f1e053c --- /dev/null +++ b/Lib/site-packages/Flask-1.0.2.dist-info/RECORD @@ -0,0 +1,48 @@ +Flask-1.0.2.dist-info/LICENSE.txt,sha256=ziEXA3AIuaiUn1qe4cd1XxCESWTYrk4TjN7Qb06J3l8,1575 +Flask-1.0.2.dist-info/METADATA,sha256=iA5tiNWzTtgCVe80aTZGNWsckj853fJyfvHs9U-WZRk,4182 +Flask-1.0.2.dist-info/RECORD,, +Flask-1.0.2.dist-info/WHEEL,sha256=J3CsTk7Mf2JNUyhImI-mjX-fmI4oDjyiXgWT4qgZiCE,110 +Flask-1.0.2.dist-info/entry_points.txt,sha256=gBLA1aKg0OYR8AhbAfg8lnburHtKcgJLDU52BBctN0k,42 +Flask-1.0.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 +flask/__init__.py,sha256=qq8lK6QQbxJALf1igz7qsvUwOTAoKvFGfdLm7jPNsso,1673 +flask/__main__.py,sha256=pgIXrHhxM5MAMvgzAqWpw_t6AXZ1zG38us4JRgJKtxk,291 +flask/_compat.py,sha256=UDFGhosh6mOdNB-4evKPuneHum1OpcAlwTNJCRm0irQ,2892 +flask/app.py,sha256=ahpe3T8w98rQd_Er5d7uDxK57S1nnqGQx3V3hirBovU,94147 +flask/blueprints.py,sha256=Cyhl_x99tgwqEZPtNDJUFneAfVJxWfEU4bQA7zWS6VU,18331 +flask/cli.py,sha256=30QYAO10Do9LbZYCLgfI_xhKjASdLopL8wKKVUGS2oA,29442 +flask/config.py,sha256=kznUhj4DLYxsTF_4kfDG8GEHto1oZG_kqblyrLFtpqQ,9951 +flask/ctx.py,sha256=leFzS9fzmo0uaLCdxpHc5_iiJZ1H0X_Ig4yPCOvT--g,16224 +flask/debughelpers.py,sha256=1ceC-UyqZTd4KsJkf0OObHPsVt5R3T6vnmYhiWBjV-w,6479 +flask/globals.py,sha256=pGg72QW_-4xUfsI33I5L_y76c21AeqfSqXDcbd8wvXU,1649 +flask/helpers.py,sha256=YCl8D1plTO1evEYP4KIgaY3H8Izww5j4EdgRJ89oHTw,40106 +flask/logging.py,sha256=qV9h0vt7NIRkKM9OHDWndzO61E5CeBMlqPJyTt-W2Wc,2231 +flask/sessions.py,sha256=2XHV4ASREhSEZ8bsPQW6pNVNuFtbR-04BzfKg0AfvHo,14452 +flask/signals.py,sha256=BGQbVyCYXnzKK2DVCzppKFyWN1qmrtW1QMAYUs-1Nr8,2211 +flask/templating.py,sha256=FDfWMbpgpC3qObW8GGXRAVrkHFF8K4CHOJymB1wvULI,4914 +flask/testing.py,sha256=XD3gWNvLUV8dqVHwKd9tZzsj81fSHtjOphQ1wTNtlMs,9379 +flask/views.py,sha256=Wy-_WkUVtCfE2zCXYeJehNgHuEtviE4v3HYfJ--MpbY,5733 +flask/wrappers.py,sha256=1Z9hF5-hXQajn_58XITQFRY8efv3Vy3uZ0avBfZu6XI,7511 +flask/json/__init__.py,sha256=Ns1Hj805XIxuBMh2z0dYnMVfb_KUgLzDmP3WoUYaPhw,10729 +flask/json/tag.py,sha256=9ehzrmt5k7hxf7ZEK0NOs3swvQyU9fWNe-pnYe69N60,8223 +../../Scripts/flask.exe,sha256=PGdlpSW7Q9Z2LFhHuPxej368Abv7Dz5B8FF6mx6M2tk,102784 +Flask-1.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask/json/__pycache__/tag.cpython-37.pyc,, +flask/json/__pycache__/__init__.cpython-37.pyc,, +flask/__pycache__/app.cpython-37.pyc,, +flask/__pycache__/blueprints.cpython-37.pyc,, +flask/__pycache__/cli.cpython-37.pyc,, +flask/__pycache__/config.cpython-37.pyc,, +flask/__pycache__/ctx.cpython-37.pyc,, +flask/__pycache__/debughelpers.cpython-37.pyc,, +flask/__pycache__/globals.cpython-37.pyc,, +flask/__pycache__/helpers.cpython-37.pyc,, +flask/__pycache__/logging.cpython-37.pyc,, +flask/__pycache__/sessions.cpython-37.pyc,, +flask/__pycache__/signals.cpython-37.pyc,, +flask/__pycache__/templating.cpython-37.pyc,, +flask/__pycache__/testing.cpython-37.pyc,, +flask/__pycache__/views.cpython-37.pyc,, +flask/__pycache__/wrappers.cpython-37.pyc,, +flask/__pycache__/_compat.cpython-37.pyc,, +flask/__pycache__/__init__.cpython-37.pyc,, +flask/__pycache__/__main__.cpython-37.pyc,, diff --git a/Lib/site-packages/Flask-1.0.2.dist-info/WHEEL b/Lib/site-packages/Flask-1.0.2.dist-info/WHEEL new file mode 100644 index 0000000..f21b51c --- /dev/null +++ b/Lib/site-packages/Flask-1.0.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/Flask-1.0.2.dist-info/entry_points.txt b/Lib/site-packages/Flask-1.0.2.dist-info/entry_points.txt new file mode 100644 index 0000000..1eb0252 --- /dev/null +++ b/Lib/site-packages/Flask-1.0.2.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask = flask.cli:main + diff --git a/Lib/site-packages/Flask-1.0.2.dist-info/top_level.txt b/Lib/site-packages/Flask-1.0.2.dist-info/top_level.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/Lib/site-packages/Flask-1.0.2.dist-info/top_level.txt @@ -0,0 +1 @@ +flask diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/DESCRIPTION.rst b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..7d7eef7 --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/DESCRIPTION.rst @@ -0,0 +1,21 @@ +Flask-WTF +========= + +.. image:: https://travis-ci.org/lepture/flask-wtf.svg?branch=master + :target: https://travis-ci.org/lepture/flask-wtf + :alt: Travis CI Status +.. image:: https://coveralls.io/repos/lepture/flask-wtf/badge.svg?branch=master + :target: https://coveralls.io/r/lepture/flask-wtf + :alt: Coverage Status + +Simple integration of Flask and WTForms, including CSRF, file upload, +and reCAPTCHA. + +Links +----- + +* `Documentation `_ +* `PyPI `_ +* `GitHub `_ + + diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/INSTALLER b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/LICENSE.txt b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..5cbad1a --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/LICENSE.txt @@ -0,0 +1,32 @@ +Copyright (c) 2010 by Dan Jacob. +Copyright (c) 2013 by Hsiaoming Yang. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +* The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/METADATA b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/METADATA new file mode 100644 index 0000000..8dd02a4 --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/METADATA @@ -0,0 +1,52 @@ +Metadata-Version: 2.0 +Name: Flask-WTF +Version: 0.14.2 +Summary: Simple integration of Flask and WTForms. +Home-page: https://github.com/lepture/flask-wtf +Author: Hsiaoming Yang +Author-email: me@lepture.com +License: BSD +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Flask +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Dist: Flask +Requires-Dist: WTForms + +Flask-WTF +========= + +.. image:: https://travis-ci.org/lepture/flask-wtf.svg?branch=master + :target: https://travis-ci.org/lepture/flask-wtf + :alt: Travis CI Status +.. image:: https://coveralls.io/repos/lepture/flask-wtf/badge.svg?branch=master + :target: https://coveralls.io/r/lepture/flask-wtf + :alt: Coverage Status + +Simple integration of Flask and WTForms, including CSRF, file upload, +and reCAPTCHA. + +Links +----- + +* `Documentation `_ +* `PyPI `_ +* `GitHub `_ + + diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/RECORD b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/RECORD new file mode 100644 index 0000000..cd4c818 --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/RECORD @@ -0,0 +1,30 @@ +Flask_WTF-0.14.2.dist-info/DESCRIPTION.rst,sha256=vyJWnOD4vgnZ6x2ERr5EH1l2uzLxXCBhr_O1L6Ell2E,584 +Flask_WTF-0.14.2.dist-info/LICENSE.txt,sha256=oHX42YrP2wXdmHFiQrniwbOrmHIpJrPEz2yRasFOg1A,1490 +Flask_WTF-0.14.2.dist-info/METADATA,sha256=M8ZfImxUciRZ5Av5r1x37JnEC3wG5sacQv346wmldHU,1846 +Flask_WTF-0.14.2.dist-info/RECORD,, +Flask_WTF-0.14.2.dist-info/WHEEL,sha256=5wvfB7GvgZAbKBSE9uX9Zbi6LCL-_KgezgHblXhCRnM,113 +Flask_WTF-0.14.2.dist-info/metadata.json,sha256=qGwhg5DSr2WilK8cvCcQsdrtDJ5NFgR1faLrO8YZCAY,1370 +Flask_WTF-0.14.2.dist-info/top_level.txt,sha256=zK3flQPSjYTkAMjB0V6Jhu3jyotC0biL1mMhzitYoog,10 +flask_wtf/__init__.py,sha256=zNLRzvfi7PLTc7jkqQT7pzgtsw9_9eN7BfO4fzwKxJc,406 +flask_wtf/_compat.py,sha256=4h1U_W5vbM9L8sJ4ZPFevuneM1TirnBTTVrsHRH3uUE,849 +flask_wtf/csrf.py,sha256=suKAZarzLIBuiJFqwP--RldEYabPj0DGfYkQA32Cc1E,11554 +flask_wtf/file.py,sha256=2UnODjSq47IjsFQMiu_z218vFA5pnQ9nL1FpX7hpK1M,2971 +flask_wtf/form.py,sha256=lpx-ItUnKjYOW8VxQpBAlbhoROJNd2PHi3v0loPPyYI,4948 +flask_wtf/html5.py,sha256=ReZHJto8DAZkO3BxUDdHnkyz5mM21KtqKYh0achJ5IM,372 +flask_wtf/i18n.py,sha256=xMB_jHCOaWfF1RXm7E6hsRHwPsUyVyKX2Rhy3tBOUgk,1790 +flask_wtf/recaptcha/__init__.py,sha256=q3TC7tZPSAZ3On3GApZKGn0EcydX4zprisbyTlhN3sQ,86 +flask_wtf/recaptcha/fields.py,sha256=kN_10iZYQcYg1EtxFp4B87BlFnnrJCktrh7bTykOVj4,453 +flask_wtf/recaptcha/validators.py,sha256=8UgjA72OxUyHVk_lm8-fGhPEvKgkMtsoFNt7yzjo0xw,2398 +flask_wtf/recaptcha/widgets.py,sha256=me-oaqMNPW2BLujNTuDHCXWcVhh6eI7wlm6_TIrIF_U,1267 +Flask_WTF-0.14.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask_wtf/recaptcha/__pycache__/fields.cpython-37.pyc,, +flask_wtf/recaptcha/__pycache__/validators.cpython-37.pyc,, +flask_wtf/recaptcha/__pycache__/widgets.cpython-37.pyc,, +flask_wtf/recaptcha/__pycache__/__init__.cpython-37.pyc,, +flask_wtf/__pycache__/csrf.cpython-37.pyc,, +flask_wtf/__pycache__/file.cpython-37.pyc,, +flask_wtf/__pycache__/form.cpython-37.pyc,, +flask_wtf/__pycache__/html5.cpython-37.pyc,, +flask_wtf/__pycache__/i18n.cpython-37.pyc,, +flask_wtf/__pycache__/_compat.cpython-37.pyc,, +flask_wtf/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/WHEEL b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/WHEEL new file mode 100644 index 0000000..7bf9daa --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0.a0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/metadata.json b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/metadata.json new file mode 100644 index 0000000..d48bac6 --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Flask", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules"], "extensions": {"python.details": {"contacts": [{"email": "me@lepture.com", "name": "Hsiaoming Yang", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://github.com/lepture/flask-wtf"}}}, "extras": [], "generator": "bdist_wheel (0.30.0.a0)", "license": "BSD", "metadata_version": "2.0", "name": "Flask-WTF", "platform": "any", "run_requires": [{"requires": ["Flask", "WTForms"]}], "summary": "Simple integration of Flask and WTForms.", "version": "0.14.2"} \ No newline at end of file diff --git a/Lib/site-packages/Flask_WTF-0.14.2.dist-info/top_level.txt b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/top_level.txt new file mode 100644 index 0000000..716f422 --- /dev/null +++ b/Lib/site-packages/Flask_WTF-0.14.2.dist-info/top_level.txt @@ -0,0 +1 @@ +flask_wtf diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst b/Lib/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..1594da5 --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/DESCRIPTION.rst @@ -0,0 +1,37 @@ + +Jinja2 +~~~~~~ + +Jinja2 is a template engine written in pure Python. It provides a +`Django`_ inspired non-XML syntax but supports inline expressions and +an optional `sandboxed`_ environment. + +Nutshell +-------- + +Here a small example of a Jinja template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} +

+ {% endblock %} + +Philosophy +---------- + +Application logic is for the controller but don't try to make the life +for the template designer too hard by giving him too few functionality. + +For more informations visit the new `Jinja2 webpage`_ and `documentation`_. + +.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) +.. _Django: https://www.djangoproject.com/ +.. _Jinja2 webpage: http://jinja.pocoo.org/ +.. _documentation: http://jinja.pocoo.org/2/documentation/ + + diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/INSTALLER b/Lib/site-packages/Jinja2-2.10.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/LICENSE.txt b/Lib/site-packages/Jinja2-2.10.dist-info/LICENSE.txt new file mode 100644 index 0000000..31bf900 --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/LICENSE.txt @@ -0,0 +1,31 @@ +Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/METADATA b/Lib/site-packages/Jinja2-2.10.dist-info/METADATA new file mode 100644 index 0000000..40f2b46 --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/METADATA @@ -0,0 +1,68 @@ +Metadata-Version: 2.0 +Name: Jinja2 +Version: 2.10 +Summary: A small but fast and easy to use stand-alone template engine written in pure python. +Home-page: http://jinja.pocoo.org/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Description-Content-Type: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Dist: MarkupSafe (>=0.23) +Provides-Extra: i18n +Requires-Dist: Babel (>=0.8); extra == 'i18n' + + +Jinja2 +~~~~~~ + +Jinja2 is a template engine written in pure Python. It provides a +`Django`_ inspired non-XML syntax but supports inline expressions and +an optional `sandboxed`_ environment. + +Nutshell +-------- + +Here a small example of a Jinja template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} + + {% endblock %} + +Philosophy +---------- + +Application logic is for the controller but don't try to make the life +for the template designer too hard by giving him too few functionality. + +For more informations visit the new `Jinja2 webpage`_ and `documentation`_. + +.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) +.. _Django: https://www.djangoproject.com/ +.. _Jinja2 webpage: http://jinja.pocoo.org/ +.. _documentation: http://jinja.pocoo.org/2/documentation/ + + diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/RECORD b/Lib/site-packages/Jinja2-2.10.dist-info/RECORD new file mode 100644 index 0000000..784bbd9 --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/RECORD @@ -0,0 +1,63 @@ +Jinja2-2.10.dist-info/DESCRIPTION.rst,sha256=b5ckFDoM7vVtz_mAsJD4OPteFKCqE7beu353g4COoYI,978 +Jinja2-2.10.dist-info/LICENSE.txt,sha256=JvzUNv3Io51EiWrAPm8d_SXjhJnEjyDYvB3Tvwqqils,1554 +Jinja2-2.10.dist-info/METADATA,sha256=18EgU8zR6-av-0-5y_gXebzK4GnBB_76lALUsl-6QHM,2258 +Jinja2-2.10.dist-info/RECORD,, +Jinja2-2.10.dist-info/WHEEL,sha256=kdsN-5OJAZIiHN-iO4Rhl82KyS0bDWf4uBwMbkNafr8,110 +Jinja2-2.10.dist-info/entry_points.txt,sha256=NdzVcOrqyNyKDxD09aERj__3bFx2paZhizFDsKmVhiA,72 +Jinja2-2.10.dist-info/metadata.json,sha256=NPUJ9TMBxVQAv_kTJzvU8HwmP-4XZvbK9mz6_4YUVl4,1473 +Jinja2-2.10.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=xJHjaMoy51_KXn1wf0cysH6tUUifUxZCwSOfcJGEYZw,2614 +jinja2/_compat.py,sha256=xP60CE5Qr8FTYcDE1f54tbZLKGvMwYml4-8T7Q4KG9k,2596 +jinja2/_identifier.py,sha256=W1QBSY-iJsyt6oR_nKSuNNCzV95vLIOYgUNPUI1d5gU,1726 +jinja2/asyncfilters.py,sha256=cTDPvrS8Hp_IkwsZ1m9af_lr5nHysw7uTa5gV0NmZVE,4144 +jinja2/asyncsupport.py,sha256=UErQ3YlTLaSjFb94P4MVn08-aVD9jJxty2JVfMRb-1M,7878 +jinja2/bccache.py,sha256=nQldx0ZRYANMyfvOihRoYFKSlUdd5vJkS7BjxNwlOZM,12794 +jinja2/compiler.py,sha256=BqC5U6JxObSRhblyT_a6Tp5GtEU5z3US1a4jLQaxxgo,65386 +jinja2/constants.py,sha256=uwwV8ZUhHhacAuz5PTwckfsbqBaqM7aKfyJL7kGX5YQ,1626 +jinja2/debug.py,sha256=WTVeUFGUa4v6ReCsYv-iVPa3pkNB75OinJt3PfxNdXs,12045 +jinja2/defaults.py,sha256=Em-95hmsJxIenDCZFB1YSvf9CNhe9rBmytN3yUrBcWA,1400 +jinja2/environment.py,sha256=VnkAkqw8JbjZct4tAyHlpBrka2vqB-Z58RAP-32P1ZY,50849 +jinja2/exceptions.py,sha256=_Rj-NVi98Q6AiEjYQOsP8dEIdu5AlmRHzcSNOPdWix4,4428 +jinja2/ext.py,sha256=atMQydEC86tN1zUsdQiHw5L5cF62nDbqGue25Yiu3N4,24500 +jinja2/filters.py,sha256=yOAJk0MsH-_gEC0i0U6NweVQhbtYaC-uE8xswHFLF4w,36528 +jinja2/idtracking.py,sha256=2GbDSzIvGArEBGLkovLkqEfmYxmWsEf8c3QZwM4uNsw,9197 +jinja2/lexer.py,sha256=ySEPoXd1g7wRjsuw23uimS6nkGN5aqrYwcOKxCaVMBQ,28559 +jinja2/loaders.py,sha256=xiTuURKAEObyym0nU8PCIXu_Qp8fn0AJ5oIADUUm-5Q,17382 +jinja2/meta.py,sha256=fmKHxkmZYAOm9QyWWy8EMd6eefAIh234rkBMW2X4ZR8,4340 +jinja2/nativetypes.py,sha256=_sJhS8f-8Q0QMIC0dm1YEdLyxEyoO-kch8qOL5xUDfE,7308 +jinja2/nodes.py,sha256=L10L_nQDfubLhO3XjpF9qz46FSh2clL-3e49ogVlMmA,30853 +jinja2/optimizer.py,sha256=MsdlFACJ0FRdPtjmCAdt7JQ9SGrXFaDNUaslsWQaG3M,1722 +jinja2/parser.py,sha256=lPzTEbcpTRBLw8ii6OYyExHeAhaZLMA05Hpv4ll3ULk,35875 +jinja2/runtime.py,sha256=DHdD38Pq8gj7uWQC5usJyWFoNWL317A9AvXOW_CLB34,27755 +jinja2/sandbox.py,sha256=TVyZHlNqqTzsv9fv2NvJNmSdWRHTguhyMHdxjWms32U,16708 +jinja2/tests.py,sha256=iJQLwbapZr-EKquTG_fVOVdwHUUKf3SX9eNkjQDF8oU,4237 +jinja2/utils.py,sha256=q24VupGZotQ-uOyrJxCaXtDWhZC1RgsQG7kcdmjck2Q,20629 +jinja2/visitor.py,sha256=JD1H1cANA29JcntFfN5fPyqQxB4bI4wC00BzZa-XHks,3316 +Jinja2-2.10.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2/__pycache__/asyncfilters.cpython-37.pyc,, +jinja2/__pycache__/asyncsupport.cpython-37.pyc,, +jinja2/__pycache__/bccache.cpython-37.pyc,, +jinja2/__pycache__/compiler.cpython-37.pyc,, +jinja2/__pycache__/constants.cpython-37.pyc,, +jinja2/__pycache__/debug.cpython-37.pyc,, +jinja2/__pycache__/defaults.cpython-37.pyc,, +jinja2/__pycache__/environment.cpython-37.pyc,, +jinja2/__pycache__/exceptions.cpython-37.pyc,, +jinja2/__pycache__/ext.cpython-37.pyc,, +jinja2/__pycache__/filters.cpython-37.pyc,, +jinja2/__pycache__/idtracking.cpython-37.pyc,, +jinja2/__pycache__/lexer.cpython-37.pyc,, +jinja2/__pycache__/loaders.cpython-37.pyc,, +jinja2/__pycache__/meta.cpython-37.pyc,, +jinja2/__pycache__/nativetypes.cpython-37.pyc,, +jinja2/__pycache__/nodes.cpython-37.pyc,, +jinja2/__pycache__/optimizer.cpython-37.pyc,, +jinja2/__pycache__/parser.cpython-37.pyc,, +jinja2/__pycache__/runtime.cpython-37.pyc,, +jinja2/__pycache__/sandbox.cpython-37.pyc,, +jinja2/__pycache__/tests.cpython-37.pyc,, +jinja2/__pycache__/utils.cpython-37.pyc,, +jinja2/__pycache__/visitor.cpython-37.pyc,, +jinja2/__pycache__/_compat.cpython-37.pyc,, +jinja2/__pycache__/_identifier.cpython-37.pyc,, +jinja2/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/WHEEL b/Lib/site-packages/Jinja2-2.10.dist-info/WHEEL new file mode 100644 index 0000000..7332a41 --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/entry_points.txt b/Lib/site-packages/Jinja2-2.10.dist-info/entry_points.txt new file mode 100644 index 0000000..32e6b75 --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/entry_points.txt @@ -0,0 +1,4 @@ + + [babel.extractors] + jinja2 = jinja2.ext:babel_extract[i18n] + \ No newline at end of file diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/metadata.json b/Lib/site-packages/Jinja2-2.10.dist-info/metadata.json new file mode 100644 index 0000000..7f5dc38 --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: HTML"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://jinja.pocoo.org/"}}, "python.exports": {"babel.extractors": {"jinja2": "jinja2.ext:babel_extract [i18n]"}}}, "extras": ["i18n"], "generator": "bdist_wheel (0.30.0)", "license": "BSD", "metadata_version": "2.0", "name": "Jinja2", "run_requires": [{"extra": "i18n", "requires": ["Babel (>=0.8)"]}, {"requires": ["MarkupSafe (>=0.23)"]}], "summary": "A small but fast and easy to use stand-alone template engine written in pure python.", "version": "2.10"} \ No newline at end of file diff --git a/Lib/site-packages/Jinja2-2.10.dist-info/top_level.txt b/Lib/site-packages/Jinja2-2.10.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/Lib/site-packages/Jinja2-2.10.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/Lib/site-packages/MarkupSafe-1.0.dist-info/INSTALLER b/Lib/site-packages/MarkupSafe-1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/MarkupSafe-1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt b/Lib/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..5d26938 --- /dev/null +++ b/Lib/site-packages/MarkupSafe-1.0.dist-info/LICENSE.txt @@ -0,0 +1,33 @@ +Copyright (c) 2010 by Armin Ronacher and contributors. See AUTHORS +for more details. + +Some rights reserved. + +Redistribution and use in source and binary forms of the software as well +as documentation, with or without modification, are permitted provided +that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +* The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/Lib/site-packages/MarkupSafe-1.0.dist-info/METADATA b/Lib/site-packages/MarkupSafe-1.0.dist-info/METADATA new file mode 100644 index 0000000..25a3ad1 --- /dev/null +++ b/Lib/site-packages/MarkupSafe-1.0.dist-info/METADATA @@ -0,0 +1,135 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 1.0 +Summary: Implements a XML/HTML/XHTML Markup safe string for Python +Home-page: http://github.com/pallets/markupsafe +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML + +MarkupSafe +========== + +Implements a unicode subclass that supports HTML strings: + +.. code-block:: python + + >>> from markupsafe import Markup, escape + >>> escape("") + Markup(u'<script>alert(document.cookie);</script>') + >>> tmpl = Markup("%s") + >>> tmpl % "Peter > Lustig" + Markup(u'Peter > Lustig') + +If you want to make an object unicode that is not yet unicode +but don't want to lose the taint information, you can use the +``soft_unicode`` function. (On Python 3 you can also use ``soft_str`` which +is a different name for the same function). + +.. code-block:: python + + >>> from markupsafe import soft_unicode + >>> soft_unicode(42) + u'42' + >>> soft_unicode(Markup('foo')) + Markup(u'foo') + +HTML Representations +-------------------- + +Objects can customize their HTML markup equivalent by overriding +the ``__html__`` function: + +.. code-block:: python + + >>> class Foo(object): + ... def __html__(self): + ... return 'Nice' + ... + >>> escape(Foo()) + Markup(u'Nice') + >>> Markup(Foo()) + Markup(u'Nice') + +Silent Escapes +-------------- + +Since MarkupSafe 0.10 there is now also a separate escape function +called ``escape_silent`` that returns an empty string for ``None`` for +consistency with other systems that return empty strings for ``None`` +when escaping (for instance Pylons' webhelpers). + +If you also want to use this for the escape method of the Markup +object, you can create your own subclass that does that: + +.. code-block:: python + + from markupsafe import Markup, escape_silent as escape + + class SilentMarkup(Markup): + __slots__ = () + + @classmethod + def escape(cls, s): + return cls(escape(s)) + +New-Style String Formatting +--------------------------- + +Starting with MarkupSafe 0.21 new style string formats from Python 2.6 and +3.x are now fully supported. Previously the escape behavior of those +functions was spotty at best. The new implementations operates under the +following algorithm: + +1. if an object has an ``__html_format__`` method it is called as + replacement for ``__format__`` with the format specifier. It either + has to return a string or markup object. +2. if an object has an ``__html__`` method it is called. +3. otherwise the default format system of Python kicks in and the result + is HTML escaped. + +Here is how you can implement your own formatting: + +.. code-block:: python + + class User(object): + + def __init__(self, id, username): + self.id = id + self.username = username + + def __html_format__(self, format_spec): + if format_spec == 'link': + return Markup('{1}').format( + self.id, + self.__html__(), + ) + elif format_spec: + raise ValueError('Invalid format spec') + return self.__html__() + + def __html__(self): + return Markup('{0}').format(self.username) + +And to format that user: + +.. code-block:: python + + >>> user = User(1, 'foo') + >>> Markup('

User: {0:link}').format(user) + Markup(u'

User: foo') + +Markupsafe supports Python 2.6, 2.7 and Python 3.3 and higher. + + diff --git a/Lib/site-packages/MarkupSafe-1.0.dist-info/RECORD b/Lib/site-packages/MarkupSafe-1.0.dist-info/RECORD new file mode 100644 index 0000000..d9bc389 --- /dev/null +++ b/Lib/site-packages/MarkupSafe-1.0.dist-info/RECORD @@ -0,0 +1,15 @@ +MarkupSafe-1.0.dist-info/LICENSE.txt,sha256=C76IIo_WPSDsCX9k5Y1aCkZRI64TkUChjUBsYLSIJLU,1582 +MarkupSafe-1.0.dist-info/METADATA,sha256=RTBfxOEfHqiY9goR2QvR2sG0-pRm52r0QWcGi_pUYCQ,4182 +MarkupSafe-1.0.dist-info/RECORD,, +MarkupSafe-1.0.dist-info/WHEEL,sha256=IHnEIVcGZmRy_cnQluwuoqp98bayJ8Ap2I77tUv6qjc,98 +MarkupSafe-1.0.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=xtkRdxhzJzgp65wUo1D4DjnazxHU88pPldaAuDekBeY,10697 +markupsafe/_compat.py,sha256=r1HE0CpcAZeb-AiTV9wITR91PeLHn0CzZ_XHkYoozpI,565 +markupsafe/_constants.py,sha256=U_xybFQsyXKCgHSfranJnFzo-z9nn9fuBeSk243sE5Q,4795 +markupsafe/_native.py,sha256=E2Un1ysOf-w45d18YCj8UelT5UP7Vt__IuFPYJ7YRIs,1187 +markupsafe/_speedups.c,sha256=B6Mf6Fn33WqkagfwY7q5ZBSm_vJoHDYxDB0Jp_DP7Jw,5936 +MarkupSafe-1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +markupsafe/__pycache__/_compat.cpython-37.pyc,, +markupsafe/__pycache__/_constants.cpython-37.pyc,, +markupsafe/__pycache__/_native.cpython-37.pyc,, +markupsafe/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/MarkupSafe-1.0.dist-info/WHEEL b/Lib/site-packages/MarkupSafe-1.0.dist-info/WHEEL new file mode 100644 index 0000000..d7e7a45 --- /dev/null +++ b/Lib/site-packages/MarkupSafe-1.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.1) +Root-Is-Purelib: true +Tag: cp37-none-any + diff --git a/Lib/site-packages/MarkupSafe-1.0.dist-info/top_level.txt b/Lib/site-packages/MarkupSafe-1.0.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/Lib/site-packages/MarkupSafe-1.0.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/Lib/site-packages/WTForms-2.2.1.dist-info/INSTALLER b/Lib/site-packages/WTForms-2.2.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/WTForms-2.2.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/WTForms-2.2.1.dist-info/METADATA b/Lib/site-packages/WTForms-2.2.1.dist-info/METADATA new file mode 100644 index 0000000..8a77324 --- /dev/null +++ b/Lib/site-packages/WTForms-2.2.1.dist-info/METADATA @@ -0,0 +1,101 @@ +Metadata-Version: 2.1 +Name: WTForms +Version: 2.2.1 +Summary: A flexible forms validation and rendering library for Python web development. +Home-page: https://wtforms.readthedocs.io/ +Author: Thomas Johansson, James Crasta +Author-email: wtforms@simplecodes.com +Maintainer: WTForms team +Maintainer-email: davidism@gmail.com +License: BSD +Project-URL: Documentation, https://wtforms.readthedocs.io/ +Project-URL: Code, https://github.com/wtforms/wtforms +Project-URL: Issue tracker, https://github.com/wtforms/wtforms/issues +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Provides-Extra: locale +Requires-Dist: ordereddict; python_version=="2.6" +Provides-Extra: locale +Requires-Dist: Babel (>=1.3); extra == 'locale' + +WTForms +======= + +WTForms is a flexible forms validation and rendering library for Python +web development. It is `framework agnostic`_ and can work with whatever +web framework and template engine you choose. There are various +community libraries that provide closer integration with popular +frameworks. + +To get started using WTForms, we recommend reading the `crash course`_ +in the docs. + +.. _crash course: https://wtforms.readthedocs.io/en/stable/crash_course.html +.. _framework agnostic: https://wtforms.readthedocs.io/en/stable/faq.html#does-wtforms-work-with-library-here + + +Installation +------------ + +Install and update using pip:: + + pip install -U WTForms + + +Third-Party Library Integrations +-------------------------------- + +WTForms is designed to work with any web framework and template engine. +There are a number of community-provided libraries that make integrating +with frameworks even better. + +- `Flask-WTF`_ integrates with the Flask framework. It can + automatically load data from the request, uses Flask-Babel to + translate based on user-selected locale, provides full-application + CSRF, and more. +- `WTForms-Alchemy`_ provides rich support for generating forms from + SQLAlchemy models, including an expanded set of fields and + validators. +- `WTForms-SQLAlchemy`_ provides ORM-backed fields and form generation + from SQLAlchemy models. +- `WTForms-AppEngine`_ provides ORM-backed fields and form generation + from AppEnding db/ndb schema +- `WTForms-AppEngine`_ provides ORM-backed fields and form generation + from Django models, as well as integration with Django's I18N + support. + +.. _Flask-WTF: https://flask-wtf.readthedocs.io/ +.. _WTForms-Alchemy: https://wtforms-alchemy.readthedocs.io/ +.. _WTForms-SQLAlchemy: https://github.com/wtforms/wtforms-sqlalchemy +.. _WTForms-AppEngine: https://github.com/wtforms/wtforms-appengine +.. _WTForms-Django: https://github.com/wtforms/wtforms-django + + +Links +----- + +- Documentation: https://wtforms.readthedocs.io/ +- License: `BSD `_ +- Releases: https://pypi.org/project/WTForms/ +- Code: https://github.com/wtforms/wtforms +- Issue tracker: https://github.com/wtforms/wtforms/issues +- Test status: + + - Linux: https://travis-ci.org/wtforms/wtforms + +- Test coverage: https://coveralls.io/github/wtforms/wtforms + + diff --git a/Lib/site-packages/WTForms-2.2.1.dist-info/RECORD b/Lib/site-packages/WTForms-2.2.1.dist-info/RECORD new file mode 100644 index 0000000..a8ed68b --- /dev/null +++ b/Lib/site-packages/WTForms-2.2.1.dist-info/RECORD @@ -0,0 +1,147 @@ +WTForms-2.2.1.dist-info/METADATA,sha256=Aqv5s_FPo1o3VxjnX-nclKn2dBPIVOpTwggPPH-DJs0,3771 +WTForms-2.2.1.dist-info/RECORD,, +WTForms-2.2.1.dist-info/WHEEL,sha256=gduuPyBvFJQSQ0zdyxF7k0zynDXbIbvg5ZBHoXum5uk,110 +WTForms-2.2.1.dist-info/top_level.txt,sha256=k5K62RAEkLEN23p118t3tRgvL6I_k56NiIU7Hk8Phv8,8 +wtforms/__init__.py,sha256=h4gmUHtk1Y9cGJ-l63rhrp-nC9REGdpcRPBGoJKP9hk,380 +wtforms/compat.py,sha256=buY-q7yLNO-2OlxA5QPAcdBO8urjZTtxvFnxg_1Euuo,589 +wtforms/form.py,sha256=ahME3_8CmTuvVsatV-AKqinBkOSEnLOE_nMeQLgrQEA,11608 +wtforms/i18n.py,sha256=RuMPdvfsxHGMqKySUy4DpMfEAzruPK_7gHe6GQTrekc,2175 +wtforms/meta.py,sha256=9yLQuKP4N_OiPBsPy3tBc7auldxhFryZweySDsKL8zI,3822 +wtforms/utils.py,sha256=Zg70vKv96pnHjrkSZ6KlzSo1noh20GV5IqfPy6FrOyA,1504 +wtforms/validators.py,sha256=niMtYGGRijIiZ2ruslYfRP7CTGDul_DHiR-iYen7zRg,19430 +wtforms/csrf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wtforms/csrf/core.py,sha256=Ot8eOSAZ88qeDBlSUhRqiLfyWA13g3EFJ4zWZ7EGYnc,3157 +wtforms/csrf/session.py,sha256=baww8MJ5YObyYItXX0Vz5AjxZTdOfTqti3zsD3koka0,3056 +wtforms/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wtforms/ext/appengine/__init__.py,sha256=xXkE1qkwzkkBw4o0YhWGZSZXcsV60DaLxX4fkxNcNe8,269 +wtforms/ext/appengine/db.py,sha256=IEJng34ztXLVSlLxneZ7M4kgGOZOPf9zR_6RTqv6Z1Q,18588 +wtforms/ext/appengine/fields.py,sha256=8Z2BJy7ft0fu_vZksneZ7xdVxdqHkWIMNjgnyfdKtho,7574 +wtforms/ext/appengine/ndb.py,sha256=szIwWA5FyD2lqZefayl__C2UsXMEAGQndqPYPhOH4Vk,17124 +wtforms/ext/csrf/__init__.py,sha256=bIQ48rbnoYrYPZkkGz04b_7PZ8leQY_CExEqYw8yitI,45 +wtforms/ext/csrf/fields.py,sha256=Ta3vLg9KQkpUTCnDF-7CP3IW11X0UqqhvL68sAopYTs,430 +wtforms/ext/csrf/form.py,sha256=ZxmvC3Um2qYeUncu6D390-W62mVQclzwPLP9_R7GedU,1785 +wtforms/ext/csrf/session.py,sha256=aKYb9_jgEmxIgvWuk0cdx9YAGTi9s3F4xy_0ibxyhbo,2627 +wtforms/ext/dateutil/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wtforms/ext/dateutil/fields.py,sha256=RlupqB1WX_HiKJEYqi9IAxiCElxgbBDHHuXrGF4nbYs,3429 +wtforms/ext/django/__init__.py,sha256=OQ0wr3s5_cUmUU7htHXhobyxVWJS16Ve4qBK_PLs_rw,259 +wtforms/ext/django/fields.py,sha256=pEWxaAtMq5_p8QaJPOffWsX7U4LB5f8Bq8ZBw4fedxk,4580 +wtforms/ext/django/i18n.py,sha256=VLvzJ8lQOqs5Uxnhe4aOE5StGgPEvGhfBEHNrRQFtp0,626 +wtforms/ext/django/orm.py,sha256=Mme5i_o_bJTXGKkabRz03EJmGggPMejAg95XNhYtNUc,6096 +wtforms/ext/django/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wtforms/ext/django/templatetags/wtforms.py,sha256=iCOicSMEkixm5bcJHz35Zx0h6xVwnz1H9JglB_hU69o,2826 +wtforms/ext/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wtforms/ext/i18n/form.py,sha256=mfsavr4LGI1GhoFLsWSuSqVPHH6QNiyqoAfY94u-XP0,1608 +wtforms/ext/i18n/utils.py,sha256=rx9-pNYjIp8DLU-VQ9XxRSXHYZuFv4ktRejzVBPTDBg,530 +wtforms/ext/sqlalchemy/__init__.py,sha256=4U9BzeiFD_YF8pXRsTehei0ekP6jikt2bX4MN3GNT9s,431 +wtforms/ext/sqlalchemy/fields.py,sha256=XwOgJUJCcXvw-QGdF6q2w51m1CI4E_COq8GXb9blgI0,6846 +wtforms/ext/sqlalchemy/orm.py,sha256=6wJN-Zm4YB3st9xsXU5xJR5jQUsdSRqcbEZ7JvvGD9s,10671 +wtforms/fields/__init__.py,sha256=M-0pFfY9EEk-GoYzRkg3yvarM_iP_cRhPjpLEl5KgVU,219 +wtforms/fields/core.py,sha256=KevHc47k4mMJgRGe8Y07UrS_9o_nzXbn3U2HznpdMI0,34307 +wtforms/fields/html5.py,sha256=bwLHIBrEWICRcS80am_lBp6GitDCVIRvBdIWEPJeSz0,1995 +wtforms/fields/simple.py,sha256=dY7cYfb6PXMDjUefXcDeTDWpv3UGyr_BMlebJAeoRso,2218 +wtforms/locale/README.md,sha256=xL3Ain6UPZK3UdL8tMrIKwfodEsPT0IYCVDpI6do524,1062 +wtforms/locale/wtforms.pot,sha256=Sqe4LRpObVRUc30htYXgZuueKYfW7wt2lNVKtM_Jrr0,4170 +wtforms/locale/ar/LC_MESSAGES/wtforms.mo,sha256=r1DDYnBCr1hT7KwEG3NpQLR52i4j_-er5ENIVqT9Sbo,4530 +wtforms/locale/ar/LC_MESSAGES/wtforms.po,sha256=Qkhg_pS-ZEf7jEZz76mDC47UPpqWcU_8t7L88ALAPvk,6262 +wtforms/locale/bg/LC_MESSAGES/wtforms.mo,sha256=aPnglyINf0hH4FGUM3U5OJpqcJT_8XRx6GiaD4Jif3g,4297 +wtforms/locale/bg/LC_MESSAGES/wtforms.po,sha256=xflJaMOGUTNN7zbFMWL-FbMVjmj-Svmvkek84mJl5NI,6356 +wtforms/locale/ca/LC_MESSAGES/wtforms.mo,sha256=zBX48Ru44A2O82FXwC9CwzU3_FiFkUyb4KGNya4toSg,3425 +wtforms/locale/ca/LC_MESSAGES/wtforms.po,sha256=oT09ydRQNsmf0a1uwskao0wfbwQqAh2tKXjFqI_iscw,5465 +wtforms/locale/cs_CZ/LC_MESSAGES/wtforms.mo,sha256=MJQPoiMNPfdHYX5eQQ2OW7PmvQ9BFETva2qm3xmPSvo,3618 +wtforms/locale/cs_CZ/LC_MESSAGES/wtforms.po,sha256=MZ1Iv28-oX4dqzSPgGo65YU3iijeBmYBKZSGsl8YYS0,5596 +wtforms/locale/cy/LC_MESSAGES/wtforms.mo,sha256=8pJPG9dguZLej33ksWSwWmCOKIJ7VmpNVlaDMb30_lc,3371 +wtforms/locale/cy/LC_MESSAGES/wtforms.po,sha256=DTGkDUWJ1MsZqFPV8YhwHaBI1uJP6uXwiud7K3LW1yw,5415 +wtforms/locale/de/LC_MESSAGES/wtforms.mo,sha256=D4BRsJeeT_cKYagO7W1LHQ8YpwC2c7_0hbv3tDgk82E,3412 +wtforms/locale/de/LC_MESSAGES/wtforms.po,sha256=BF7F3vwQOAL_yaZTHi7x2KZnaCTzz3MNUNCtuc6e47A,5457 +wtforms/locale/de_CH/LC_MESSAGES/wtforms.mo,sha256=lBUgz2N_AlkXB4W-CxaNGuHdwhgTrYCPtwM9DWL-pP0,3418 +wtforms/locale/de_CH/LC_MESSAGES/wtforms.po,sha256=LiAqravsNbETdXHJiOi3vJD4o3hWrTRZWSHcLNvHjgc,5477 +wtforms/locale/el/LC_MESSAGES/wtforms.mo,sha256=r0_oQGB_KYBZdSmFsielQMCF0P7rgsLDCA28u37XAkw,4307 +wtforms/locale/el/LC_MESSAGES/wtforms.po,sha256=snlBcC-cjlFdpIbSG9pRGYlWFhl1EaQX72Umv2PWfp8,6345 +wtforms/locale/en/LC_MESSAGES/wtforms.mo,sha256=DCJnvT-_j_oec9za8vxn0FZSog4mm5PnaiWIpesctDE,3285 +wtforms/locale/en/LC_MESSAGES/wtforms.po,sha256=-GGpFQm9Sdz3Yg0EqltIGTEcOwnYqmepRSREkHV_UVU,5347 +wtforms/locale/es/LC_MESSAGES/wtforms.mo,sha256=U_oe-S3-i6A2VsBTVKxZ8N5QAEbpqXBlenSIaLnFupE,3394 +wtforms/locale/es/LC_MESSAGES/wtforms.po,sha256=P36kwWq3LZNjYHXTyoyMl86WziWpZYXxGFsFiqev1oU,5368 +wtforms/locale/et/LC_MESSAGES/wtforms.mo,sha256=Ugx0IpG1TJtP-DKpNZiVyo-L5F8ESrr_qCpPXR96pww,3456 +wtforms/locale/et/LC_MESSAGES/wtforms.po,sha256=doeYijsnPkyHy_JK4JRH6AQdHG8uaQTQWYwsCP6_Iuk,5497 +wtforms/locale/fa/LC_MESSAGES/wtforms.mo,sha256=exJzwjxXvOALqJhsQetN9Kcad4Lx62Exvnx2jtzja8Q,4137 +wtforms/locale/fa/LC_MESSAGES/wtforms.po,sha256=MHjVwlp-MHMV-TTUUkUYtuBdtbEjfV0jzVSgWHFv80Q,6149 +wtforms/locale/fi/LC_MESSAGES/wtforms.mo,sha256=NiodjvNOW25UkxEpuCioXdpvjbGwPoYmz0dfiMxE3S8,3416 +wtforms/locale/fi/LC_MESSAGES/wtforms.po,sha256=4uP6A6sfNoATdRR_8PlecqiiTsVzIp9qpcn9qe0jGMA,5456 +wtforms/locale/fr/LC_MESSAGES/wtforms.mo,sha256=BoZI4I1MK0-nipyLWOSG-s_55E9x9eG0WqYdz1qZ1KQ,3484 +wtforms/locale/fr/LC_MESSAGES/wtforms.po,sha256=60tb7Uyco3tdKc1Z4sdvwta46V_RGSmvXM9SdvuBvhg,5529 +wtforms/locale/he/LC_MESSAGES/wtforms.mo,sha256=UhetGKepgOnGXa5IsjZBdOi5IbPLCufpIugkkDuXkjQ,3649 +wtforms/locale/he/LC_MESSAGES/wtforms.po,sha256=GJy7zG0ik8U0YnubNlfjjl9iPT62w3XyaAP4kNCntkQ,5657 +wtforms/locale/hu/LC_MESSAGES/wtforms.mo,sha256=Z-qEeJI422dmm7-2qJIgCuCS1eyS2pJfoavPnGK2334,3544 +wtforms/locale/hu/LC_MESSAGES/wtforms.po,sha256=eiyNXYa4_XLQWRd-j4KmAXml27cYAPjIBhjjIv9WMbE,5492 +wtforms/locale/it/LC_MESSAGES/wtforms.mo,sha256=petuqW4x1p1S69sJax15WpLQryWoDRXW0uQjr58E9Jw,3510 +wtforms/locale/it/LC_MESSAGES/wtforms.po,sha256=EuI0Plf7nLfg5NcRPqQvfg3z7fpfIdRQGBmyq1ivpGE,5556 +wtforms/locale/ja/LC_MESSAGES/wtforms.mo,sha256=thfPsxKfihz2wNvb9LA7MzYb4PnfyXT81gaE_802AlM,3736 +wtforms/locale/ja/LC_MESSAGES/wtforms.po,sha256=ydUzTwxnk8sUQcPTeS7AuU7sgArIMWgbDzxFt85mhG8,5753 +wtforms/locale/ko/LC_MESSAGES/wtforms.mo,sha256=ZRJGcizRhJifuw4rElZ6Bb-hNdH3zqCYzxhwYJisCpU,3851 +wtforms/locale/ko/LC_MESSAGES/wtforms.po,sha256=9os2sRuqxoX0fTWHr47IvBwlkY_sDoLKdn3byS7MfjQ,5842 +wtforms/locale/nb/LC_MESSAGES/wtforms.mo,sha256=0YxYTElaTGBpIurcZqZHPU2lXslt3UNF_HOw575OAKM,3337 +wtforms/locale/nb/LC_MESSAGES/wtforms.po,sha256=NXrr3nrnoOo2x2t0g8UZXT2Jm9KQnkYdnieeoB7U9Yw,5387 +wtforms/locale/nl/LC_MESSAGES/wtforms.mo,sha256=8wLTkRK82jpG5oDkqM-jLNVLYHte4fRHYF6VAN7lB6U,3350 +wtforms/locale/nl/LC_MESSAGES/wtforms.po,sha256=9xSoztymVdIgFBA2vnzaHeSK4qEGTGbiPbfwjdcHN0k,5388 +wtforms/locale/pl/LC_MESSAGES/wtforms.mo,sha256=QUs5iz_IOoo6oCVmcpWWNNkXyqYA0X01wERmQYQiXYo,3610 +wtforms/locale/pl/LC_MESSAGES/wtforms.po,sha256=XrkwltOhyLHrOOgxYVvcmR2Hcw4LUN3_sZEdJofS5Vk,5652 +wtforms/locale/pt/LC_MESSAGES/wtforms.mo,sha256=PC5HRiM-QYt4GX3eMPapzG31jLKmo3zt6nKGVb_o174,3438 +wtforms/locale/pt/LC_MESSAGES/wtforms.po,sha256=cXIZJJZ4UDDR24yrQ-XYck3klonRZd9Ajt8A7dqqJc4,5481 +wtforms/locale/ru/LC_MESSAGES/wtforms.mo,sha256=ski71qWfnwGL9GtZEQZ1fksHBeZsePxi4ZN16AlLeZE,4406 +wtforms/locale/ru/LC_MESSAGES/wtforms.po,sha256=3eeI-CxivICl6FzYpKrqfYnz2rB68hMNCicC_9aM90s,6407 +wtforms/locale/sk/LC_MESSAGES/wtforms.mo,sha256=Lo_5eGNF_LnkJsJLOde_YNWE_F3UZtScFTFlO4v-EyU,3548 +wtforms/locale/sk/LC_MESSAGES/wtforms.po,sha256=ywPpnxYnHgEkD6Ab7LJgyqgC6dIj8cBmn6hB21aS3NI,5586 +wtforms/locale/sv/LC_MESSAGES/wtforms.mo,sha256=U7noK9cso_pRgaQcvF4duRQ69joI7SHN0XcHyd0mAVg,3376 +wtforms/locale/sv/LC_MESSAGES/wtforms.po,sha256=jMtpwUlQPbi4Xiut9KNfLjGhsjqmys1Y_iGZ3lJA4NQ,5416 +wtforms/locale/tr/LC_MESSAGES/wtforms.mo,sha256=kp3J8k2FVBaXVVJJclGnUmZTEUYHS6Hg1v2baGwtReo,3391 +wtforms/locale/tr/LC_MESSAGES/wtforms.po,sha256=PFo_e3vKCMgKtkcQSaXqNOlr-YgzxvgUtg8Ju5M-8f8,5431 +wtforms/locale/uk/LC_MESSAGES/wtforms.mo,sha256=5iZS-8LmCyeteqN3TXQ15byNTGJbjpsDa8AF3zh6L1o,4451 +wtforms/locale/uk/LC_MESSAGES/wtforms.po,sha256=fIijOGm8gXO-yZkdYoX6kWMPXZE6j9yALhekfQCK5KU,6520 +wtforms/locale/zh/LC_MESSAGES/wtforms.mo,sha256=yCzjCCwAf5yu80NhllpGqlk7V6PBFyJYfoZ6IF2dQnM,3362 +wtforms/locale/zh/LC_MESSAGES/wtforms.po,sha256=ZIh59O9rnjZMRpdKFfvrk59wouOAUHyjZS0f-TMsN6U,5378 +wtforms/locale/zh_TW/LC_MESSAGES/wtforms.mo,sha256=iha5oFUQDVs7wPBpcWLLAP_Jgm42Ea9n9xIlaCsUsNE,3204 +wtforms/locale/zh_TW/LC_MESSAGES/wtforms.po,sha256=a7q2T9fdwN_xESBCD4umHMfSptN7Qt-abjO9UFRWDBo,5218 +wtforms/widgets/__init__.py,sha256=nxI0oIsofuJCNgc4Oxwzf3_q3IiCYZTSiCoEuSRZeJM,124 +wtforms/widgets/core.py,sha256=X3I5PRFbPeX1nU3DrPpsJyglsObujdN1hMxHHFTkKOk,11150 +wtforms/widgets/html5.py,sha256=LDnNegNTx-LYpw4YkbymvS2TaA2V03p2rRdYN83skYQ,2440 +WTForms-2.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +wtforms/csrf/__pycache__/core.cpython-37.pyc,, +wtforms/csrf/__pycache__/session.cpython-37.pyc,, +wtforms/csrf/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/appengine/__pycache__/db.cpython-37.pyc,, +wtforms/ext/appengine/__pycache__/fields.cpython-37.pyc,, +wtforms/ext/appengine/__pycache__/ndb.cpython-37.pyc,, +wtforms/ext/appengine/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/csrf/__pycache__/fields.cpython-37.pyc,, +wtforms/ext/csrf/__pycache__/form.cpython-37.pyc,, +wtforms/ext/csrf/__pycache__/session.cpython-37.pyc,, +wtforms/ext/csrf/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/dateutil/__pycache__/fields.cpython-37.pyc,, +wtforms/ext/dateutil/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/django/templatetags/__pycache__/wtforms.cpython-37.pyc,, +wtforms/ext/django/templatetags/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/django/__pycache__/fields.cpython-37.pyc,, +wtforms/ext/django/__pycache__/i18n.cpython-37.pyc,, +wtforms/ext/django/__pycache__/orm.cpython-37.pyc,, +wtforms/ext/django/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/i18n/__pycache__/form.cpython-37.pyc,, +wtforms/ext/i18n/__pycache__/utils.cpython-37.pyc,, +wtforms/ext/i18n/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/sqlalchemy/__pycache__/fields.cpython-37.pyc,, +wtforms/ext/sqlalchemy/__pycache__/orm.cpython-37.pyc,, +wtforms/ext/sqlalchemy/__pycache__/__init__.cpython-37.pyc,, +wtforms/ext/__pycache__/__init__.cpython-37.pyc,, +wtforms/fields/__pycache__/core.cpython-37.pyc,, +wtforms/fields/__pycache__/html5.cpython-37.pyc,, +wtforms/fields/__pycache__/simple.cpython-37.pyc,, +wtforms/fields/__pycache__/__init__.cpython-37.pyc,, +wtforms/widgets/__pycache__/core.cpython-37.pyc,, +wtforms/widgets/__pycache__/html5.cpython-37.pyc,, +wtforms/widgets/__pycache__/__init__.cpython-37.pyc,, +wtforms/__pycache__/compat.cpython-37.pyc,, +wtforms/__pycache__/form.cpython-37.pyc,, +wtforms/__pycache__/i18n.cpython-37.pyc,, +wtforms/__pycache__/meta.cpython-37.pyc,, +wtforms/__pycache__/utils.cpython-37.pyc,, +wtforms/__pycache__/validators.cpython-37.pyc,, +wtforms/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/WTForms-2.2.1.dist-info/WHEEL b/Lib/site-packages/WTForms-2.2.1.dist-info/WHEEL new file mode 100644 index 0000000..1316c41 --- /dev/null +++ b/Lib/site-packages/WTForms-2.2.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/WTForms-2.2.1.dist-info/top_level.txt b/Lib/site-packages/WTForms-2.2.1.dist-info/top_level.txt new file mode 100644 index 0000000..26d80fd --- /dev/null +++ b/Lib/site-packages/WTForms-2.2.1.dist-info/top_level.txt @@ -0,0 +1 @@ +wtforms diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst b/Lib/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..675f08d --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/DESCRIPTION.rst @@ -0,0 +1,80 @@ +Werkzeug +======== + +Werkzeug is a comprehensive `WSGI`_ web application library. It began as +a simple collection of various utilities for WSGI applications and has +become one of the most advanced WSGI utility libraries. + +It includes: + +* An interactive debugger that allows inspecting stack traces and source + code in the browser with an interactive interpreter for any frame in + the stack. +* A full-featured request object with objects to interact with headers, + query args, form data, files, and cookies. +* A response object that can wrap other WSGI applications and handle + streaming data. +* A routing system for matching URLs to endpoints and generating URLs + for endpoints, with an extensible system for capturing variables from + URLs. +* HTTP utilities to handle entity tags, cache control, dates, user + agents, cookies, files, and more. +* A threaded WSGI server for use while developing applications locally. +* A test client for simulating HTTP requests during testing without + requiring running a server. + +Werkzeug is Unicode aware and doesn't enforce any dependencies. It is up +to the developer to choose a template engine, database adapter, and even +how to handle requests. It can be used to build all sorts of end user +applications such as blogs, wikis, or bulletin boards. + +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while +providing more structure and patterns for defining powerful +applications. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Werkzeug + + +A Simple Example +---------------- + +.. code-block:: python + + from werkzeug.wrappers import Request, Response + + @Request.application + def application(request): + return Response('Hello, World!') + + if __name__ == '__main__': + from werkzeug.serving import run_simple + run_simple('localhost', 4000, application) + + +Links +----- + +* Website: https://www.palletsprojects.com/p/werkzeug/ +* Releases: https://pypi.org/project/Werkzeug/ +* Code: https://github.com/pallets/werkzeug +* Issue tracker: https://github.com/pallets/werkzeug/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/werkzeug + * Windows: https://ci.appveyor.com/project/davidism/werkzeug + +* Test coverage: https://codecov.io/gh/pallets/werkzeug + +.. _WSGI: https://wsgi.readthedocs.io/en/latest/ +.. _Flask: https://www.palletsprojects.com/p/flask/ +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER b/Lib/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt b/Lib/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt new file mode 100644 index 0000000..1cc75bb --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/LICENSE.txt @@ -0,0 +1,31 @@ +Copyright © 2007 by the Pallets team. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/METADATA b/Lib/site-packages/Werkzeug-0.14.1.dist-info/METADATA new file mode 100644 index 0000000..bfc3c4e --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/METADATA @@ -0,0 +1,116 @@ +Metadata-Version: 2.0 +Name: Werkzeug +Version: 0.14.1 +Summary: The comprehensive WSGI web application library. +Home-page: https://www.palletsprojects.org/p/werkzeug/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: BSD +Description-Content-Type: UNKNOWN +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Provides-Extra: dev +Requires-Dist: coverage; extra == 'dev' +Requires-Dist: pytest; extra == 'dev' +Requires-Dist: sphinx; extra == 'dev' +Requires-Dist: tox; extra == 'dev' +Provides-Extra: termcolor +Requires-Dist: termcolor; extra == 'termcolor' +Provides-Extra: watchdog +Requires-Dist: watchdog; extra == 'watchdog' + +Werkzeug +======== + +Werkzeug is a comprehensive `WSGI`_ web application library. It began as +a simple collection of various utilities for WSGI applications and has +become one of the most advanced WSGI utility libraries. + +It includes: + +* An interactive debugger that allows inspecting stack traces and source + code in the browser with an interactive interpreter for any frame in + the stack. +* A full-featured request object with objects to interact with headers, + query args, form data, files, and cookies. +* A response object that can wrap other WSGI applications and handle + streaming data. +* A routing system for matching URLs to endpoints and generating URLs + for endpoints, with an extensible system for capturing variables from + URLs. +* HTTP utilities to handle entity tags, cache control, dates, user + agents, cookies, files, and more. +* A threaded WSGI server for use while developing applications locally. +* A test client for simulating HTTP requests during testing without + requiring running a server. + +Werkzeug is Unicode aware and doesn't enforce any dependencies. It is up +to the developer to choose a template engine, database adapter, and even +how to handle requests. It can be used to build all sorts of end user +applications such as blogs, wikis, or bulletin boards. + +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while +providing more structure and patterns for defining powerful +applications. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Werkzeug + + +A Simple Example +---------------- + +.. code-block:: python + + from werkzeug.wrappers import Request, Response + + @Request.application + def application(request): + return Response('Hello, World!') + + if __name__ == '__main__': + from werkzeug.serving import run_simple + run_simple('localhost', 4000, application) + + +Links +----- + +* Website: https://www.palletsprojects.com/p/werkzeug/ +* Releases: https://pypi.org/project/Werkzeug/ +* Code: https://github.com/pallets/werkzeug +* Issue tracker: https://github.com/pallets/werkzeug/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/werkzeug + * Windows: https://ci.appveyor.com/project/davidism/werkzeug + +* Test coverage: https://codecov.io/gh/pallets/werkzeug + +.. _WSGI: https://wsgi.readthedocs.io/en/latest/ +.. _Flask: https://www.palletsprojects.com/p/flask/ +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/RECORD b/Lib/site-packages/Werkzeug-0.14.1.dist-info/RECORD new file mode 100644 index 0000000..914b8e7 --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/RECORD @@ -0,0 +1,97 @@ +Werkzeug-0.14.1.dist-info/DESCRIPTION.rst,sha256=rOCN36jwsWtWsTpqPG96z7FMilB5qI1CIARSKRuUmz8,2452 +Werkzeug-0.14.1.dist-info/LICENSE.txt,sha256=xndz_dD4m269AF9l_Xbl5V3tM1N3C1LoZC2PEPxWO-8,1534 +Werkzeug-0.14.1.dist-info/METADATA,sha256=FbfadrPdJNUWAxMOKxGUtHe5R3IDSBKYYmAz3FvI3uY,3872 +Werkzeug-0.14.1.dist-info/RECORD,, +Werkzeug-0.14.1.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 +Werkzeug-0.14.1.dist-info/metadata.json,sha256=4489UTt6HBp2NQil95-pBkjU4Je93SMHvMxZ_rjOpqA,1452 +Werkzeug-0.14.1.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 +werkzeug/__init__.py,sha256=NR0d4n_-U9BLVKlOISean3zUt2vBwhvK-AZE6M0sC0k,6842 +werkzeug/_compat.py,sha256=8c4U9o6A_TR9nKCcTbpZNxpqCXcXDVIbFawwKM2s92c,6311 +werkzeug/_internal.py,sha256=GhEyGMlsSz_tYjsDWO9TG35VN7304MM8gjKDrXLEdVc,13873 +werkzeug/_reloader.py,sha256=AyPphcOHPbu6qzW0UbrVvTDJdre5WgpxbhIJN_TqzUc,9264 +werkzeug/datastructures.py,sha256=3IgNKNqrz-ZjmAG7y3YgEYK-enDiMT_b652PsypWcYg,90080 +werkzeug/exceptions.py,sha256=3wp95Hqj9FqV8MdikV99JRcHse_fSMn27V8tgP5Hw2c,20505 +werkzeug/filesystem.py,sha256=hHWeWo_gqLMzTRfYt8-7n2wWcWUNTnDyudQDLOBEICE,2175 +werkzeug/formparser.py,sha256=mUuCwjzjb8_E4RzrAT2AioLuZSYpqR1KXTK6LScRYzA,21722 +werkzeug/http.py,sha256=RQg4MJuhRv2isNRiEh__Phh09ebpfT3Kuu_GfrZ54_c,40079 +werkzeug/local.py,sha256=QdQhWV5L8p1Y1CJ1CDStwxaUs24SuN5aebHwjVD08C8,14553 +werkzeug/posixemulation.py,sha256=xEF2Bxc-vUCPkiu4IbfWVd3LW7DROYAT-ExW6THqyzw,3519 +werkzeug/routing.py,sha256=2JVtdSgxKGeANy4Z_FP-dKESvKtkYGCZ1J2fARCLGCY,67214 +werkzeug/script.py,sha256=DwaVDcXdaOTffdNvlBdLitxWXjKaRVT32VbhDtljFPY,11365 +werkzeug/security.py,sha256=0m107exslz4QJLWQCpfQJ04z3re4eGHVggRvrQVAdWc,9193 +werkzeug/serving.py,sha256=A0flnIJHufdn2QJ9oeuHfrXwP3LzP8fn3rNW6hbxKUg,31926 +werkzeug/test.py,sha256=XmECSmnpASiYQTct4oMiWr0LT5jHWCtKqnpYKZd2ui8,36100 +werkzeug/testapp.py,sha256=3HQRW1sHZKXuAjCvFMet4KXtQG3loYTFnvn6LWt-4zI,9396 +werkzeug/urls.py,sha256=dUeLg2IeTm0WLmSvFeD4hBZWGdOs-uHudR5-t8n9zPo,36771 +werkzeug/useragents.py,sha256=BhYMf4cBTHyN4U0WsQedePIocmNlH_34C-UwqSThGCc,5865 +werkzeug/utils.py,sha256=BrY1j0DHQ8RTb0K1StIobKuMJhN9SQQkWEARbrh2qpk,22972 +werkzeug/websocket.py,sha256=PpSeDxXD_0UsPAa5hQhQNM6mxibeUgn8lA8eRqiS0vM,11344 +werkzeug/wrappers.py,sha256=kbyL_aFjxELwPgMwfNCYjKu-CR6kNkh-oO8wv3GXbk8,84511 +werkzeug/wsgi.py,sha256=1Nob-aeChWQf7MsiicO8RZt6J90iRzEcik44ev9Qu8s,49347 +werkzeug/contrib/__init__.py,sha256=f7PfttZhbrImqpr5Ezre8CXgwvcGUJK7zWNpO34WWrw,623 +werkzeug/contrib/atom.py,sha256=qqfJcfIn2RYY-3hO3Oz0aLq9YuNubcPQ_KZcNsDwVJo,15575 +werkzeug/contrib/cache.py,sha256=xBImHNj09BmX_7kC5NUCx8f_l4L8_O7zi0jCL21UZKE,32163 +werkzeug/contrib/fixers.py,sha256=gR06T-w71ur-tHQ_31kP_4jpOncPJ4Wc1dOqTvYusr8,10179 +werkzeug/contrib/iterio.py,sha256=RlqDvGhz0RneTpzE8dVc-yWCUv4nkPl1jEc_EDp2fH0,10814 +werkzeug/contrib/jsrouting.py,sha256=QTmgeDoKXvNK02KzXgx9lr3cAH6fAzpwF5bBdPNvJPs,8564 +werkzeug/contrib/limiter.py,sha256=iS8-ahPZ-JLRnmfIBzxpm7O_s3lPsiDMVWv7llAIDCI,1334 +werkzeug/contrib/lint.py,sha256=Mj9NeUN7s4zIUWeQOAVjrmtZIcl3Mm2yDe9BSIr9YGE,12558 +werkzeug/contrib/profiler.py,sha256=ISwCWvwVyGpDLRBRpLjo_qUWma6GXYBrTAco4PEQSHY,5151 +werkzeug/contrib/securecookie.py,sha256=uWMyHDHY3lkeBRiCSayGqWkAIy4a7xAbSE_Hln9ecqc,12196 +werkzeug/contrib/sessions.py,sha256=39LVNvLbm5JWpbxM79WC2l87MJFbqeISARjwYbkJatw,12577 +werkzeug/contrib/testtools.py,sha256=G9xN-qeihJlhExrIZMCahvQOIDxdL9NiX874jiiHFMs,2453 +werkzeug/contrib/wrappers.py,sha256=v7OYlz7wQtDlS9fey75UiRZ1IkUWqCpzbhsLy4k14Hw,10398 +werkzeug/debug/__init__.py,sha256=uSn9BqCZ5E3ySgpoZtundpROGsn-uYvZtSFiTfAX24M,17452 +werkzeug/debug/console.py,sha256=n3-dsKk1TsjnN-u4ZgmuWCU_HO0qw5IA7ttjhyyMM6I,5607 +werkzeug/debug/repr.py,sha256=bKqstDYGfECpeLerd48s_hxuqK4b6UWnjMu3d_DHO8I,9340 +werkzeug/debug/tbtools.py,sha256=rBudXCmkVdAKIcdhxANxgf09g6kQjJWW9_5bjSpr4OY,18451 +werkzeug/debug/shared/FONT_LICENSE,sha256=LwAVEI1oYnvXiNMT9SnCH_TaLCxCpeHziDrMg0gPkAI,4673 +werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507 +werkzeug/debug/shared/debugger.js,sha256=PKPVYuyO4SX1hkqLOwCLvmIEO5154WatFYaXE-zIfKI,6264 +werkzeug/debug/shared/jquery.js,sha256=7LkWEzqTdpEfELxcZZlS6wAx5Ff13zZ83lYO2_ujj7g,95957 +werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191 +werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200 +werkzeug/debug/shared/source.png,sha256=RoGcBTE4CyCB85GBuDGTFlAnUqxwTBiIfDqW15EpnUQ,818 +werkzeug/debug/shared/style.css,sha256=IEO0PC2pWmh2aEyGCaN--txuWsRCliuhlbEhPDFwh0A,6270 +werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220 +Werkzeug-0.14.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +werkzeug/contrib/__pycache__/atom.cpython-37.pyc,, +werkzeug/contrib/__pycache__/cache.cpython-37.pyc,, +werkzeug/contrib/__pycache__/fixers.cpython-37.pyc,, +werkzeug/contrib/__pycache__/iterio.cpython-37.pyc,, +werkzeug/contrib/__pycache__/jsrouting.cpython-37.pyc,, +werkzeug/contrib/__pycache__/limiter.cpython-37.pyc,, +werkzeug/contrib/__pycache__/lint.cpython-37.pyc,, +werkzeug/contrib/__pycache__/profiler.cpython-37.pyc,, +werkzeug/contrib/__pycache__/securecookie.cpython-37.pyc,, +werkzeug/contrib/__pycache__/sessions.cpython-37.pyc,, +werkzeug/contrib/__pycache__/testtools.cpython-37.pyc,, +werkzeug/contrib/__pycache__/wrappers.cpython-37.pyc,, +werkzeug/contrib/__pycache__/__init__.cpython-37.pyc,, +werkzeug/debug/__pycache__/console.cpython-37.pyc,, +werkzeug/debug/__pycache__/repr.cpython-37.pyc,, +werkzeug/debug/__pycache__/tbtools.cpython-37.pyc,, +werkzeug/debug/__pycache__/__init__.cpython-37.pyc,, +werkzeug/__pycache__/datastructures.cpython-37.pyc,, +werkzeug/__pycache__/exceptions.cpython-37.pyc,, +werkzeug/__pycache__/filesystem.cpython-37.pyc,, +werkzeug/__pycache__/formparser.cpython-37.pyc,, +werkzeug/__pycache__/http.cpython-37.pyc,, +werkzeug/__pycache__/local.cpython-37.pyc,, +werkzeug/__pycache__/posixemulation.cpython-37.pyc,, +werkzeug/__pycache__/routing.cpython-37.pyc,, +werkzeug/__pycache__/script.cpython-37.pyc,, +werkzeug/__pycache__/security.cpython-37.pyc,, +werkzeug/__pycache__/serving.cpython-37.pyc,, +werkzeug/__pycache__/test.cpython-37.pyc,, +werkzeug/__pycache__/testapp.cpython-37.pyc,, +werkzeug/__pycache__/urls.cpython-37.pyc,, +werkzeug/__pycache__/useragents.cpython-37.pyc,, +werkzeug/__pycache__/utils.cpython-37.pyc,, +werkzeug/__pycache__/websocket.cpython-37.pyc,, +werkzeug/__pycache__/wrappers.cpython-37.pyc,, +werkzeug/__pycache__/wsgi.cpython-37.pyc,, +werkzeug/__pycache__/_compat.cpython-37.pyc,, +werkzeug/__pycache__/_internal.cpython-37.pyc,, +werkzeug/__pycache__/_reloader.cpython-37.pyc,, +werkzeug/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/WHEEL b/Lib/site-packages/Werkzeug-0.14.1.dist-info/WHEEL new file mode 100644 index 0000000..0de529b --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.26.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/metadata.json b/Lib/site-packages/Werkzeug-0.14.1.dist-info/metadata.json new file mode 100644 index 0000000..bca8d12 --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/metadata.json @@ -0,0 +1 @@ +{"generator": "bdist_wheel (0.26.0)", "summary": "The comprehensive WSGI web application library.", "classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"project_urls": {"Home": "https://www.palletsprojects.org/p/werkzeug/"}, "contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}}}, "license": "BSD", "metadata_version": "2.0", "name": "Werkzeug", "platform": "any", "extras": ["dev", "termcolor", "watchdog"], "run_requires": [{"requires": ["coverage", "pytest", "sphinx", "tox"], "extra": "dev"}, {"requires": ["termcolor"], "extra": "termcolor"}, {"requires": ["watchdog"], "extra": "watchdog"}], "version": "0.14.1"} \ No newline at end of file diff --git a/Lib/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt b/Lib/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt new file mode 100644 index 0000000..6fe8da8 --- /dev/null +++ b/Lib/site-packages/Werkzeug-0.14.1.dist-info/top_level.txt @@ -0,0 +1 @@ +werkzeug diff --git a/Lib/site-packages/__pycache__/easy_install.cpython-37.pyc b/Lib/site-packages/__pycache__/easy_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1708847d598452c84f1cdfacbb2070dcefa9f48c GIT binary patch literal 312 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 F`M(Zf17`pL literal 0 HcmV?d00001 diff --git a/Lib/site-packages/__pycache__/pytest.cpython-37.pyc b/Lib/site-packages/__pycache__/pytest.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9986e82cdba034e79b3d2987e0a9b69b0c2f4144 GIT binary patch literal 1758 zcmbtT$#UC95Cy=UB1MYYH;dXVQwuH8mMyzdso1jYQYBWYqBvEVuxbjy3@Mm105Slh zV`MD0GomER zq#WB>F)k~l65BaZl@p{E+j%i5r^u9?CeyKB5HoU?%*r`3C+Eq$Tp$Z_ku1isqF9p4 zT;E=#&$`p$#t?WH^_$EB%ASC8ESh-wqko+JdzF4klSQi?vNe1OLpZR z*^^DujN=vYSniX3c|ZTH#* zv30h=HrYeA#U8N++h#j#m+i48d(8H`tKD0vR!ba`L;j2({%-wY+?l_c zUJX{Ci0AT%9KpFqcLr3`x-c3~Z(GISCgNfAvflUHsBU|#-syWzKJjoZvD!Q zF6-wv(WUP-i~pdCjf_r9+x2wuLuhyTiBi7OIY%<#dR*r(eZLn5+(|4~2BKlT4m`L!GA%r$O+ z6#4hBzWtiMJ2}&tz*e?|BXSo!#Pb>{oj#4Y)P-YT2<|`zoqp>IEVR^dg&15ZY-Dxr z+;)0Ejn2OJSzmCSITmm`oj>)$$o3py>Ft1NU3kYmu53sL=V$F8Q2w>fD%%Zts4Spc zr4Z5x83Y(8LyaL65OC6TA>H`j96}zUf>1@6M3_LR0icemr>4=zxzuG4 z25thi*{U0=Sq#i0%poiy%pfcwEF(NXSV5>GtO4jerPv>oo&h)W6l&`S)Ja&Q9lOV6 z%u3^h&QZ#Ihf*?56D6CD?{(bnXD?2w!;M3_N7p11!&uTuAX-cjnHjDR`YG%O*a9(i zBsU1gl#Ws`{!_o(g#l0{xDtWByKgm88RmmF!=4*)J}S@eM~*K+!V&lPw8tut(lAS` z!4$H$fq-g!8g#vwb5b7e_k5UzM4MQaSfB;`bQ3?lrxFT=p-oi#oM5Cj%$n?`cHqXX z5G$$HAt8zcV?-(H>e-TmT-k&SUA(w~(Um7KM5A-z-hmydE%^3NL+xT=2>+fQzifYi z5f9rZXW#!&KX~4L6$EeW$Zmh*!=Sdm<1%OmZm{R#lnAl+^AYn^>)DHTa@ydp8Qkdn t7fB0!iDMCd1W0F=%&J)$yj3&trogXTRV$ma%>VahQ^i!?8c&t1{{X#K)5ZV* literal 0 HcmV?d00001 diff --git a/Lib/site-packages/__pycache__/six.cpython-37.pyc b/Lib/site-packages/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..56a6321f220d6e77af1419586957cfe8bf81f693 GIT binary patch literal 24970 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 j-N@XjtTh7sBdKHzNr$o zGhrigr@Qa&boYICIT-Z7TmE66)*in?(^=+=b022kCk8L1fOg0Ti#TbbA|~(vVmpB< zS@!gVKyVfp@d8Bj2rQYyXv6gp-zsftDGbkTgy^+r)r?*w3sH)Yt v7RGx1@#_(jdhg(vs@7JcUQi&dkisPx1dLlcvEV~{%vL}}7npKN}*d+-I z1mN9;C3@&9yLatOAD|cZUHck+hu+{eSAK=uwBK2P6sMyc^k`x54NmnpT)5S>xXo*^J*stUBd6<(>fO3cb57joHq71ay13Wl z=BU|i+SV{PTFpe6iF$^~g#-u3KXHz?08yi+-Z< z`ZRC7v2E+ImDGM~iG`O|_Y7a)-Ycv7Ub4g&%Mo`l>pZa9OToWjY!JukA?pQdxDlqK zEEYOS6V^{93*;aRq!R2f(nETx)&-0DEJ~Edr-FNl5M0eKU)lP+^UKa9BO@E@A;ewm ze6e}4bCIp3F&C0O6H-BoV*MbBJ)N?ClyIhpf{lVf6f&h{lnmCHN|}G{yIb4$zP*2U zXK#mzV?0Jl_G}C1m zIsxb8hf%$@ohJQg(DBI^Kb1Z-t+RyO+*&=qN+15OqurUgzx8f3JntU7g{&aU;>xj^ zo9oD!0U}T`P0Ao8w<$s-$m1#SVIJqrHF*OR6|Ia*5FkcKsDVO10w}O}Y?T*iAgz~c zzy=G4B91$3?RI}2%?4|L)C}>dL)<=EFRq7*}3uX zzPD8#1||cM2noz1s8hF@3T2dOQ$QyQ(_7mVI^3jLzj_^*=yoc!)KamGg96tkOy$GcG6F(VN1ZN@! zB<5X0q1+qv%=nWEs^rgA`sA3?+8zoVIY|bzVVDv}$Yh=JUph_ikkv%{fCAdw;#!kKggGp8jjRlAIwI5KfU0c`sQKU)`| zP3B3t{C}bU)3w841S0_?;{Ub*gb0Tz`}8WthJnoE=d@!}c*^aS(8CC9JpqgRX`b+P zc7fgjGRb$;w2np~jz}Bt456870;Z4xL`6uMf}V2)cT3afYkKPfZQL^trxub?#^P$L z)kBHiBVc#Lc!%U&W~*kezrDM&$|~njJ7BF$kX{rAkrF(Cq(Pkau)EKvr>qn(?OXI- zR@*5~2R)U>;CH{oXVK!(vxs_+VmU*Pq5Xcv6^6mZ%;R|=jUjyDyiut3*$hky|4zsbkLp7 zZJdg_%ZWX)d^C`dYLjt`WjB(_NT_zLs4EfoWfL#{!;%ZQ{qSh}^8Q2gB5HqU_cxE( zg)jH7W!a5D2m5zZRNVfa7-jq5^BIRe{fejZi%Y-S2k3;-`~LJk7g8`$(enK$iL~!u zC)#`Q0) z7xr|eoISdvo0G;%`-b)V^DkVZy)|*sU;lmL@)q8AC-v706L;d2R+6Nre|=<4>XhQ= zpQQ<~SoMe~g#>5GPt$S-zSLVA{_aY;7WVlc?5l78jpKQ(gYjnDD{84K>RF(Ng`-4P zII&2IX4T0Rt~k;n;j%$ry9yhJ;6)=+ST9_ZJJ#AwNq;p8Hlrku`VKv|xc|6+fs;r|zvm9u-ZZFfHmVo<)C zc2j6`%~nG-wm4S^#Zr*#bV}!_N4M;k=PWj{Jbhwc>p^!_Gx8T0zhfa;X)GjDt5P=t z+qV1+QzwKQ0Yl7J0^4Wh3Z5v!{aoh~5tdY*l4whkOkiuQg`k0@vn}=n^3P7{q}AMj*ohh>JOZL<&O`LkeRsgCvsFxJF;F7L)h{ek!O%R$v7o>uu_Q6ZCqFqcCnh8{w;-k< zvp_d9uec;JCr7u?A|=1b$jmaPpt2;jxFjYXMng^4E2zB1VUwGmQks)$#{zN?5HkP( D9KSKe literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/cacheprovider.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/cacheprovider.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8dd6690d6be9ea3ba058422b6f511329588e84e7 GIT binary patch literal 12268 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/capture.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/capture.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d38eccc0ac7a8a1214c88b5a9e5fd054892dbbf1 GIT binary patch literal 24636 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Ν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 aI5D$&*>ui3uhy1p^R=Qg?_6|BPVxU)J^T9r literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/deprecated.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/deprecated.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0313849c02a202d53cb8ff7d30b6ce401e2284cc GIT binary patch literal 3101 zcma)8O>^7G5hX=hmTAkDKeqO;mnr9BZHdtC)>byF%5E)Jf>bQ?Lq&ql8dhp*gc*v6 z0Sr7CNFuj#a{foo$t8zelRu(Us&YyGLQZ)Nfco+tOqGBEW_r5&^?N<|aecj2!_R$h z-~9c4t@dwvSpJ$A{DA-L92Z&hYqBm^qI$gIufz?%5jXv2y>?KO4cYutO*Yk?_YHql z-tq6sRew$1_3z0wza{Va_hrj}An*I@YE?dXU-uv4zK;7N`Ox3M_z}jB<%a(RmtYsc47U;x^Fv*xysZoKjp-xz=vP_()jEO|Det^Ml>r>_ z>V5^Xlg`Z@H~`UW*$OUe_2PLkN|6v1Qn1Vdxf3c?Y3{^e+KWvh$kj$$j0~_k3c&~P zOqi2AM)6T=M5Bas7VbP$5!eLAU?q5W-MpxFFjGY5Utru7go}UtOd$Pn2j+mih;164 zm!RiG%+Jf!MX?bF=g%2bfkiiCE*bVQJ{`sm3x-!!E#y*dNr6L8#j77GgsONbLT!Wv zEiOU$*M1o*E3;rI93?D6$ks-4hgI_>LW#DJu}EyC!CR}h3K#I6}E5&BkrrFN+Hn^988f5KgbF!_H?FcS1yIp1G z%xoMLe2;a}KtO$RtrKT4cvD*bo@Gdh8WB3d&(kncMco*Uz>1sfAq3x8t)rc#@g-v4 z(i|9dqAX>Cf}V;fN7wpr2U=3XTP#`pwcUmk^T@U%jh=Mf;8yWTx`krVs}OD(1cPFo z*2e*pQ>!gt`BhO5NT%`)*XFeKuLm#8 z3925$EJL-!U{Et3w zww4>+^Z*)@;Z^g5j9c14;MWf5Tk5&SxXVqi0eo4m#XtAZq3Kku%FELz zKS41`jsh7cZL8CEq)t^t5||dP?S`bc5Jn(~AV^hAr-g{u0!)3-Zq7m=c@3&e>twL` ziMfY^mp%rjIh|sh8#;+igD&*NdGTcL>Z`8$^e9egf4$%74*1v`@y_UA?B9Rgb$ff< zbI0D;f4Dyx?BX>)9J%}5pZrg7@g^ge(|fNw9Pr&vujfD6-N%yGWW&d9G2uTtaJ|a< zRi`&`{np4GPkJ8j4G;XM{m$qm?+*5dyyJPJ?vE4C^*<|K9(G2ZzU#T8vFq{4;IOm% zvO9pq$lV=|_V`cz9)cMjx+Cv3{0@6P_#2LRzw^@VdT!r;4C4+t=AFI0GQ7{L&<=Z( zgYIC=_eaA%A0T*dc*uM1E4RmYhl70z-`}X#4iLl`&fTkTr*cGJITvfcEx) zZe~@BWV^B95NMASVNHzf@xC8`!ghomJ3efzeb}|f7kkzY`>^3-ogDUQPPVUe^7s8& z{Qv|-%sAX+WmRQn<>Sx)@%?`$-W?q+8u-m^$Dh3Ru3`L7zVv<>JiLP|YM6!*7@iTB zfmJs*EzjDtJ$uvf9Fuu=J>zBMp7pYF&v`ky=e<1cPQ9>M^opA!-pFRjE6F#R`sn7E zH-_h|Hy-4?i6HMC3JTt2Q1lLmfn7Noj0B~phBpZx`f=S#@yk`W5gCkFk;7C~7w!M>hKN?KoeJXqg@27%e!Ew|(9b64g2G2Y-y=PJ5 zRB#$KPKWu8=TOHDo(-Nuo#z8LcpmpN!I|I%++RS=v%xvkJcpWRQS)5zV(=15UPQ_H zU>YUUX~|2$%fTxsIUigIF5*5N%mkNke>u1uyo&oP!Ij`O+%E*L2j9W{BEFjmz8k#p zl^MJleDA5TZF-ji`?fLtw>sZ(gIZK=eikaX(goY5r7j zY|RLc2Pen{{oGU1!fCAkpoQlo51gR$0t0Jurkos3m%widwN~quwWxDKzqs<|t~OPF zp%SN})}kaock|}Lt=kK?r>(?^pR~dx7lf;oc0EoedJTq+YBQ)c);iDip4@g62E)zi zCGKR}@#@7lr%g2uf+e|XvtAFYap%y*i)mXIQ{G65QQTCaAFFma-+6972UY5Icc%5E z$4SXp`g!{Gw3B2j!XdgNXFaU95+}fNcP0jXsgUfYs6{&8tFAYjQ3#%F#_QnQW;<@R z!I@39S&O7-!draUihycz>VR9<%$k&xp>Gac2PY;@| zHXCuR(GD**8y8a|b>1RxRou1OXJMa$7u;S=H*SiSsH|d|E*1duhtTy&{7kRw-UoiO z(UZt&Xzoe?{;PTUwJ=^&&34NxAV;%yVn?w`GWF)8P$g407H5~|ZZG>wbGH_kmi^i9 zFD}f^k+-w0ii%JpBj5iEL!AX3f3-Aw_1+z1NB8E+AAan<`o_KMt=5f7T)9W}Qopwx zZno~VYORa4Mihf7FFt%TXsRpU{ocLS6RyxbKfR~p2hS!GI?L~m@HzAp-9loRj%mri zqUD$+tJr_H%sg_e{=0tDb$ey{ZMa0eh&HQKRQ%bv99*KXet-w48)M6YiZTQ9fu$~Y ztqp6#R`apbMQ+#JwxjttBTv?CqcIg{d-*b4jvC17AbDPd5S**}%Z7s1wux3^- zfjW%dl9FGG{3wjuEf6Icy`c@l2Vx775f-LIO2*T&Wwb%l04?u80@h`b!bYrKLVL16 zIyuMY52s{Jbqch0J^U>cL?tAKnKg^%5wnDU>N4J|qy~Sa2q`2~A-zZy(8E?^0cPDb zcg$U5%MR?W{UF;q8#uf}p=QdRyi5kuo`<&Lyy9lF9wi0XzPKIN>Jiu~zfy_9MrAWh z92HiAX-AKJ1|6wONRm7`8gq*F%}2eAQV&-|BV%Cnj+r+lw?B4*oc@a5#7jE%tU8Ic zGDqZZ4u6(E+WFlMUjVf6uO z%MuRAkfHX95{I|_l(>L~E4U)+Rl}SDB_=?R66wLRDzke(uH`$pqEkph!!rZJvjF5Q zKo(FSaB#|E)sIZYfQ_wtg&931CN8&THjCoH&*QUl@ zGqyg|BbBkDn5(ytJirx^@$+Whk(@m&V55Y;JuL7eV-;!+Y>@ZtA3g z4w-iC^rGt5wB#rs;Sz>~F!8-lN#b16SSEf351^h=H@-C9GlZ5_U_Z?V_7^Z8+x8Za zE$Hc#6+i2@foExh_vpJw1_B9T9FcZ1LH23EbL1H~8S9gg=R#1#bCxP;y41O(Q>w+4)E>8dhG!kS=j)l?N`?%S*}u! z`Qtr{i#9QO76~W_8q%D?yxM^&euD$HvQpCuHqD9J1U$*Xr&<9{O-8gr72J*rBR9g8 z_L`om=77ToK_xBdinc<1z@*HC*n`SE&?b2wL;ih~MjWwWXU#FI^X6~36n$3hlYotp z3_=2$jW3KHsI0CH1!ivnacr2%g+jBs87j1f)6IMi=F`g8PR6j(%K%rYtjh4!2{bdE z6%k8ptOcAER7rB->2%v6ra?4EaAW8D!<0^&^1b!E<-<PzeCm|?A>Nm(RFVAg&caz-BGxg? z?t{DCE!a$GD@@>Zn ztX*>_vrA|ajA5M>E8JHCM2`m~$Z~Nz+LnTuF=bU*73B9#Eyp%~?ox{WPPHXmO&RJ6u zgkxxnV+06ywf{Mx{WkjK;1Bq23>vB*z+cNyBEK>B* zJ9qm)UG-Xn!gv?Lon0b1G=uP+&G)!S<|IF3@^qj#utys4-i zF&O644Xo7Dg@N(L=V(JfR+4$7z@zdCq@6OSm&GX1qAWgw4@&J@CDjCVe}PN$rc=V& zjNzJqAKAG)yhgtccl6zZLufIFi;Ecj9Ew1rP-S5UE z%VNMAb(MJ=S=6>+FbY30)xQL@J3lcWe@Nf%C+7W|fJB*%+*TH8{!8M;!d4DxQ4Gvu z^ptN*@V%SeC?3PYA45(&(#>p}8>Ov6Jlf55^W6eadNCf`Hnv9MaR|}G&LJ|@wz*a6 z=F^@5xHj?|lRJk42kbT~3ZD2pA0O$CZksm{bpXQ;<83*=}3%j6VOKb;8&h zZG1P#V}_$aVQcL1%P5=LIV@`J)Yf=+bmv%5?2dKESFI^Sm~>=o>?h{K<9ChtcsD~@ zZCjwgN_Vt7vU8%#8K3NycI};Kg3_+}2HT&BPa*d-Ml#VI4MyWsu>+Brs7Q3UQKfK{v=;`?`>fbivGw}=J$epEHy{*;in1&<2q)J!Ekj(dG zl}k+PC8+g9Jgh-G-G3HRXmYu`CV@Q2Zyp1d{ueUEM}q~rFwCmJZK?-Z2ky|| z!(SHgW#{d=kFI}k>*kz$b8+_i^1@=-y;FX_ym+^K!9}p!jnQrNhaj$BZ zD8pjBC0psxsPV&Zn5#Js4;y`AeJ`@ zIb<9NvC&2~R7;%P$4nRo(M~emVL_=ff4IvC+lh((J1iiA(YTP<3V{M5oSrWLUv7{&-p~MFtQ&-RJQLjizw0?O)-2*2O5+lTWbUim%bwv zYT`Ply`+$*$9CsXL;V=Zf5Vl=q8Uk^ge8M5lSnijA^t0xSxd*?h%3iXHfAFlXS;S5 zUrfk1;xw5>lpT?rJfdCS#<+a}qs;YT0QX9ur346IS4@oml(EYFMFg8mpI~*#toO-n z*zH*b;)&PAz6*&2r(kvhTtuk)l9d!SsYvVs`qbe#vop1CfN%#{1>KdWi~F1t?UQU` zjOrm18W*9T`p0~FpGm*hl-4@tQbEz5;S!*bH^*}MVm_ZQmEI6MTSbZdNDE?5u48l= zNorRl_ymgrD1?h(i0*P0S1!(P8*yP9`v0rE07Qw!AS91XkMgpAeU<|1FE8Dh^XC_r z{8y8s!};&tyk36)=0bTcIZ|F+`r!J_1#iy3`~3y%mfX5NJEul5hUD17dnlaq`@-(u zm|MQSa5I^hUHstI^`(W|i)DZQ=Joe(C!^PI-dw!v-zhK5F5Z|+M)d2uAEP}`Q+T|F zCe=@w(8*N4!-UITE5i1U=Z5x$%XY+_K%2Z6q4QP0a_pSKmP%)_X0?@inSK;@TErlS)3R^qsqMSp-K z6(y<^#F*%L$u1aBHc|AJ%{{LT8vujiWdoXJxNlH1x3b*zLOw(d3Mofni;HY!TekZJ zbODKPi)XS^!oE?VTi6)|M*zrRkHy^0Y!$o3jWP8*fMCUq3B&~Q-Qu?MAtK4*)nzsO zP!kxYs2oPjH!FbCK7j5A%%zv00|yeeJES>YDE=ob`bS8-0ymrd82e}HIcC1bWQWP8 zOtzVjyl|4>75Y)D*<9sT<$AMm#pBl8GIZ-L*%9?d$WW=eWhhDFX_0on=?zYgXe~?0 zLwR}@fblo<{yBSME$uzZ;8*y1hRFc(2%m@*I)s8NLj5^#~l zaCmGAOyb=Stx~1o*-5Ns30AD@Q>d14L z?vK)>_E8p}KaP)YEk8ocpHp zJp@pDUv!=yfX>uKcUPXcudr8F4+P67jAf&y`e*16o4^w8$8H;_hp~}~yb%=ly?ice zZ=k|c4P<=4(aBz_ledmjzcBY;{X)|)&@a8cL+U;C3O_pu zR)0~Hh_fSMZK|5ajVEJN8ar7i2Ow+B*|4N!G@pT`=eU zQ}83R8pjabxyV$vN?jlfIc~r z9>HI(edY`7J?{`WZj#>8E+Z zTXmpXb5>ENF&lYiNLl5ElvP&mKmtALmIm7C+Z5BsWTF?*B7s8*fh_=F{NoeU6O>e6 zLD@&BoQ|f-NuP4)sV0VgZ*W+1Oy-$(b1t2A;@Q;0f{4;gd?duKa~qDgS%C7>YgQ>}7fFU@0A zm*F9aeafJB{Y<*Ts}w4P+di^6T`bZkV0Z`{I}b zg~FQUdH4Z1%LkVDbF`7zRh-4hvxMi^u)XlF+437mz<23*dm*SX=(;qEGw@2i3Njx` zxHrlJCH1rtTn?`kr14e;Or=ZDTHTb`>d>4-{j8&bHYY-}Ze;SOfvW$U5_g{dJ`+JumQb?c&QP_%JqL-PyQkX)dyz9vwvzb@c&Z; zbayQ;D{sh?w_JZsGuU3q>jOERS2TRq%QRsB0|(OinT*)QZ?@U0@i?YxZuThWH?WE9 z>#!@7yDlSn8};}BmaWM>?5q72*vfhwx1y_;F0Iw#_4W#M+2$oymPFH-wdUIj%_x8w zoN5YE3fCj7Z@a}ER;U&1xFZ}Rq|>D2cb#MB@7?YGaQc(>o%`oMQA_vV{^Z_E_s-m( z?iZ}QySJd)qbuc;TJSJwOt+DNI7D8d@wlnH>j20*I0gmhplj1*d&fXT)sAg>0yK}V zcC*n{LNv&cXvwGftz0*QI3xf+ylluHfRla(yoW~3s^6A(Za(zN5Wi&ELA|HZ#Y}m5 zz8^a7;WHWbm<)RdDjR0p+@&%`n8UgE>b)!Qt!zjn&KG4=xE4N6Y#hl#rlmryXsBb7 zaTRXjz_s6#xPLXIIDhLmV4E4eX`+K)0~XuYI<{9v_pp6Z8vaiGA%>)QC^|XZ_uJDo z$A(;T$k#smAPaj{v|pa{sDgkM18w5yU;`$MyitI=K>$Fo9$uvh^;f705J-%u{*p=G zfT(|m*RM$i7Z2RTgO`tpl(eE^yg z3wPcS{je0SAyADovZ8iXYFnsF_8JHVE3~|89jSgF?WSW)4uiF&m7&l@55mie4wjX? z#hsSO!Gi%XFWmMU4*fg7*3czfC1>OJ44grP9&!HzpAQT>3IG4~o`F&#`pyI8zaQee zfR~iUCiaQ}+ptfJjUn!CZZPg(Zsg-aVAcTJPRRam=YPl)mU%>}_xBL)F!gZ&9*64O zPg8UDX%DG$9dODCo4ps@N1;oB)BAjGEp{u|_(N=*_f``pIe8GOXCtLQjn8Q(2MzOY zJm|>Puy+uI+`vN=pa!ciMwg=AX^7d_2%X_NITXO#30W6kpe(cXLEa6!BJc6Nj zmgc+@>1e)Ll$<=ck@8}B4l3S$5I)f&y^rgkf#ubvPcP%d);%aqz;6;v2n- zM6=Zu@@eEPVRX#`8vi=MD zpgY0incEB-!3>-Mv;vb*rcQRKuqo0b4&2t`33slvJoG zX&kI6f2=ao^KJy&qJthj6_}KwM-BbJ)q|!vOTnO+5~O1@oifi5O8e=Tl{!OkoG*jc z0Gj+vwxgmHk!r~mbj-qDb1I|&0+0f*Mo~L-U%2x6Yp)N<15Cf;-}?9p&mkB5-Wv4v zA68t}p7-b^k{;qr5oLM?R@T+&od0J0Z(#fG=!m;?u}5u@w*F3|HsXUv~;KFz}-H4)DL(bk86k&~;K8rp5o}7^uGCkN*vB(;06p z{X-AJV(_i{FKkah30w2>*zJ1|0#tzpD=dPOJNRWYeyDtkjRwQFrZ)c$Y*2} z--iwXURDB~a5#Lm&A-vZ=|9q0k>QlXpO`$)#Aos%lgmtAW^#eaTS$_^TH5G~l)9|5mrKVi#M0uhm#RtrEv=}o zap7hA)-jJrbb$a5fA(U7bM!yEcN8#-Gm-f#`9dB$kQ1eeZ2nAfbh45kM^16_+5E`l Q>HK8=4ZIcd6Zw<>7q}$dasU7T literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/experiments.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/experiments.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14bab90918adde124baa3505c92dd5857650802b GIT binary patch literal 729 zcmaJ0T)a=|dC9Worb8*02^?QZGG_T$g0jQeUj&b-J z{vqVlxRJUz@amKGRrka^)q_N;6%|Y7rXKf$s`sq4r54S5*U5GB=-Om94Ns@xD>`~P fnbGj=@WtdL+<|j@)ef`jKHARyxCVA>KiK~R-OtBX literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/fixtures.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/fixtures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7af7e5184d856ac723c3bf74b7ab66c30b1a190b GIT binary patch literal 38369 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/helpconfig.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/helpconfig.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05f6ad83d63a628c3336d0f0d0681ab8e44f2d12 GIT binary patch literal 6259 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 LLyP<5?LGek<+TG- literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/junitxml.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/junitxml.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6c4305c9e7e50eef26599c7be57f79f32b6d7ab GIT binary patch literal 16429 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 S#@X6@ZK`$%2R4nvoB0ng-Ha0e literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/logging.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/logging.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74ed7982578f761f0df446d30f4234cbf726d7da GIT binary patch literal 17575 zcmd6O+jAUOdS74W(lZ!<0C*E6QEbts$k7sztX)eoR#C_$2}w2tazRMi9Z?<)ryIb4 zgXz)f9)cJTY-gcF>kD_wams7^#ekDk>?D=iN^EaZE|)i(RGf$S!LC##>B`$yrELEJ ze%Q)Ge!uT@_soD0r7FJ!WS=>G`kd3}@?C!4cfS70r5X z;0g<-VR%N(@J!EYn_E`R+Oli*R<4#aS!TEMwLE@v?ZQ^ER@`!GPEuZ~mE?K3R>p6> zJ+W1(Rg!0uwMlt4Rh#k(wPRkfHvNX-IbP{w!z=mu&6z#BHtUtWiI0uiaj)V{;`fB_ zc&<0)9sAhaGixVNf7+Wt{Tb9hh5DyaGV2{j$#MS)+@J9$H=p!QcqczLQ2#0Kly@4v zJncQc@Fo_c;|3`F6rC#?Au25+5V5YSDQ^g4BbY@ zbDKdYQbF5o2kUOL(T#el)mfi+|C&o!wc}%ryJ67oMSi`t)eTe>J6`L4D{KXwc&dx4 zQGKn~X-2qTu3B-i*$zUqkEhtJ{~+3GbQIr?KT%=U)2B(7kY}-Rk(Ap!y|`dH=rO)(>Chvn`ApJyyfMbK%W}3vVx6xZUJX z)4!=C6Gq7RM$Pn$n&p`_+s|$0J!`|nZ^5%Xd&5Gm=;fruNq$RSUhd0YL4GIv%AV0G z)+YU_eeCanS)2aESTkjho!X4#xxY?r_7fwAUB>!W;*-~ccA$K3iDO?3)K(+nOut%o z@h8t(ecz2X{IU7X&xdZep&~a}lV{wJHEE3EF!Vh)3fy|V)oDfb`n>cN+jvWyyBoB< zT4Bd;w}b6Czpi}0Q!8|Ps@wMaXD-|suHl{PrT4!u_rc%4<2@f%n^v+^6ZkFQI)*F! zE|SQI%z?3IZCV3sV1LUrjmX~2sq+J4Ge0oug-#i{qRzJrlsLFA?Xxt0VD9Dyx$sTT zxNQt_`x6JoZvH_HPb&M92gY^dgQYvxZeh1L0J}w4)Is6EY?-HwU5A_Uu`wuK2chql z2Il7Uz*#c~rEi(L?76f*Gth6aaOVsPuNfcRc@IpDCC@F#rHoLTV0HQ9{3rl!;|gby zaI7DccR>;Z^VhA9a%gF;{=NaawdP-pbEGmgiF%U!Xyw|%op(ZCg?DZ&zx#FfCtkU8 zwcEYkh#Gg6f@Y(AXVu^8-s!fwbFEGoHQMdDk6!fx_0r2fb*H-%`C)XYp8R4X*U3}e zogbB7^IFZQ8Ekc5|4ELDLo68mmyRTu`E0XaYx9la>+{3r)!8^7_PV}O4*H0lv~FyN ztp~Av>+3JYx%%2x6i?Oz)x!J1al9?m!)T}N$0zHuVD%_qaeb@N?UHYgFWq?e#?tcD zw{O%J-(Ib++<4>0*WyCxH&k6tq+Rde#D>rYg-j4I&<*hI-CUcD| z>wYBUzl=q#6}B4c9$MOA?{0M>&V_z^tu~cP0xbyQTtlsgapB%Je{09H{Y=IeH8*OL zV})^EZfoTx*{vRQBQ(<-6ZxK=ANRCY(G`-O&&nM*(5oL&8Ir10uQ%J^xO!bv!!$|a zIFj?YLMDbeYZlD1RW=LOl$pan$2wtJ=5&sCWvgKJpLzV2X3S@!Hxem-!&i}jxQ%@i zYTyRs6F<(U1a zkDhVT^$C(FccWg9%k}zJ;Pu+fSL*eTdJU2AxGUD{UeLtCpW`^3Yb$T9zIE;DQk=iB zvT}1JF1~klW%;e;H{u*Kaqg|<#hY>d`i-x=^F~})zPWn)#wuvckJMQ;0nFRO$g0&pE<>Jx-wI878fbxnmKmPcFeNrB>yT_*{VDx>z7F!ZX~Za z*yv>>4_+LYka?GOv1$9pz=CwN2exP2bJTMvG1C%N7(g|DR7m6*w$h4A*hSDZHEjV| z$o*J)S}fas*maV=Qt&6(j~`z&Vsbr|Jssv$0bY zm2e3m{vTw%Y3>6W9hkplcwhL$_{3a;eD-o5mv%v%UfwHsMXEu<8?W-PXhNoXlK?iB zcg&l92v~*t8E-Z+z2n(EU`%8I!pQS)nwz$F8hw-rW|9^FGw9*zti@SC7;B`5a{y0S z4|v0~-g(^rSXTeXy$iU1F1x?zT^buf)q8$80?z{5T<%}E>UpkStB^YOXhb9=x!mOT z@-L5zO7kgP;fqKx9ZZ=D(}VInZFm-^^i5+EcR&pG0BUZK`;J9*nkcRQtmm&adhN)) z-)Q%IYI_%utC*C=xoD^B$GHu^-Hme|R0^n~(C|ELXsv`_J?3gYF6f-Pj&Z1~OuoY8 z$B|Sm^)!Cs0-yzy*^rOpDfBQxBBCWZBLk!{YxOT_?N!g-GoNXp@rM0lb90?wPQc(C zjHk2~~o2f6i-#jk|5%l{!#60G_?|jffaDbc2q&)&R=_ z?_kQ|e6=9+!psF`#(C*%WSZA7=KjPS-#sTnPY*z{{YxmN_I2gf?GZ=a-AMtKJkhcU z!f&{I(q%<=sRdYE=A?AKUqwE}W{vPMozC}XbSEC5?_AQ;G4{lQw7YqB$AZt-r)XJ- zuU7vnfX!S-Y2OOF?Z%Gl34oWib5*b7UIK6k+H9lblK$B};a4SYvc8j;GZ|*Q2cK(kzG_ zR$#9GLbnlZkUtwP@7?VUzmtt)yVY*HcTotVB0_l-WP@VmWF|5w-X~Kzjm~vv$c)Y> z*)?f8x@*!lnbE1?DCb6}bRr$`=pI+C<>hLw=0GebAnN*!#jEcut=0ji>Wep5-oCmT zpB^o{esvWXOdhBkpl~oU)rxwPiKr^g*}7DO{`6s%g*j}510)8N)pWrEL>c~btTcag zE|=8h)2Yv>`?#Le`*?rT<|yz-2}3p0#1;M%BoWjgj0DI>&%9SsPeLtPL^Mz!mXusZ ziA_a`5@P^EL?Fa_Oz}k~meV7gJ8m0l|3i&L3{vzuP zV633eocb2-V8Zb3Yp4UIVD+zE(*~@YSg?>7jR*qEhaB~xCSbg6Zv>k6v=nJHH(6~L3l)Fg}@+$|BO#m)wdap06NE%Bpg|r_I?hmVscW+biVvEzTZu?o|`UM3o5~Fx5CI}4#0wVks@|%6_=}d z)yCVPfxBJ59G+hXWq*b%nP0{1pL%qD>||`KI6s*ifwyc6 zJQADMzJ0(g$_ab|M%KepEmTsQOzt6pwJN)E^n%BEaIYWzH&oO^0x9=TKRP6-#f`qq ze&?9XGkJjtH(GIKs>?)7qhUf(tk#kIDXx$5>y_vdb@;C>4T)NMTKIE1^33^(*0j*)4$m0T9!W1}u^ zm^!4r$k|ild`4#??0@i>73b@8D#XXd<<)}!096<)aD}i%h1uNIwf) z3tB;}>E)X*i?hzf-|9vy1otJfE9EkQrlH$}fLYh@bYaVnHWoevrRoWPsQrEHf@B|J zc#2|7v*I1*eilg;PCER=6Idxof3df<4k_r8LrVo$$67Mt|Als;!2iMti1_|fOPM6j zmMpD1#;aUESu;{PS8P+95&bV@lU`7?V;0HssCiWIr2sFu81yZ}?Fv z7e(QxLKNy3HjAISZM#7jwg}2;y|~?tM(Bql6tDpN(AaVzqXfV%WZiRb-`i+40dcd2 z6ve^ar~&CrTFKt1f~|S?T~L~*El2RB!UCTMz4W^0FT3aAEo`3`_x||^zB>=#|NQ76 z(j9^5f1i{Ar9Y1)ToJ#|2icew;92OY&Vrsd^#qt*Gdk!r9S(32N4E~cqJxRSJ3l1& z`FZy~Kn>Ii)Qj&eEVy5s|5DaJAhF)~*+(`$R2Q*FqIXiaRE~&Ww*D{~PteYsg-I7aG^5pyQ3=qpJH3o#F_lA%#|A3Y#hUK1}!$8!W9 zCB2OeDO)DWTO5H|@Y{p)>AA;J+5P{L4lO|!pqd6rzSRZUkQh^brJV6-r&Z$dC;xY*1?d0Uj zQaq!I&BPZYz=7+C!vR7uIUG2a?g&p zqQ+J?yzKf>6Xe>s#~J$%;1|P^XqLbfLw5@SSLJE}L#catR@ncGo{=9O#= z8Qqd*iSmS#c_<>BTp=g#8wbWH|C;LO@f<>w?5ci&$sv&cizqvnat}C_Dm1ZPQ)!-2 zb>=+%yiDq(O=r?K7*j_9*|b_V#WB|8*eROnW66xcS665Q$xe##cSs16hq%j`q6Z;p zWd~HQRZ17#9<5T~o^1nhJev*L8a1!dWsy3|nNw&Cd(+|?Si3eILjxOFn+IOR-EabJ z=4jInEI59|MWk_eb|um>>@Y|@&FI$>7npM^JG@w9No|x8QPFH5)) zO&wiupAC9U#yK=Dp{Z8y7f6r-3nzF&JAI^ulhq!h%*!?Gq@lzPUkv>Jd^m7pI)isJgZu-d5U8JVCNC6Hr7($oNvt`y~4uTln zA5wT451_YagiikdBVkPwq>9`KRnRN?DMa8OK?F`Cp@El414Q6Mc56IyxXJ8tTw=$W*RJO)yyp>2?{m18D#uNrC4p(iq%f@FaiK zgU(@iMu5z?XgfY1P0<2Oj;;>ejGk*i<9vy4cnXerKkk|aLI2QNv0!gGfL6wF5h z6mIG81Q>V`&bS#6wr8m~;Rb{EeAnKYjtWsRa-gK`J)34=&WK9)%IfD$kRF`U<^2iI z+OJTFA3%J5!~D9@v69mkyPw#yLPdbH2nZ3iMrzQ?Z@C{_{JGtWDP-hou6G#2L(B*( zQ$y862{JZ9005iJySD&HU_yezLijM1MANZnlI)>|y)7XZzv0bSC)Jm+O6oNvaTyVh z2^mQ!4UTcd-l)^F6~_4<9OEjsq5R__Og+T=DUnxk8D5&6e?zH2;Rs&h!fNGr7{MrI z5{v@b#(0|ABs2lSJl4f+7uI-El-;Ujj%6q;WXDg?jiHxo=o@{H`%mAXVGlz+3Rcdl z;M@iwN;u2Q!5^)D9W^q#K%1fSlTLSy8L`ta=@A6Ng9Lg(tmQt>P|0C)-F6SZh*y}@ zx#XZMc9g#ka|-J*xumP!(lt$)=HW@ChnCnL1h&B2+~ou)$qZ9{2Pp+w_Q!#Wgk$iL zC&zlpX~0OohnDG7-Ro^_?Jx*|@&~bQ5|bKb@3GWxCf#Q5v5~uiEBx0;KCffmcQ#9m ziFs&dj`{LPS?Zvl7%58~^_7vb)L}n4QYIn6aNf+q1&^|fP4WcppPBTFK(K^B;i?mM|A$S5|dzyRWX^}&W715C? zo|d6J=NBJXU9Vz1bv1S7X)(CScm5WWD^gWQmP68nT8x$!(<5``u@;4w9yf;^Pb?y) z<4t`G8&9K|M2w_o-s%I^k*FJvELm~b8RyvxMX!?CXA`f@W?iJJ`mnQ3&H#5QL1?ZT zg@Qe6okA371uka?A{Nns$W?F;jA`dY=$5T1tDt?p^wLRUw3|CH_=K>wwmRUK_zqL(K=uOST0rBv=m6h5mzX zyVYz(?VXH%KxlV;1Y|*F4r6w-F|iG0tKIy`i3HqEkfz=oBld?B$cQkk;4p+}S$!4r z0IJ!?&rq!%?LklnsPubWT0t?n0v59W%+jbTnLkWsnZ3qC{>)zcJ=`#seUD2>F9JgI z9@^jjWms(n;@K}Tg(pEy@gO)XfSv`4S?WIW#jo*=CH30~NP&1eF!n0|Nf3Vflc<#+;+;2z!l!V|QLmemf@ z*hvq4VjKHVoss|zIepeuh2yz85`a?YxeDV+LcuNUK|Nsd&zSIFLk*B1-kcu%+AKp# zv_z?gzQp9=NK$wyV%7y}H=~A^Fc5I8p{AK? zXDI{GJe+QQ7Ij4UW(T5;?4;vCgiekO_lXbB1Y82+R7L-rGjY&^fo})OCMf0cvq{?> zJ)4xaKYR2A9O<{hjdTx=9`qB3mLD(I&3-tx{?9#j{j)}6G{aAinz+IZBxFZ=sj&s- zw{OWW&?I64S0f5+YtQ`lC0LROZ4zOQuely-#?9PrnsFJ9p>x1>hn|VU*zP~G(!)6k z4|(u0NE<>7s!<@7e8z(46H^?E2(z1oj05}Y_*boi;u*%!QU!&nO`-k;#;>S+w5TO2 zNkm0lOkmn!2{=2xtnDD^{uLLLrk#OL4H$Dr_%LlfZS@&EF(U6CZJJR6sfYs+`0xW{ zNYM;-BY=P}2*H$q>VG8qu7uz8sd(D4xCoI1%(f!}WP@RP0;csHLXdDL`ON}8o^$Tm z>KhTP9(;t7J207#CfIHdq3-y?tMt&`Ep(=$%I0Kpk8i)CDd`!ZOX!PQ)u2Qp0^$^hjeB=>eBPL@=#> zm&pN=_)ML1PRQf-SU}_}aCtzRR+I z%jDlN`9mh(WAevLIO-9mmN}7m#Q@*obWY*Uf$PQjg5y-qp2*9;BGM_TL&=x@S;$?% zB_ESK&f}m10U0vO4~=U@uM7^EP=A89jk9>G0QqYmZ5%(3(Zl$63S<=Qj`#!;URiKk zkv`RtPx4#|eI>L{*@85`)>7aav`kOY<$bURMtlZRbX|XlF#5d#SxA^pzDXF`9&Y+U zNEmtW_r8E1L^CIbHrX(sv9jG_AV@MoxV}xkr17WnE(>iG%`i2KO;v>Kp#8~uP|5r1sDLFeyzWIcs zTU*}qt4U@hl@RHZjEROJV2Aohcx(QecGJAA-B#(WQ?#BFtN|TVV zI^&C>;jun4zeBU?Vl-dmtT-&g>Yw}c*}(CR&vl&p~qD_!}$4E9cM1ECoT1) z+`(8Ea(U$z6a_p$IxvM3(AKm-4+#}?FNyqmf#~{$6th+r)gPdH919>OR*bddspX|V zsf4M&-BJG$byE9;M%dx)4!BnK3nmXmSG(?F4fgH}@YP zZ-p-+r2|l()6=16b-Za>+Rq!!jBVvR6oE&9q*UdpDzC=7I5{|e?~&UCswgmts5-w zAgP_?xeeHDyt{PAo@c#7q{(KlbH`j{^rxF*8w=YNz8v_3nw?CbNFX|{eK-!uiB_Y6Imf|pjhrI1+JuvHilTVr^QLDdI-XzmuJs7L@Lesc z8_H%vS(_Y*B!2jI>#j!3bn~cJnVdjUn@VM<_9<$VLdC2D{lCs!jfsF3lB2r9>qIFCwPWyh6tr7Bf%TowJv zt6ct}Kgsu8VJO2ll&P$y*|L1AW&3u^@g0+8b~ESae-1B~3?ghUf_o82vd&w`!eas)j z-D!@s#{KcMj|nNWo0I+|>T=Bktto%1bkExP>T#fk;sd4{dHK8UyHvC7_0X2pD33X6SdKmXp>JfDU_b1e&%ESH1AlEpp9#bbjHtw4KnJ*jaadqlrL!Aod?%MuY zRtjqT9ym=}U{#g9Vq_&d zCf9e@+BW-U!{QoqeYv*k=skDY#9J(%*^~g{VGb|Kxx+UYbaYl*_&xg12cY0{rF(UZ>t*|NiC{(*po8Ai#HeI zi8gq#wxPoS{1Eo$23+BFt5Fo_cIZVNuX?*vSKe|*dr4z5mjkv5dsg{uoLkzcH&yJY zdKmfkm76zwx1y@L7WUk)lp%bhI;D=V>cJ80jYvtlRO>IQLM1(C7GFnen&0e=&CiqbmqC;$9t*Kgf=UgQQJim8 zHYweUT0F6q-*4Vv9v zaehASJGR>!tvDycYVN1r8P3M5E@Mg30nkGF-p~mlWWcaI=VFFIRJ~o*`WW8ShnXB_ za)imlNP30&`7qM;S`?R(PmAiL9b*W*XB zdWbhHb5>tT>U%$Sy`yV^ETI={V!H^t1j1;`m`TotA<{8D_X^7>{e@QP;8;RU0^+lJc=ae~dH?s`d*i~Z%V06Amk%no)92Vm0Tgi_Qc5<|c_G_iS5Z8cyIZHj zA&-DSVK=B@4`LhR?ebi1L=X&jihKnIZg)5wJMv4z=iXyiWi4c+YMU#SG{R_!7#?u? zJ}EObKfe|PUA4h2i+vpS4kjh@!=iX{Uz5XM#Vepx`cA?R<=)XD)70DZx9d9Es6w*b zjt{4-RjIct!{XlgWYX!{Cb|QXtSTa<=?z;Bw;PPpU}|#5vCre2 zboB#6pGWy;Z(g~0>m3w_x2`SReBXQagU_=H>CdUsxwT(dd9 z{-WyW^Ur_b7Pc6^;8rEQx2p9vcp{!k^23Rqz%b$OA~8(IwB+BcB~O-R7V_hRQr4A{ znzSA2(|mSkn}VJ7Gpxr`ZrD@S%kZs{CujKf_@IC3chA_vH#p+3Z_Csd@GS#7m-?9| zu-Lhic<37u?A*I%#S|;cTJYV3Bv^w|B{kD4mDo-AXwKBn<1JZ@BzX?m0U0x93w{Nq zA&qLo)Gr{d$uk~kb<@R@3EaeVB23|~xot&e->O*3+_vwVJ$LJT-`KHt4H$pcwhdF; zY2^BrvhTr!Rt`$czR|btTHRNby!Wor{#T9>xoai;6DHm=jc*w58|{C9vOLOeCuLEA zW1#$(QC>v(AExD{#@NpIuCeX(VeYRP`ZuGAzSEeD4m76jTF4!2Oz#|0xt$r59%fDB z$gZ_ZbDlFh+IN)8nMJc{|F3?oUt{N3-$Co+yB69##CCmW=i%s)UGu)Fr_&Mg>=W~| z-ZS1c;BXW$Bdc*@=h0n!k<2ZJ*4JfJuWzBwQpJ1d5!8B&ZQcV_8WzmuQty!)YmoC1 z)WWD`Nr!DkS6gDKiCIWFow{wBE>JK3_3ew^*SAZo2sUf=_Hw89BsUCwxr<({y0Nkv zc{jRHKb?)xyRil1t91<~-(#f(SXVEikGMn=5O!v?5zd{A^EVQ=FwS3l@AbvXn_txz z(a4{us16NPvDbpwp)2PfN_S*BCG?>qooAo!b+Jz4Dd}YK+Kt5<*I#-4jcZrqgI^7{ zmO53fUZ;-L8(mnw=}wPx7(oU8#I?;@AU5;s_@1}~r&H|US`g=MSDPDwE^>_Gpc#bK zRv5csq|jrWyQ85MV;62ks|vT3P60JrY`4M{|5!TbwR9Sg@7X+($-cg@c@}uKI^6K|6%uU4dtv(HhE?+t_zhryj|Q`9(VLT(LlZ0ag2V`1l=N?N-u7`Riy9 zzKX=K3Z@H@NFh}~I*Drrsf(*5*Aer$++E4L=D2wT0Ca<1&GL-#i%(3}UN*=Q<34lc9*v;h8h7xte>c(blQ;P|(g>|3v!DElK^ z;VcrvoHD1d(;aKZJY`OE-{YDxHCqi#a$CrF7!Tm1;|jV3qK1UhJxW+i@f@> z_t8i6r#^x!j|#Zz;>^NruX;BVbKSevhTYw1(?|1`wq%3WR)g9a?P`Kcd<#krx~~m) zJN5YCtmzJbOacMKPHyudtm!&5l6|M%h9;B@R$-~$z7G7OkTvU#XHVr?xZ0Z-1j!1>`QfCXlEx>-n)~Oibr4UM4ZBbr0ctbY zd{+6HIJYbrGcIP62!}iWv(lv|z8W?~_c9ERWKX(A?_qIj;N_Gr5eaFAm+_D_oXf{f zqf>9|>zGVj=mHqvwkM(k^&ZlB2YZIpWj5TlIL|kcg9JK_H+&b=LN=YSUPGCFPP)oQ z{S)Lui5=L-sfsKouS1j#L_JLi(nQ3>&*K3?9F{NG%-qG6yk}wCTiw|egWG>6VKuvN z>q~vIATZ#MVStgbXre_hM|U7Lc42(3x%w>yH6U-nfZKMWJWX2N=sRI!P*Xrn4r3M? z#cj8r3%?5k*2TMjPFlD-CH4m6wg|Q@E%=k^Caxr2Ap|1{5xYrt&q{OKQ0U5Tla-#@ zHX{hR9el~IIl9(%Y<0Jio^rBEAaI@inw$Iga1+I)k@cNRg+(%fOkh7~u^07IcvqiA za(!;hKU{%BNXvsdr^0Q=#RZ~T*UZF4RHp`z3n>S%LvQeXey_gGgzFejbekJ+Y5|b~ zBGLYV%E0YrFW69UE1?(Vt>^KAKc3E1s(l!wwdRHjFp@tZ07=FVQTYq$gr->5$M>#Neow_HkeQNJ{Q>7XaL|%P1!=jwT^Q5VN8ndk7l0WJe+8!(rvz41ezlcqZZT_*jZA7pW z8V z)y01pZh+R3W&T7{0Z0%;vVqK04(CE6P8&~)8E<(-6 zX!QYkShMvh*mD3()(ZL*x9A{u0hXcFrrl_+U<+@}l6SBvxmm4S_O`Q~+jfCf%m9DL z0e@Ica02%69(WHb#RN)_>$|&9&vW)dY?eR$pZMdh41qF6iR{j&tOHc71@nG{$zTZz z>s^!JXc3t=gt4fA0sAh;h2@QAlj=R~Dco3++++AuRHhM-*oMg7zb6lkj6)#_b4b0! zok$DAuqGh_=>WKP0p8#&cA;zbp3NFoMqVB&jgi8vAsvGpobUQ(Y`^vXdHqdJj9-;} z7~J7+p#*yCXL0inbed|k>-}?{$+{hF^eiVmh1ZR7*D6gFAf<`rja&LJpll#E*npzr zWn3X~=fLo>=)Q&X02X5KHeHQ^IcqdfMdbW}D)Nv4_kw>pPoPU?Vi@5WoPP=P##}A9ZvJFCzeFu_ zikz4~4Tb`~Tp^ZIp+Lfdak8A9LJ+S~K_G@76Fb6pcksCXL&hpJ84%Ldl}cs!Ez@AG z-qF3^GH6Gp!4T{dXeE%#MCjsqyi!?*a7$|R_c-1!>>YHV<@H}g#rqtQ1OZ>I3El&p|=6pv}FusW>Z^un^Y06P96 zI@W)g$uA)Rk_DKoR;i3oX*l7(!bxz#?>ALbMMVc&HC2$KMwONvB6-S66 zTPUFo_alfZ6W=@Mcz~TI6c*?FTl@xELXP=ojk+s7J&?pkIK}5#NF11GffsaIJItDw(fg9U)WYIoAD&{Yl_nx8g4F&DX;nfm2Asf2P;1icdHbmKxt9hc;~wQDBx5h4f`QgxI}2Jm zA^IKoF^z;UV?ObC_bsG^H|lau>3f_LyEV+-bT$`86q4$}=zBcUOB`Ly04_&@BM9Uv z#w;-oc$d#az%yXTICt&soEW`E!=-nc%r`&WF^EBc$QcHZXy(vAD6yXe6%gM(j7xCw zmSN`uQWMQ9-X>g2Vb+25<4?D?2Jfc5B}PUL@Z09r{`DHi;Iv1i@)t-CMm`PLsp6(v zlX&XQWV9J=JoF1Fd>A2;#aYBdN*=ohx10o`g%7fjXdqG&uS3jI+Q9)gd8iNmBtRrM z4>#A8Oa6oal&Aw%)?N`G z*w1)%#F2*44MgGv|1_R;PKq~bIl3^AS|&tUsc zBMd+jEu-YVNe+B09!4X(2`w+6C&&c)Qd22SK@R|MNC97gYAA&l1!)0)U8IFWkgJl5 z+`GKzC0AI1JVCCwZEv3Mn*d7Aay0;}IRd;Hjl#}Y0+gV?JTUs4vX2Smw!ZkTfp{-L z7e)dm8wdJOc>jQk?y6xTPW{{(PMe)D-gW1Mq{893Vom4oM2fLDlKmm#mVi~T$m zBub0S3qoN8SryB0~ zMem8Q^h5}?D$0v%um38OzlH=bBOG=d*eF5)0;xrNcw|AO|28W}#1ODsVG%Tx^BOqS zl%Pa?c10NmSeIKb&SH}(AEwfk-gXR88{*s&je-zIJ2ky-{ToQ;5KiH@eyF=K?UpJ~^O&h%SCe#^ooIaSIU83`j7D$&e()!OWo4 zL6BnFJR%`Z7wI^h+TLu&-21oSKwHywprokb3U`of{yf&wz^dNghVI(|o)p2Cx(h80 z;mX()L@ZAQpcP;d6KE#O5qoz zK|CswvkVCzlIxQ51f#tRFT3jn$|HIJ3q9-N#oi&vN1o*t9hx3bOTthS`XAyubPEXr z-qo(2XLi6Y`tPx#kYU2&gy_G|CQmZCF11)2sITQt=F9#LtA3lw9VYu^%qf)p8!i>y z76YWG%`^=+oqBcBK4J9^WDAjU)IgCjAW7-+IIi${Xg(UYO``>Blg0yOW&_s8zS@Q~ zfzmQ$?}PpgH~i7&CxBJ+j3a&6-v*eEbt!BYu)B-;7E?$S0R8&b`X%o1T?0V^NEBKx z-!?xncP3c!32n1U0{pyxVgfyK(caxT@CipP_KW%wWI>UqSnxi6kiZswkwBCJmyGpG z1aTYF3_jfBDUshpIO5+&hagkTW%CH+)i=z||ArPbG_et$FdB#9Wx&t4=V0c4@NI;8 zc8=^K9yyrV(Om=m+>B>+9Ll!?faIV0kx&} zlCk+PIN>4W?Oh8q9p4`7k8$k#*80hGR~%SKrD~jiD><0i12B;wEI2xro}JOO$9t22 zA`#YCJk|+8JCFt7V6lP)O(bJt{KU~BhHNinojisr1mbXx0})2Z@ds>)xNxaiZ7r$l zgQy4@p_`t)*q)fWUPJGo)omiS-<=@Hi3#3a1$; z1n(eFzvhxE>jR9+)ZDje)JUeuQ$m0vNta|3v!~CBmw0}Cv#T!`INM~D-sAs=`DX3^ zf6gq428n3ltn}|8nHbIogcia->`$hrg|MzXiL3twTmJ}2Y*iY-K~9%EHEGVn}1L#l_$u8VS1Ue}Ji+Jn6q#zJ!{&cOUy$-CA>f481I+vHbx}B zl4_#Iv5#pdCb|@SyK9DLcm__KCrJ2vmOevh4rLC@aE6dTox{^a@?EmHfX3({OlCM^=T-4+hRoT$Bnn) zd8JVp8}<`i5dP~!CiDEHGU1E7%G|IAIKki^5Z>O?!>Kfm^Jmi@gsjKl-5rCEv2CZ8 zm$d`14EDk=MK~`6FN7!uEIDd`-qTk)ZG^h;qX5L-07WS;5iN-Uk6<1*X&T`2@Rus3 zaS2tV!4Zj~BmqSI2|hfg!z;YW9S?~Dz@xr|U)?1VC7%kf7zc%htpFLohL;~8#8xL1 zc9tML`^eUgdMS3(p=2TV@;W?IpjUA8`APEohx1&^6L`(Y@rYm&7D7baPIHg~w7N&^ z>U|vy);EVf1{;EY0Ym0@)1Wym>4rpc^;xhv&kAD=csxT{j9M_a1G_rPHwy661tpWy zTXM7mF%AG4wB*7+Gw4T0C^fwpM!_C0NNM2b&}98|zr?T}Grf+R*q7MiRq0 zCkq(Pc@j)dF)2~+G_M&LrR+#f5CQk60WRjoXXeuY0dbmPDeOHYO&9`A)+e_WH-5*@!B`Id5o!Q2%EXvetF zH2g^uWA8kBLp>&2Tu$R=pn<5D-$}a=U@8%Wd-+0i=~u`KvuMg#A;moZaa+Tx$B}hl zFb4kFaxeWFOmBi4-{sM&cipd#diXry%$jg7Mh?kc7zBlynEsSgtr~#?0-i* zB0yOxhf|&H1lYn+3G18So4Xb)Ozu{9LH}EfEJj=J=up*SDT%0H@6Lk_ILpLxboaYR zV>pcpi7NV8f5di-*QBJ33sOns=HIbO`gw#;`)J8Id_Y=Glf0x9Dv?s>B%MN)yTsg`YGPw;JD~D-=4uCOBYL%@6*ka za%|UpqX;(vdTYC|c@?=5blOF_ObrOnH7oq*e1co!AS{m=vrK;<;{(Lmnd}!=;1DFo z^HpxUu>O5$z5-l@7o!90>n_~EHGnVrMfRfH^x4^&0z1JS5Qpb;J*{7$Q`VU7=T)B2 z(E0`RN~E)pNMvD(>z|n)EcUE3b14)vcS!#Mh^4kq<5VRzMNqzK>8wfQDA07JK72Q8HIb%)S50H-vxqu3zNA(ZudUK$$R0 z!hHXf&Hf2ni~$i(*b>mo1N;vCU(jlq>_!WSsELD%Xb2D5FqI9Ar%Ay`SU+x^AdX_4 zMCp+nSn|+dV~_A8`jkI1It6)9l*Kcpq7$pCk05C`}Mbt0yC5n7;ZWJ6#K!DQwIQBsDBa;LeNpL7r zj=E-xI+1Ma!J_K_jycOp3{Kz^K}~H$Q1ySXUKoMfZ)ACYgIQU<6oMTtOP&Wah+#cw zN%-D(xFkpLKy-wWh5}*^1hR;gj2cQApo_5m;@r`F(PfFnCc&ZaaWa$*`foD%btar! zVgrlO=QI05Ca0Lt574x3HLW&LBqHb&DM`K&@{PzZk!0eEF*+I2hu~fy&p1|LYC1n% zz}+rPmL>|177i3H74n6#!ffFn(o+)AoI9^~@CGCN%NtO*i1uqTlD3(Ujrem;{QP1w zYSx!@nWcZs6(;07{0b!r=agZFgWek~8~B5aS=3kLM`@z=gg`#x z(CPqdNNmK*SRo_)3KAY{Zrt6)kPa2oqq4ZU{pH zGf+>15>Vi#Vmej1q$-tjlA$BR$x=8CBD z5-)#ko!HIue2G`SwwkManOE^%^iDhm`M*!j1}}(C-IoTxaYX?9HmV$$5W2 zj`|}dTESo#NtKj&a1_L7nXC+D5UN(zvr)5?l};2Y@k9;$(0?c-N=n_}i5f{Ux%3B( z2($4~U$D?02+lU@->bdZp?TK!G4O{&48Jhx3#ZXN=9c)aroqlP=(zG74W$^0kl*;o@5e9R z(yZIJm}MM;C3~%O}y_6Z2NTPdpWLgN{$!8?(m&iuMH?g**xc^ScU% zjnfCOJQ|5ufm*t!LOy4DI^~RIdVY+27{oon>x{Up-A?z=ZtJc?UxFYsE~j)5gy55) z%Y61@G2W4qSVpp2V2EHJf}=}x$82ph9GDheXkj?ZEieI2GzwV+-qbr`w2m-h%9js? zs_XuZnv*Pls%7{t$#CM)E^BtPIM6cvHUb zBC#$O?V>H0k?W8Q)31bw3U1?x{{ac)7qa`*KDMX!DYPYWj&i2XiGA!o`PtOIWBvYL z9eY!U+f(nd^+W5}8LudJ>Q22A=h(e(J-Xsq$~&ycT^m}!w!XAN?*U53RWpih-M7L9 z+7!^{?`-S1U|W;7RB>83u}`h17I$Bu(Ly7!>yq~Q&Hv&zxn#5=6Z+VLkX?mTP>nTs|8c#qQAUEbuI{ZX6y1LRNTQ6SCLrhW*z%AN7r=7^w6)6K6-Pz_@J#R z`@lJIHTYdr-^uR_A_x{v{83RLg z9nD6PmNEJMU<5S;b(L9JmhuznKn5N#$~^)_{$Fjgul8vC4hnn8<3_naYQvc`oBjxszz z12nLrcm;`NuY-d$-{37bQPQE}>_r1BCMtj^aPpb4zP@?QHqxo811icIfXiUo2AslG=fnFe>h8K%|_v~uHATU_6)%p@$V|~i@!J12x_&}dNlI;hP~t#s^`WgJu6A1vKjFOkkSjE2ULZ zb2`PCA<;ZnbVNqBLZN&(WKFAR1AEJ}C(F6@|8xYJ=6b#Bjr5RGkAYmvTv+Yjb zkK^t3+(O!!{(IaDI=y@_GV#C{emG{@$kQ=sXang7v`vrgaiDtbHrww5&a=@FNJ2ab z)Er!`*I6gx;+k%;z0F|Zdr>%pv$XD1_h>*LMg2Hm166VXxB_qhl_6E&_c!LiKy7=W zDK)1BEnwu-GuWsx0Gq+H9jMbFN7DHkHrbVQ!YiBXo!V@{065)IpTXqDff{A#uP3Bn zfnq_71;>E|%mTtE8nQSV2tz`Ub6<2Lv?TncksuIlyqRwz9(8(pnW=NsZpVuEgMCmq z^LEIkz^M*`hdn58Df~ksDS^rWN~zx^bVt4w`8k*h$Kel#eKDgcBuMqJ%vba4bIgdjwIjFNA%jRi8kO=|e*Xd)ZXXv&h4l$pxv=fknPfNP@zAEzq)nu4#T0C8v z0yWCX)IO-3E>oYU4*FOJ)zfp-a$4%TPi@;$EBeblap5BpPAmEWB$E9^D8PvfL1>?h zK{kwGgFh?=kqjmzQp5>SpBukzM$`|-#Q6TG4*@3Beg@WO7=AVf4>(}EBJqm>+jExs z2s{9q9*HmzFxhMzjabJA^8%=m_vxqBp4hJ4HVXv1E$V{Ifq>gBB-|w+JZkSlAt=hv zfrm{afwV1X8U@CeDqqaL$hJININ3S){X2$FXY#pV5_0*x0;d?56uKB<+4l$g+}~zb zwyxAtABh<9aWn!!p~5wB+ilZ+PKL;e&;r}-C`PfdymK_$)pfb^WzOb|(?$JLE5YKP zp0Vo({d}vblQr8XM2^nK??YxebSe8%k6A|q$Xm}x&_@7P@!?%Uv*yil95 z$*y(@8j}w2c($C4jLV3!sry_b&oEtXUa#4*mY$b(_n@APwOu?{1Mnu70F_hkaJDU= zhMmCfPkQV?rfL{OR{A3#1XPD;Lwwn-831*pcP zl&-l}Hm3IbG?0ec1-*K?L9N$XEhYVq*!Me!J=i9|tM^gfEJCo*?2IOozlFL#!V~`r z5^Ke?%T8IlAw|!#SDY$2A#Mdg@`Amno6^N}2o2JY)Do#Dt(rn)pqk*gDGMs8u3)T{ zbKpWHG39Z%oL|{M==KyP8n4@0IRW3tA5C3(0Oh3Hgl|I4lt}?$B$$30@5D{j%`$zT zIH|Jn{J#W3Wp~Jl2b9nCO}kA;PYf@k!JJfYGQh0`wURU2t*o<#?!<4z;Ikn!^#Zm% z3ZhZmA3vjMKJHT7AfKB|jMgy$DGNmW=CljyGQE?pAY*YjCEr5LD1~8J4pg94Zd`_a7 z1>5FDQ_JLH#kUv6My)Eh!ErB?w4?-4rL}3VRZErpfI5&To0QUdYlSm%r3FgfqK4Yl znE4yTbPfCfW-;^-GZGcj3VsiDuX-?a=HLUb*t}ouceUw$H!K zL^&5CEx@$#I=iP~KpyFXeSyRfL=V6FtkwS|@;3taBp=UkcB58E%Gq*$0nz0hA~i9M z;jObo2b&N{|DK3W{*zTi^ym5PMC}?2w9kRzb#yfJK6XI+4d`CPP7aI6;rp_Vq)hEs ztjh@TA#MWLc%aYYsS91IgZqpLRx4(!kH1L=QVtE6|wf$SGDyr)54rh!FbaxeCOR@->hX zY^JS~EKs~7aiTaWrBlisl%(P?lZ2#{4scc^iePy3{AYABnB6NIyLe$9vzta87p>?= z@BCos;7QOkf^(Y!Qk;TO?&Kez&+w$W=ScJ{?;FM^JeAYyEbjd!O2FJwW-ReMkw8Fz z@JOTP${*n^f18qzk)S|F3SKA$MMwdr`4_Y`v7*vsfx@Ob4;E6SAgAzK_#g^%@`PR` zIwP`W|FQE5N?V%lrwI8dgauFF#iZ=+POh`N=0=6s2f;MJ1A$Hr=YPB~RRSjuWBK;9z%9CzBN|5vqqTBR>@#Hd3#G>+r%Ky=vW6qbR; z(?~WC8#1;_aSXE)tg6Ws+dzaygGc>)FNtY4==*Gel zWfMn=q>=^?5ivE(eiJp#)$~@mp5C;_vPc~ej~onxzG$xB+i89L>D|xn?Y4IA-TUlb zt8weo9euAnySdWAi==2S3iVZsp$2W{dAm%?*G*LE15&p-(BRqY2s6-MmBI~9#jUf{{mys!ecw5+&CgdX{I1-Ozj^9q%la3-WWNF)F5!y)6^XKx-L-ml!|pi^ zr{^|Yn|V&xYj|=mGzxMrHi~jDHA-^#8@}Aja(BCx-dtm@S8Y^L-)qc=#qEXt#n9hg zdT8$-dT2EctAZ+iU^R}YlJaps8kV*nd&5#?Rr$bDmGIbo_rBdYj+{AFMNXADjT3mE zR||Mw2v6Ysq*_!R>tPUYF)QeHcES~@!CK49lgBtj)BVjC+i2+% zvR`DGW_Y*V!JO;E-T!5=m6hwLcXgn9tvC+V6;pp@$K`ae%V&dS8SgLqhB61o{VNtn3y+!sd&eA1V~O?Qf8#fHR#wO; zg^0_SxYw?{gSVnt#H1i=_E(l(0AGCc&gGRGUyDK=-MF&)?l*$Ze&NQe!{O_#xOL;p zgLbQX<9gT|-WYa)TQ94DK6n0=8^c}B=teWWv-Jq;kyM(}E#D85{Y3H? zeaEva&M{jrA+JsT^C=XA6@xqP+xHyYZQR}1-h&(>b?)0cmVQQoH}_oSn4Ir| zd-t3j%91<&^K=ET>rohVHo$CQ&bL_5puN@UD#-~3=IeSZ0#~QZdj;zpEN=`3FRr)r z%F1i4u`ox_nbbu!79h#fa?8Tq*_+hD*Y#11eqwfGK6M9rX!!Ih)6h z>*^kKN(_ynuwr}GwsW8B;jAV_!x_+TrOhyg*lF-as^OZ=#Ot?uAwGIh*xg9n!TNSm z7~JWH`rvd+%_izMn=9Sgte zdKOP7)pKeYUs4U+@DZq)eE?PO4ZeixId|0QlG{BDfNmvr#^?8K^QbX zEp}}s@m9f_Br^!yjMC*=k@?dcFJ1q zp;WWlM>~9vhVlIS6bpNMK{>}!a@%6stSX32&4rk3L=d+vD(%{$up%S}7PKEHMcCSn z&Sp}I!iZ=7$=W~cVpdZrX}z#Zf}KA&T29p-&y!&wz@|oyV~A&5T$gc0 zlt_|qU$o3aq7-|4J}~49qOc!z;tp72YcSXehI(*!HyA~s3W!-?xdNk(=`$xe!Ii;77Km&xmi|0a!Pza1w2)fBiT z-qlVwOgu9EjQPu__j$BUH7Y!2-*;dHojoUZ?>qWAedRv9*Gz44#T7Z_?Qkt)RjKYBHm;j8%w>`?t0j4i?+x7hl$(nMh91Mk-E1%isC^} z?25hMR0`vxX7OeV&a5G|wyYsJNOAoj5SSj2J%ww-Ic9`mT)OaV6g;ah z3ai05l$%ZIw%OF5LRFdJC#(?oO@~9>Y<`bJltr5GmHCp}GAaWq1sT&jcp%=0LDFa; zcHXyRh&#>VeU~Iw4y;^V^6)Hq*0#4@*e=E;C=$$K+eazyfu{-&Z1@|rf5q`z!Da|+ z){4WR72Ij*K7eg-rxS09&f5g1_M!BEn5heU5b)M!C|VLIIm%&X2mDeG62A*HCJumM zQZMmXHz}nRQ~atTivk9+!ntSYn1dDCM#e zWE1j+NcI;&ww09^q7cduL{zCq5vUN@inQziogc6oK}*3XL{U8elY9oPJ(^c!K7YhP zrm{RI1M7ZU`_4n)C2=>MaTsXhfzjG~2D@{X|lyrC-HWNTp zRAW+TZ?!u8#G~9DG`&$ggm>=;S~+Wri1h9~;n?jL48Tp%Y}iAxHu5U>Q*r@v=!m*J{Ax`DUK{v6(` zq;G#o-shoYnd3100e&rv|3mEp_jV}VyA+e46&Sn_0C@wHk*t}^l)6Nu>k6$&T5=^= zTZ0l=TMK~T*4B*fsI!&&^TYXi^;ZSo7=7S8y zjBj?G;n=OMU2SzER)d8DR0&#fFdWeM13Rv*y|lJAao9CQ3ZgpyHb(h+*d9QY3^al! zuYUEd<{MX5$II~V=&Q9d^@6F*Oe|o{P_Nb&8r9U-l_~2lqh)A`rcu|;gQZ|PlRBky_5?UHp5DWyNRPF=&b--OPk2n5yzIy4R(uG=~ zmo0YeY_QSk0)5M>LH~}rP|fSRhM!OpD}-ne+~Uy0TF3$rFtLpTh@Z&1nR1jl=Tydd zuWc?Pe;l%lE8@i=?^!n&B#>pDwBCg_xdn}bAv+(kMyfoW#HqiO*mn=e^GD?iw9t2l z`r_ZSIYW-|GeRy7F9X!|3$&`;=wdyu0ENtTgq1xuU9w60E=U?~{sb}~ShwnQmA}in zwu<9JAL}|_E3OmGW1GdvdUvnV9PQf=u|}_3H_t=ezCPV4`l6*kI0f@Z&k$YMJbHW&@N@b}J;70!wt zspX?wHT3rqKULsLzXhsj5iBysG}c9|0Zr)NV1e1S(BDAbKj4adBv$D#gyw`je*9w# zFcq-Kq}b)%zU+YF=Q23talC0Z9!0x6>HYIg^4 z_u}9TJ?8Lks|O+kS^T#~6}bUZM{U`K>FUmu%gJLx9;QTXTAdr643Dn`AzeXJ-R^p; zy^|SV34fCI{XsU)J1sizqrS=;pWzT{0vVLi0PDMXu}nq)lptlXZh%ConU%#$O6f2T ztVwd1;hvNXsSN%T>Kd?yxQ{H($IIlhGP5wjfrVjo5oYrVI#<+gg4W&E&!8^=*l7sT z^-0a5tO+5xL=|ZHRtJ3s81s3``hmX!H3*~ra%=(=c{?fOhmj(wrq-ff2bLY`5WqfE zD=We0>gV$|sUfek(`@0UG*MC}q= z_knMLZAJM)-7bNlfMppsA_BX$L~IMCYL71jX-v9>+2^2E0y9Aty5S-c&Wan@>hA_7 z_7l~iz-s7D)LK$BG}F%`C!K0zVJ5;8=`XSLta?ihkxEi7>+j!C$|yUh2p4|I9v>41 z_*lW50<@&0!e!Q^p37juzV*;bA%eS_7tc)ewX8UUWj8A{(%aULom<{DGs;{&=yy?4 zzsF>D^dD6&2$V*I;^Kd?H8x$e#;5ZEQ=+0N^PCq)<1`1ji4~r0HxVE&b^kMK)|v+I z@+ns*1{b9BXE2xmX`3q!BrXVB5Xbm$p+q-HZs3`T+(KVt=Zml#E-Y{^!kf7=p?ou7 z*%^n~HU!021fL>2Fgs_1J|O!qYovv}!P^tG1dbAhgRdms3JlAXDN!SC%n8rc#Zf#1 z1Ho?jgJhY&*j!V-!L5qJqzdqu4OFMdCUKE-V8QezsPl`Qq#2-@uANhr9L4K0i=Rd! z9^(m7&G2jJ|3vT~#ak>wqG(O+@lDauqH)31sjL{ye5TWHcSnkI8;s!5bvGtx;m%g4 zy(L>YeL4*io6CS^8i`@x4pTdik%(uQDU>fDBPq2C4|cfN9O_X&L}a%e(r%a8En5WtreV0*0y$bC zzTqX^{yQEF7ZWOilU?dA{Uk)x+b=vs07lvOJd`MIm$rR;gT``?m4`G}T^V&qj>9fL0t;L{7{$Bqr|bpQJ4>suI5Zt}3B*PrjQT zmz2Nb>AytnBJ%Bf#oeX&(EedY3y@cO&+4D>toX=IMgOCXJmlKh&ex%Nw~xa2 zEu}p?22S!2nJ+&mf`2Nj*I_pX{Y_m40mL`Fns}{IJU}RA3mfnHYsjw^8$Qi0gJ($z zTk{OhClwU9WBdRVj&~8v_2YHp_auukR)uyPku-V=wPQw#7Mp2^z1Qj^yr+|SY;R2> zvyH=7O$7eSh%JwX;v^;o!C;LFWEK#SflGy34s9LeeP3>t^I7I9=<2nTa!qk|KDteMcpwuUwN6G`L+S{oW!qe4|2l z*otN=&PGqu|4N*AUB}EGGC81QmrOKv0|p#h3>YX*Vp!27l;rju9aP3miq27_3w9B2 z*wn*z0G=JsF{y(*=2WnG?BI_auPl~i?Q_qM*DIaK(<4&m_37v-T@}l@1yHSEnZTc?($-$y?tAM4>fWO z#VI(rL|K!=VyHL<|I#V6Qh$x3A?Bei%c*$=$h(IxJa?0AxJDC_(##VN2n?CbP>kpV z2sC^sKI)JdvXmTI9mH?a5$(YU;`9uO^abj(jIG zr3gx>81M?_D1b8OHkb<-05fn>qES%nFfHWA2ZRLP_|u>TyeRDd(RrJiP%1<9Koq?m zpmB_uDy&x2Biw}M`Zk{~A%P`;#@FA$V`luR^b!}gcxo+020y@uH#kEH8zACFEIrLx z(^8yImJ{WKWwMv>z=#1B*3lO*RdGzY550|$%>zV+_b_qT$8)gG4)*^LkYgV0Gi)n% zr8)i8bkj2NXr*dAJaCsV2)ibDEhZ)Sjf}qOZ=t(}+aASIffg%;5Xe#;jcsUg;Ipua zsC%hX0qjYO9;5=b)+(t$7PY9(K?N%J@yW@GA3!Xt*pHH}yj&xTuq0(1$qL27nPvF_ zTGS-7(Tx-9GEs!z#n)HZeFYD`>p4rVU-V0w`8mx=?->TWdj=GS-*WRw@!Jro!QnU3 z88P+Di@Rps@(~)7jVMTWV_r6@g8SYL`e(8T(I@;9@Q z$Mfm_2Hy0KOdC5c$`+%jH!ss7orMTZS?1G*3Jr=}CiJ_k3$LE+li=03Jba&FE_|~t z;ffw@Km`kp>jw|_WSW-|O~fzZ+A^96PZ;MOekB_z?cbRiAhFlX0CVnt4PSEZ=W#0s z$AsrZ3V7_Q45(s``2wiOG2c=MsKO(@I5Jfh2_a;u3bGsD#%RGZowiH>j^gcf)1Bx8 zyYMiAJj04e9_?oY= zaYfG~Nza4ubP^95hzvji3O4pwA#bjvUM3B;*^4gdKS5OkR)s4Bio?5sOD~6rqsAf* z#%L&JfxewEfZAu!cFyv;NNVAtI&#Bk2y)xQ`+XV4`Wi?S-sQg zcI&}Aa@d#WsUjJO&=kGRkd-sxD22NGI9ZITu=mukh^axR*`ZzMMhRTpoQeS=-w-xA zPd=F)mH$u4uG~dUQA^@6z?Qg}EAPiz74Dx#>41!<`j#TjQ#kR{pjv6T;Lb82&qvII&P&%lAhY;#!L3jH&bFcA+NpW*2v9^wV(r<+BI|5mtbN{Y=U zl^b(YJqni3VC=8sE6#MtAXxGMH)wv}=L(#{gXK5|!8%I_Gc3UjAI9G?Ou!3Vw zZSdSd8~i@nX!zXhqV5p9pdTX7%;`R#*rDcepvg!wlCW2FX#zGE77RPk=_wVb?$5SK(tUE`8gIm!9;COQ)8+{{d*#dNg9=MGc6RX(nv&6X;BqX(t?msc&Guf7_By*b+gW1+?jFP zRL+yDf{^$R$s>PhUwPs$@Wgj!ZHHE=rMX}Bo9}$*9Dmhn)fs*dX8M;z(wbj0Yn7y)Hv9(qRpGv1 zep7g&hPD+oL|rugK`f#Hv_Bdr_>5OK4Yx{g8Dxo?q+8 zN!HPk(j7I4(RQB7SnDY340GAZauscM{sCatwTlbkzRHt{j)FKH=TaA*h@ZqN&a$~k-7{E2CIir3?1HXz6f z?(u6299zCa?Oa`~@#oHGpZD*L$M-`W z_P@&qVbbqK>9{|R$2a3l=`cxdKE5q-xpnJKA2b17KbW`12;-w-4Zs5P?daJc8WYco zK3Zs*@($4s!zDKX6%&H=*0ew4LND@g@-lg z)H=4nEOrM_t6_A2!^EhvG@K@(2pi15RuBkvW!T_yYqCYG+)&)EvB7nwYa>kNOaMWeQWwEY;K1 zDId8ccFr_MpLTlKxo1|a#hQR?1T|g7d9zz(roUXre0|h7X&NItqC!SK#hu2q)xDw> zkjx%M8609VE-I$!y<%~CfqAaCL|@vO7cCuyQshrFbIXFi_ptBGs`70NKS3!Cdi^y@ z%?Ho1WvjRpt6-cXBI z`TofFzFnxILt9*UGQ}~!5f~g$jE?*!e18~cVG=)&WY?1P9tscHD-Se^T|e(NBq>D_ zW|qg>a|dmkUejt@@&;Cx`XHT!>uNP$sX!>d=HyL)o{>(cE^{p6@N#?>h1t zPRfs|BC6#_sJh%BFD*d^G@6!I(IW(^RIi8NVdl<9^bU3sA_~J$-(_tBl|!hOIOGS| z1K;})jj@EJXPkk7SJVc1l0*YCjRCSmQ(T!7NPZp6cLk+`Z{rq4;f4{!Ptl$ak?1~y zm|r%1<5o?IUnU?evH9ND^ITPCi4{r+yP=8}({Esn_`QQt04XuxJL>P_mQ0(WA?%^*{GUE$hX3;#cF=VYpfgF+@sf+zbz(xtlL#?=DTZ!8w4UB zAXL@^q;|p(1d_slw5g(p$_6Umog+0|ny7CC;J4@Vn}a+X#*ZXL4ikq>oHPz#G-s^( lKkc50<4hsm-7?eekf#{8au9MoYn?Z3ujaX{7g1L{?>{vyK+*sJ literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/outcomes.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/outcomes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f791f0f09e847dea899585e8655197be8b0dfb09 GIT binary patch literal 5011 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 Px3!Me^4$%uh0%WjYI5Mc literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/pastebin.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/pastebin.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..77c1884f4d6d6c6e2a46089b16670c2067327af0 GIT binary patch literal 3295 zcma)8&vVUjMsAFdGm-Ns-V6Q#-U&y8X-hz}<_fm3pv3S@YZ})xg`}U)D zJ9hAUaH@a5)p4AE(aZAZq45h8HAcmq)ZvV~1sl1kJMvO*7D^{dD3w=bl9&6H9A%o?x=ONSoGC5#@)AAd)4VS>lb3Ma>3Zfu zwx_CMqD3zsjVq~5#Pg>)&0;!ZnU}h^KPme((@vk!82nt6Cdz#j^&?a>XO8`zu@g39 zL!1ToXm{M9eGOdN*B2p9#DVwm&U8%+Im*kdNTi@8^KvkaH#U|&8h=!AVH!$TQkdx6 z9MEnBH(pj0)Ay7px!u3uGZ^faX|H>>|7I!l|8BY)m~bR?_B4|w$n2(!&v9@jde|z^g zFst1MJHLIL-2U0_hvV_bna*~9UG=kK_mLQlcgOj7BQKSP+Z#_l;FWym{h#lSk12w? zy~T66>&@}8S*>lamM3H?TF+rI^O<}8513qs^--6lp_a!5qJADU0`0P>9lX47h7N+o z4qf>P+V0%rZXH7I95&@A+MhSLcg9{gy#QeihtZ$e=g#MB-?h+mARJLJZiK#*x1$y^J> zkSP-!9%XW%D4_kS+|LIlstRs9*oewYaFON|J!^cE+>TH=tc8Efrf)8yQx8WrZr&*< z*6QBo`KWHw1T}JGNb|MF#bl6|qpZvZz)%wyt1TwdK#29SO<1X9CXas!r{#4T=k@fF zq?7A<@(nV$TFL|s>ucAwM)^H5SihIZIrr@W;S539p8+v*mvF*hL)$xZko45@&m6M-k=`2ffRIB7A>45Pt}}DzO;AE`<|54T zjGeL*54IH^&b%wHLL2Saol2q_d6_EO?$_+@^yWikJgDMza{H91EqPe;+Vt8o(n~Jf zD5}ABa!bYCmI)6sm1!KAJxpH-acF!gGHx3EqC(o{SpihwLusDdJ_ztri+*)@lU;Dt|lRJy!La`boa#OJM(26DbJ^Je}jn@7BT#(3uo zL>4FjN6ce>VHO~!t7q)YJqc%_ob!w5AI@8R?F`Iu1roq7&4R1+bRh@p)4#e2nc1lU87?^*Y)^QKcY%^Aig{%214hVST=!&p9JpgRzrJ8#X1>iow}>Hf~4 z`_HgV>)Jb=i-hs!oms;YW@C6^zDlX0FV2EfroPf^e_|Tx05S|Q(>jl4{w$<4q5e-k z`mENw=1$Frli;9dm;c5OcL5VAjhoycucpmgD%se$2R`gxPCJXs#wOwh<*UWx z`?Q7?DO|uZt>hLA#)CqoQBjoxsJcwsRBM^_#a`AwOjqa?nJ9Ci>K9TlsG#Y52)fPp zaJ_sWWhK)~JxsK?wH|`w*0f~FKM}v7puP5mWBrUCw%BDmT z$TmsZEbmc8tJsTN8XZ*CAui^HRcK56^)_k#Z+QMnOrkruJx>a8kI2AEh|kvD2tMKO NMeX&=(Q5SF{{T1XfQtYC literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/paths.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/paths.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87bfdb2f8a6d7e79c045fb4f223929ce8afaedd8 GIT binary patch literal 558 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 Zz8lW|VCmt~cxjT7C-{80IC&uW{{SfYS!e(N literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/python_api.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/python_api.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4e9ccb390f7ad1bb7054e1bfebc159253d881a7 GIT binary patch literal 23764 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 T%$0wY`J>W8=~tQ8OWFSiuRuJl literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/recwarn.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/recwarn.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a941c3e3b55f36d3659e944e95e76344b0efbdb5 GIT binary patch literal 8973 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 J{Kt#m{y&|c^Y#D$ literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/reports.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/reports.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65c756310c82ed349d019a9acb554f498fa0b5bc GIT binary patch literal 5933 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 l>?$NFlPWI9O_ZcCInEJm<`v`!|`a>(KxJ literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/resultlog.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/resultlog.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73384a5d69213daf711d121528390fd12b3f9d73 GIT binary patch literal 3671 zcmZu!TXP&o6`r2^u2!-|1P6B_*qxzTeI{-}%nbhl`7C1HbL#^0WUe z8OHyqbM~{**up1wQE($LIOAr@#%5rSt-u=Ffz4>lN}a&bwHvtH=FXQ!;Bl9GsD1A9 z7U~vn^99uH`v&ju#V-xM7%v=KL5Ew9jNa1p<8GP{yW?oEpJefR5eXSbPtv$s#|lExeDmw2$zv(%O7iOkbU8HdTZ z$VI7qo;*$HEVWdKBrC(cNj9K^`U6IL@H6rG`0n77w@_5ZiI)7-oUw|HATP-X`3&xH z|Ah-37?7dWpRSa#7$;ej;-z$5k`1TV>qnDxMLHScy?H?w%IU)TdNVieoORZ*QaQ5B zMXc;1D)*;v-`)P?;r5-|JKJ}=G|+|gjiy8#ajmGiZm@f!XDc_-QYmj7m(kNmD38Z` z5tOIw{WvXpX5bIwawzgi5ws%C>o@gGk}7i#EqjY8phZq;$b3z(O_k6j}0CdA|6C#%*6`bXg`ZY)^n6Q$g{m#-Lokm4nfHaK8lJ%~Mh_7K((q@DC<`P?lJ=^#?Y{~4H;s+RStV#YxOrx#2fkp}K zf=vuqgDm<4@&IX4ptym)at3J*$kLp6lLp$8 z>`VbYQ@lmvT0BDdIayZbs01-+9Y7jl0jYUXS7S5NDhk^nT9P zfXyMWH*cFWi<>k1=m>p_8~-xbjJw9)_h(M!jLex^xs`QbiYJvV9#`fGxJFBg9fyVP zJJipXblcT)-ps~cHuEZvZsY!eEB=jnTk8yGR35FX+?jRw_FoL%g8qPea8|po5qeKt z#hYKTO~p1|v7hfu%^!cJpwXa}0xyGou&c5)5Z%2Rhi+5=cU)OTUMPE%Ct1%|c2dS; z=$+OF&X52r)^Tv4cY%HFEa!31%Hn7BG2&;Ky^N*KFwSC;3_{vZc+eya9BB;MY=yaK z+rX0xERii-%=qa0O#A}t2l$#Fp=%4Dd>=(@1i)2bQXE4pvWUr1Yc@yi5TB!VIieM6 zk1y~JYM(Dsj1q6)h=GNIepJ)p8n(n)6$51$6%hw6!3NepgBjrw(a4r@x>o~_MlK8P zhhdT>Wf!>$ z*|nLCHCAPxpFivZ74&4gKXq=(?oA2KvdP=07IiG;=xA9xR$CTnQl^O0vge3j;#TDo z$!mgYr*R2}8NkrWPxEYuNGOy|t1ruY<(U9rLhwo$XQg=lN1P;y_Y8K8EwSm^Yr!wA z{C4>XOyCZ9oaPR@vbk~Ki|-MCz(b4^v$CNZ>(pwPBX9|k3GZ3rhuE#rDoBrKg1L1d z7r&)hf{@sx;u2*nkPP{x9OUEp6UgBA^h%BHhUIgW&p{Q)_L8gcjrpvwK$puW>eZ}r6 z_GsF=DK~HOO>#d^&;{c6RD48*2I3#kQcJg?Y9yL@wk+?7Bg913VeaCnG ztNwzX=`AWR40%4NZ{3@e$X>!wkbeq_Sb}gXcBr5fP3P4*9n<-Y4xdO(pNt3*6z;z5 c4a$GN7Uu&xQNzV%t0o>}`5k}R_x_9q zz46RYq&Bl|W4g7HMnNxWlHLHacQR=%@aLei{@g(0FKJ5zs2q7+yDKdru`2e@;?ieYq-LfbWIbQrwLscJ-u&uM&IBX&fFkZw(?We+gQ=fKz(KUdb-%`aW;EglyWH1 zCfl6DKLeM8>pHIR0*Y8$RRSVRVLdb_daSR4-NKFxp%^PF5ABW)hH4;AwK<-P0@?2l zT0K{)Pj?5)US+RZUJeFSp=QdMlVXr{UB=HYsth~ z33{W3={d_mv@C}kBd^jDVyH-)m>_?{NbFHdhJj2D|l4K124s+1QqgVRbMs89igo`@))@h zYZGHxo0wZK$HuC;W9@2hXx}+Ev9{dULhbmZ6qRBq__iTmj?EoAF71Mk>o4EY)?c`z z#b$U{y~SKD3qzPt2kRmFG1A%9aM#1%ijAELWntIQwZW;U%q_4aryGtz%_IBrArH!I-z^^;wvb^ z#!OBFU?_sFVBe_MY6o65?dx?Rek4+2ZLS1^M%kOqx1XwMAmwxHHX;f8-|L2v zr`~}|Vq%DV0lkNb`{Xa7(1*;+Sd^_o%D>$-%y+7oqh znI=hzdJUCG+lFBK5c8DZMpC^+%Ww;13X&=891o-!&1N|aLYmgYi#?hxHtWW48NGs+ zhy0YL%P*olAZ*1F>gb`i?da5jViEESXisWU(2`=fIq+$Yba@Glhd(`k@Y9{{pc}4S z!NC06zk+&OtpgR_>8{oGxx!S_Q5v{Rp+AJ4MOF+w69((5zjUx)xh<>NFcjkwhoVha z0s=XMU@L;a^lvxpq|{v*4%fV#lbK8Nd&6Z#pp@-j!XlEHtS|R=-tlZ#`{txOgE_VM ze)(n0J4}niU&>#14P!$(Ax)pxYq;dEqJFz=vI&3G_`*m15DyXdO*=L*V^f~O?)4Dm zjzJzpCi;w6-!>;!Y%S}sK-Q`ymoTcdYOj{%n~@W1+q7(HOC?;2OFLCH&*VJXqoT!% z_1F-lhn8wJr~Nl`<;A}`#NMi$ZGZ0i#vHsnn;l5WS`sm8`G z=5UsVgYz-h%swc~nR(S_#}vcPrYELFf)UE}zv55^iDaxY^%$ z-aTK8+W_S+yWgEO#>NG=*_cvX@QwmRfaodQ@s)K2!k~RkO6tig`^o?1FY;))&i^&CKh}QtUVx2zZE6c>aaU#n2Ked5p8zC4X!~tkA+3}K zYf7%v6qJzcD>y={O0Fogatf7Pfs_&eNRS7LuC%g7Q@)BZ4J$eBZ;S*?tKZ&`64*AC zIN++()F~ra9zlLu66RMe`;ZhRx&6y6g_7Y8ULVrVQLN-Qa4(k1) z?i;vxx9-=V^Cjy19c}QsrA78yRj%lGh856v%DdWK;Ma+=5~~huh0fWrnjfn-e5ikD zd}w~8y{`?7_fqR_Hsw`(wP7}!%|=DOje25+;8CU5g0?A`Syff#p_6*rEa7mMTJ1G> z&NMPeDg}g3oM5XBW$z4=aEgdFa?zeK{(MGIcN_ZRvX*UbR zSc5aID>bBQ+Pb`hzQ=nM`sF=(LfJCb$2#$w>e04QQ+^I&@M{>4rIHByI9|`qnjdTd ze#6hu#QeW3em?WNn4o}Mx(WF{o{J?@1PUieW(e8>T`mY?hqeS(1W*#De+MvCSZO^n zSFPB%q77=S?UZOMun`()d;F6smHZtg%kGW$Rq%BEotrloo40*FxX}>NOGia_v=5oM zyEGBXh`=E(2Mbm8nzuUc2Okhgeei+X4c+E&5L|FY(1Xc&?7KU1*jH937~Jd1;ebKn zf_js8^f7B0m%lr4&%^Y5rfXyS{9psnq6stp76_5LWWw3R7y=w-Z%oY5aFmM_W4OeD zj`}n<@*PfNK$8{(#)_ZcLnS1@(rhBMx={ljQ$2+$9>8MsTcAC7v1ZF>$ptwt3NShdV}mXWL;dgWVhzjfor;u~nz zq~JUjFoS9n1sGFl6G zL0?tEMKKR=pr9heddG;(AL#%Q*sBU-0KsC55R74ryo3P8jBUU$$QdA+7261`zK&LS zF+K_Np$YqHLjn~TQ%a(2i!NyZv0aPaLfMaKskW%7t zSS;;Ho@%cI?KM~)_$Nq$L}0WY;FLbXl=)LawSe~1P0 z8rpVnWdSWsQXP_2Q)Wu_78-6~SmBQdLMU0o3lYOvz`D^3eBLpr$-8>-1o*bA*HRDV zIh(C;i=xpeLl3svG_ML=CDV{LBv=@g588nwcjZkKiMb?}yz=W}>029JS}pS8u{)uO z{W-1-lM?SBPGM`Y1KKAW*A#~lBMYqkNd&%;_5cZ!*xWY0uSLcu+9&!aM#oeEwG->; zLtqY@g_O!eW|!=yH*<)!ZM?1c<9Ae+fS%%k*1>lk=w1DR@l)eRdg`l{TooD)wV}YI z9PG2Ex|H6Z#^b->N@L;Y9uc)iqhQYl02zrTP)jM}S>V-H3jU zWD9v2qz}v}Wxo_E zHNYW5m+Uz}KT6p(4yFAHG!Jp4X9(Q`M?4Ej2}_iaF+@s3l#%g+HiM=W8Da2v!Mz!T zNG83wnCpy7A#+=9jy3UoFN>`f+~%8YGK+t_7Z`@B62o-(z$7Y^HGo^vnhD%;6}ZI$ zZh14sEr@4ciArjmJ*Z|g$_k;(XUHb&O)*P8B9BZR#V1K~rcw#W6~JP08_AKkGp@Zw zdqAd1O0XPqtc5%rTnO$#uaj8ZVfrS?A%%2F(jVat7~hS2|KIVHViD5@8x$6S%2y3X zA(6U1K9X~OA)iyYmjg!N65d3mm&XNA8f&Y@Hu6dneNaO*huF8Ho`eb(Xq=DH5LnIe zbYZ|QBe^oJrn^O5j-R-af8C|Oe)X)xh^viKx@9wjcq;d}$vslOA?9P;5v$WDZ?m_v&P7Qj6`KCxjDE#Z~e=u5}c!TmR=fT67F!pTu<>?zS8|&@wxwe4Idz zx&rB_HV+6J)$$gJLR;F!_PI{n6F`!m~=_*xLBwAuGP;p!ZqTVy1kJZw^=x*Q6l_GUQ=&zZZ<_*IOgTs{-Q6 zgrT0yzzjw5mfC;U^GFOr4NLWg$ zwq)8dDI={K0bTFY9OW-o(fOaa!fPlrm?p-^z=7$7xS6#YN=H8igoqd#<*YHMpM*&x zI^Ijn!^iM#g65-owe;1gCD1 z)zM=_E4v!7Ly0Pyrsbs+<%#(~+d*<2$1l#VfdJNyDzUvBqk3ExRjBNbqnWr2^)AQdi4n~{fTBS?jA#xhYf5O_=C(BfCW#&YXzW1#Yt1$` zQ2cRA3VP7X0@kP$&Ne{@((Xv}F;PsCt3$C=YxJa&JrCuc%1Gjl5~7I|cU;Icg&N{# z!?UEBubW+j@AKb$BP0 zoLI(*8B{$@W-1^*{!MS`y2d0(g zV3x;E?&HP&afLik7RVFDkK?F-;(78JA!SB!VnBVaE=h7~-d%jWSe@>@81 z$C2tal@B*~6g9E#S7U2ir9Ri^5keRUA)0vzp^k*V7O5lPiTS>^KK~vr9`Q;MsY4KC zHZXTDXdurN86+K=Y_cF!N(>xZmzOrWJ?N)8=8&y!7yv?(n~EM@wP045m;mF6iH5^e zn(-+gdn3O{8XdzsG?gSsqX&f9rlU;Q_~d@79h_RwjI1tH?*<+KE`jEl_scU0I2_7O z9JUrfQ65R3$q&uLGw^*-$2B`V1DLBTn0qEFf26OU$qu9Q6sRLV#p_d(&zz`|@l>)bX`W^tZkjL+@gYA!?mBQkhE!i#NR!>hLDC@c~sMFVH) z#vN_zRHUM&Z5>;#W6RnOP(Des?m`ei3V9_eeFX7JHNj4I^XGV-{4on95nS?teGz6I zVy%1`ZEx@Gi)Tc$VCn%?Ew%+ADDrOHM4_t02$1g@ejuRjYNI-T$iNN7>NqZ6rhzm( zU`KnU1#vvGr?Js+6S^BBpP=OOGMD*f6v>f65C|Nh6tLuxLlnBan|m5NtB+6YV@R=Z zmFg};kIOF9mAHW*Z|hyf2ahEcH;rSr)h{9t`<%O>sS^uzN{QcG*ic&&YWr@cwor2X zlH+Ei;NZl7+S*WC8{9HvFT%0dDk7ZyYFkk}!_gk_uVUOm-IafVb;-YE@mDA^3oQSR z4S&tzpdph#M;q3Xt0mF!afN(wz>uru0b^FsCZm2q9Ws_{xsEHOG(ic$RKQ>|RK;&w z=RhR`vUv(AGo

uToA%7SCv7`~rphTt5jpz70=`^IB#Dgu&mIV9r&F1`e$%sc?X* zI2@$pgQ`tXbqZAdK}yxAwllp8!{?WoLs@TvqD?3_(>&&Qkp9TX9WJdRPQh^@0}JI0 z3vqFksO4^$=Y|(?wzx7Bg(IbNi@@E2HgN;Y@15oxg%)uc(pRyc1#Q`~beGjxlTj+)Na>Rf?ub{!pkK{550j!jf z0@O_PFuq3~hj>Dzi)9Zr@JGc0oUTsX)0ZC9zGOCgp^xJvb%?x0($q004Oq#bIt;7) zN50ayjn&?6G!!eCTIy^tVSsNN{EEqf1e5D5ct)K1bP`b61#d13iWXoRMX$Zccz?@Gway6W~x(;<5Xv#cFsE|XTARey^vc$ literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/setuponly.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/setuponly.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..923557442ab6e70b534dc282e0fd87c75fd390ea GIT binary patch literal 2416 zcmZuz-E!MR6xOa}S^i7h)Jf@e(}9UcwABeFd&KXRR0rl}Gz?_Uzen&VJ{Uzizea7CgJ>>gks-`U5AI zj}3#b;FX8aFpH7cnh>8%s81)hZxfW!*zq0HSNsaIne)=}UG9vltis%12&*#hrFBkx zkJVTm)@rQ5n$Xuvofhb;2=+i3g-PG!9DO$cwKlO!Yj9+DXcj-enDoWAY;NPx@cT;h-D<;AV_N9EJ&CI z4%GX8gYo@*G)$9&Xf$nXY)G#1EKTCmX|tSc;7r%0N(B#;$ocdmlyr?|_aHh^x#03n zm!;h#Rb76Eir29Y zjYaCjA=LaldN~qJSlR0lzj2tRFOEf+Wn2vLF7ZJa;yZ*_GH96f#4@*M&1gZ#WK6|# zWfz2zb1I$`*4Pn!Rl)w8h;2ZC12^qnkirV8M`j)7-fh4}P)$5s!;z{L0OxaBqQLI! z3ZyKY=*pwry~p46>e^iZLc5Ek>Y51}??+b;Lm4V1v>h?2JxE;~?#EoTz+K%OhQmY7 z0%Oi^m@bGC#!qx7!0kbamtX-3z<#}yFn*w`f*<9OYq1K(%(X3=2HNhFslK#eT)GJ> zvIC7pUE>)NL0M-==Nq5pf&j|0x(u?n8LxU1$`f#UyeI5(ud^g=0fXw=kuP1Q{J0 zk_|e~T~jnp-*1&+0`Buz`QF~{gCBOj{jo1@fZ1MEtU;$&FJqmANjTzS5mXzN#5HUX zB#RAHU>I)<`kgC5XQ>1-h>|dlrd;%3n?yt**gT9Le&TJIFCpc@1Tkr%{u2feD@1GH zMCZ0447;$!`-MGsF028aIkQSZ=ama<<`(YUy+8oE^D3jT)9Y9lq@3I1T0!P@<{;e0 z4OY2r&6^i!zXcRy8$Dpf7gW4bD?mN9m$4V{=O@eSc*bX2?xt{-?Ct zo!&Z=if6O#nH;7WhrUG9>@_AzAh`l29aPd4qvKag6|n+~|3i}mp?nLP!g{ub2x8U? zThM}F;T};&fM%(<1qywGW#A{e`H8keF}ecqziRhKJmDvq*xo^-ND7WM{oqY?vw1&8 z(vsVo%RSRh_ruat+07+q_qu1Z-jv?y8jww$r)RTgy_*7kHBj?gS)7leq)d-r12$bq z{B@bjj3+D@#p!++2W2At>!1=SE+z=T;8;X3)=nHHTvyD@_e{=`e4^chR7^spEAcpo zihdW4)s-CSPFErLB%E;VO8D4uroB=iwKGnm#MF=R+P{G%HsMzs(Y8F5uv@V-SEh&Z z>UpM&v^|ldMSw2&4bf>EwQNxFsXEpU$FbRfYMRR>;yjdlsG+zgj7p}AeQhBP30j)0g9pWM4Mr~SOGOSrTx90Esz!b z11Chg8boo_&I_--LSz3*7Jf>Fp=0moqIh0u7H5UvQr9lczGW)oWxXS0R_b_Km8k|hNU`|_76EZU4ndR$YK?vZz+d<~ zUgHI(#6W7G*ajw~>jmMEvXg3-@^YHZ&WGc%V!9F{Ps;P{&KMi39w^Nvi?yuS`8ze| zOK&+(v^UMpbS0Vcl9GCwDXqLEuX5_0Fpr(F6d1s{(jMjILw)6f=#`#lMQt2em$EQyzmye%3i^R&njpAd8Bbnd>p!3uBMq(IyEgY%j`y)R@{dJGypB|g2+1*uTgBR(ZV`zn?M5J3WC75 zYo~2P?X;xp{svSyN|SWXXbh#Uat&1)bd{%UTK6P7t$<8Zl2#2NXT8_a=tAS>x|{Gu z89vAwUfXk!0mP2x*}a7rR*A0^9G`gBXV0Oj#UD15TQMP}-nEr@f`= pMCi^r{|diL-f(KZzLvGg-;~9DQE*!2?4@C=Tu^(&wcO#J`yUZ&2WbER literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/skipping.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/skipping.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e8d2245081097cd2af5c94e7a6d74681950561b GIT binary patch literal 7689 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/__pycache__/unittest.cpython-37.pyc b/Lib/site-packages/_pytest/__pycache__/unittest.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7d242e363a7975c6ac9e5cd2e28c98644b9c33d GIT binary patch literal 7859 zcmcIpPi)*)dgs64aH!E}BrA&TI9{%uEHYbL-K1&OF1hvp>Z!l)ku&;d zw*`uh#7FY|{oeP!@Av)T$Mf^9hTomN{0Eb7YTCck%k*dA;TA6W3lvQAHKsEo)(3`f z3{2k~SiYrGof+5sn!4M*t?qT-!QF}*1J`#|pISUOX!^~;ygxr^`7Kpv#|wkD-ySUb zi-RS9X>i6rgZesio@@T{_cYdE?sJW~d~wh8U&H$xYvR4h&)|K9yKJ7dUg&IrwV!Ky zy8pVWSwzheJELmOZfbp;5@rKF~TVyEi=+$zJ+|i;)*5%oD>TiIPn(?Rzq3 zSL0|yglM`nOrkvJGQWiCQOrGhmaE>^;DpvOi-mAQrtvW6K{Uuxkrxh&oW5KWSaK)IirO=J=~zWO7hxj%Tm*wq>~JBA+U+=$ zvaml(*)ZmXbGMqVXA%YY(cQsy8<)I+Vst*&#zwAh8%#f^ZJT?BJj=8P+Lv0gY-zc* z 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 L8P0}tt$yqO(WXpS literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/_argcomplete.py b/Lib/site-packages/_pytest/_argcomplete.py new file mode 100644 index 0000000..8f480d7 --- /dev/null +++ b/Lib/site-packages/_pytest/_argcomplete.py @@ -0,0 +1,107 @@ + +"""allow bash-completion for argparse with argcomplete if installed +needs argcomplete>=0.5.6 for python 3.2/3.3 (older versions fail +to find the magic string, so _ARGCOMPLETE env. var is never set, and +this does not need special code. + +Function try_argcomplete(parser) should be called directly before +the call to ArgumentParser.parse_args(). + +The filescompleter is what you normally would use on the positional +arguments specification, in order to get "dirname/" after "dirn" +instead of the default "dirname ": + + optparser.add_argument(Config._file_or_dir, nargs='*' + ).completer=filescompleter + +Other, application specific, completers should go in the file +doing the add_argument calls as they need to be specified as .completer +attributes as well. (If argcomplete is not installed, the function the +attribute points to will not be used). + +SPEEDUP +======= +The generic argcomplete script for bash-completion +(/etc/bash_completion.d/python-argcomplete.sh ) +uses a python program to determine startup script generated by pip. +You can speed up completion somewhat by changing this script to include + # PYTHON_ARGCOMPLETE_OK +so the the python-argcomplete-check-easy-install-script does not +need to be called to find the entry point of the code and see if that is +marked with PYTHON_ARGCOMPLETE_OK + +INSTALL/DEBUGGING +================= +To include this support in another application that has setup.py generated +scripts: +- add the line: + # PYTHON_ARGCOMPLETE_OK + near the top of the main python entry point +- include in the file calling parse_args(): + from _argcomplete import try_argcomplete, filescompleter + , call try_argcomplete just before parse_args(), and optionally add + filescompleter to the positional arguments' add_argument() +If things do not work right away: +- switch on argcomplete debugging with (also helpful when doing custom + completers): + export _ARC_DEBUG=1 +- run: + python-argcomplete-check-easy-install-script $(which appname) + echo $? + will echo 0 if the magic line has been found, 1 if not +- sometimes it helps to find early on errors using: + _ARGCOMPLETE=1 _ARC_DEBUG=1 appname + which should throw a KeyError: 'COMPLINE' (which is properly set by the + global argcomplete script). +""" +from __future__ import absolute_import, division, print_function +import sys +import os +from glob import glob + + +class FastFilesCompleter(object): + "Fast file completer class" + + def __init__(self, directories=True): + self.directories = directories + + def __call__(self, prefix, **kwargs): + """only called on non option completions""" + if os.path.sep in prefix[1:]: + prefix_dir = len(os.path.dirname(prefix) + os.path.sep) + else: + prefix_dir = 0 + completion = [] + globbed = [] + if "*" not in prefix and "?" not in prefix: + # we are on unix, otherwise no bash + if not prefix or prefix[-1] == os.path.sep: + globbed.extend(glob(prefix + ".*")) + prefix += "*" + globbed.extend(glob(prefix)) + for x in sorted(globbed): + if os.path.isdir(x): + x += "/" + # append stripping the prefix (like bash, not like compgen) + completion.append(x[prefix_dir:]) + return completion + + +if os.environ.get("_ARGCOMPLETE"): + try: + import argcomplete.completers + except ImportError: + sys.exit(-1) + filescompleter = FastFilesCompleter() + + def try_argcomplete(parser): + argcomplete.autocomplete(parser, always_complete_options=False) + + +else: + + def try_argcomplete(parser): + pass + + filescompleter = None diff --git a/Lib/site-packages/_pytest/_code/__init__.py b/Lib/site-packages/_pytest/_code/__init__.py new file mode 100644 index 0000000..815c13b --- /dev/null +++ b/Lib/site-packages/_pytest/_code/__init__.py @@ -0,0 +1,10 @@ +""" python inspection/code generation API """ +from __future__ import absolute_import, division, print_function +from .code import Code # noqa +from .code import ExceptionInfo # noqa +from .code import Frame # noqa +from .code import Traceback # noqa +from .code import getrawcode # noqa +from .source import Source # noqa +from .source import compile_ as compile # noqa +from .source import getfslineno # noqa diff --git a/Lib/site-packages/_pytest/_code/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/_pytest/_code/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..160a589f814cdbe61c183be0b7484e9a82202bb4 GIT binary patch literal 604 zcmY+B%Wl*#6o#EiCbyY%D&PUKL$fFd7Tkm?N*Sa|s6uK%s)=N|v8Pz|4ch^V*zp#; z0k4!TtG)s&jw8CjQGS2_v31VL$;+mx5v>A0fj-pC=0=$4bTQ7y?+8nQU$AS=MdP2sUK>08@PKb+Bc4?Fh zWXxhlmq%YjDWg8b2axw4%Vb`NG6sFZu3o-pGcK6={0tho;zx!Ge+9U(%CK*&9NHI~nn UVT0uRad`d~NS545mj69}0lFiiasU7T literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/_code/__pycache__/_py2traceback.cpython-37.pyc b/Lib/site-packages/_pytest/_code/__pycache__/_py2traceback.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..347c81f10de160bbea8a308f3e0d643fb2bd8cb3 GIT binary patch literal 2301 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 bo*JJzI#rq~Po0|DKQ%UWsJtHvc=7)LQESX7 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/_code/__pycache__/source.cpython-37.pyc b/Lib/site-packages/_pytest/_code/__pycache__/source.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fff8a822e28961e7799c8fffe46e8a652da495e0 GIT binary patch literal 10561 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 Ie%@XFKUZd^;s5{u literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/_code/_py2traceback.py b/Lib/site-packages/_pytest/_code/_py2traceback.py new file mode 100644 index 0000000..2dd100c --- /dev/null +++ b/Lib/site-packages/_pytest/_code/_py2traceback.py @@ -0,0 +1,89 @@ +# copied from python-2.7.3's traceback.py +# CHANGES: +# - some_str is replaced, trying to create unicode strings +# +from __future__ import absolute_import, division, print_function +import types +from six import text_type + + +def format_exception_only(etype, value): + """Format the exception part of a traceback. + + The arguments are the exception type and value such as given by + sys.last_type and sys.last_value. The return value is a list of + strings, each ending in a newline. + + Normally, the list contains a single string; however, for + SyntaxError exceptions, it contains several lines that (when + printed) display detailed information about where the syntax + error occurred. + + The message indicating which exception occurred is always the last + string in the list. + + """ + + # An instance should not have a meaningful value parameter, but + # sometimes does, particularly for string exceptions, such as + # >>> raise string1, string2 # deprecated + # + # Clear these out first because issubtype(string1, SyntaxError) + # would throw another exception and mask the original problem. + if ( + isinstance(etype, BaseException) + or isinstance(etype, types.InstanceType) + or etype is None + or type(etype) is str + ): + return [_format_final_exc_line(etype, value)] + + stype = etype.__name__ + + if not issubclass(etype, SyntaxError): + return [_format_final_exc_line(stype, value)] + + # It was a syntax error; show exactly where the problem was found. + lines = [] + try: + msg, (filename, lineno, offset, badline) = value.args + except Exception: + pass + else: + filename = filename or "" + lines.append(' File "%s", line %d\n' % (filename, lineno)) + if badline is not None: + if isinstance(badline, bytes): # python 2 only + badline = badline.decode("utf-8", "replace") + lines.append(u" %s\n" % badline.strip()) + if offset is not None: + caretspace = badline.rstrip("\n")[:offset].lstrip() + # non-space whitespace (likes tabs) must be kept for alignment + caretspace = ((c.isspace() and c or " ") for c in caretspace) + # only three spaces to account for offset1 == pos 0 + lines.append(" %s^\n" % "".join(caretspace)) + value = msg + + lines.append(_format_final_exc_line(stype, value)) + return lines + + +def _format_final_exc_line(etype, value): + """Return a list of a single line -- normal case for format_exception_only""" + valuestr = _some_str(value) + if value is None or not valuestr: + line = "%s\n" % etype + else: + line = "%s: %s\n" % (etype, valuestr) + return line + + +def _some_str(value): + try: + return text_type(value) + except Exception: + try: + return str(value) + except Exception: + pass + return "" % type(value).__name__ diff --git a/Lib/site-packages/_pytest/_code/code.py b/Lib/site-packages/_pytest/_code/code.py new file mode 100644 index 0000000..78644db --- /dev/null +++ b/Lib/site-packages/_pytest/_code/code.py @@ -0,0 +1,978 @@ +from __future__ import absolute_import, division, print_function +import inspect +import pprint +import sys +import traceback +from inspect import CO_VARARGS, CO_VARKEYWORDS + +import attr +import re +from weakref import ref +from _pytest.compat import _PY2, _PY3, PY35, safe_str +from six import text_type +import py + +builtin_repr = repr + +if _PY3: + from traceback import format_exception_only +else: + from ._py2traceback import format_exception_only + + +class Code(object): + """ wrapper around Python code objects """ + + def __init__(self, rawcode): + if not hasattr(rawcode, "co_filename"): + rawcode = getrawcode(rawcode) + try: + self.filename = rawcode.co_filename + self.firstlineno = rawcode.co_firstlineno - 1 + self.name = rawcode.co_name + except AttributeError: + raise TypeError("not a code object: %r" % (rawcode,)) + self.raw = rawcode + + def __eq__(self, other): + return self.raw == other.raw + + __hash__ = None + + def __ne__(self, other): + return not self == other + + @property + def path(self): + """ return a path object pointing to source code (note that it + might not point to an actually existing file). """ + try: + p = py.path.local(self.raw.co_filename) + # maybe don't try this checking + if not p.check(): + raise OSError("py.path check failed.") + except OSError: + # XXX maybe try harder like the weird logic + # in the standard lib [linecache.updatecache] does? + p = self.raw.co_filename + + return p + + @property + def fullsource(self): + """ return a _pytest._code.Source object for the full source file of the code + """ + from _pytest._code import source + + full, _ = source.findsource(self.raw) + return full + + def source(self): + """ return a _pytest._code.Source object for the code object's source only + """ + # return source only for that part of code + import _pytest._code + + return _pytest._code.Source(self.raw) + + def getargs(self, var=False): + """ return a tuple with the argument names for the code object + + if 'var' is set True also return the names of the variable and + keyword arguments when present + """ + # handfull shortcut for getting args + raw = self.raw + argcount = raw.co_argcount + if var: + argcount += raw.co_flags & CO_VARARGS + argcount += raw.co_flags & CO_VARKEYWORDS + return raw.co_varnames[:argcount] + + +class Frame(object): + """Wrapper around a Python frame holding f_locals and f_globals + in which expressions can be evaluated.""" + + def __init__(self, frame): + self.lineno = frame.f_lineno - 1 + self.f_globals = frame.f_globals + self.f_locals = frame.f_locals + self.raw = frame + self.code = Code(frame.f_code) + + @property + def statement(self): + """ statement this frame is at """ + import _pytest._code + + if self.code.fullsource is None: + return _pytest._code.Source("") + return self.code.fullsource.getstatement(self.lineno) + + def eval(self, code, **vars): + """ evaluate 'code' in the frame + + 'vars' are optional additional local variables + + returns the result of the evaluation + """ + f_locals = self.f_locals.copy() + f_locals.update(vars) + return eval(code, self.f_globals, f_locals) + + def exec_(self, code, **vars): + """ exec 'code' in the frame + + 'vars' are optiona; additional local variables + """ + f_locals = self.f_locals.copy() + f_locals.update(vars) + py.builtin.exec_(code, self.f_globals, f_locals) + + def repr(self, object): + """ return a 'safe' (non-recursive, one-line) string repr for 'object' + """ + return py.io.saferepr(object) + + def is_true(self, object): + return object + + def getargs(self, var=False): + """ return a list of tuples (name, value) for all arguments + + if 'var' is set True also include the variable and keyword + arguments when present + """ + retval = [] + for arg in self.code.getargs(var): + try: + retval.append((arg, self.f_locals[arg])) + except KeyError: + pass # this can occur when using Psyco + return retval + + +class TracebackEntry(object): + """ a single entry in a traceback """ + + _repr_style = None + exprinfo = None + + def __init__(self, rawentry, excinfo=None): + self._excinfo = excinfo + self._rawentry = rawentry + self.lineno = rawentry.tb_lineno - 1 + + def set_repr_style(self, mode): + assert mode in ("short", "long") + self._repr_style = mode + + @property + def frame(self): + import _pytest._code + + return _pytest._code.Frame(self._rawentry.tb_frame) + + @property + def relline(self): + return self.lineno - self.frame.code.firstlineno + + def __repr__(self): + return "" % (self.frame.code.path, self.lineno + 1) + + @property + def statement(self): + """ _pytest._code.Source object for the current statement """ + source = self.frame.code.fullsource + return source.getstatement(self.lineno) + + @property + def path(self): + """ path to the source code """ + return self.frame.code.path + + def getlocals(self): + return self.frame.f_locals + + locals = property(getlocals, None, None, "locals of underlaying frame") + + def getfirstlinesource(self): + # on Jython this firstlineno can be -1 apparently + return max(self.frame.code.firstlineno, 0) + + def getsource(self, astcache=None): + """ return failing source code. """ + # we use the passed in astcache to not reparse asttrees + # within exception info printing + from _pytest._code.source import getstatementrange_ast + + source = self.frame.code.fullsource + if source is None: + return None + key = astnode = None + if astcache is not None: + key = self.frame.code.path + if key is not None: + astnode = astcache.get(key, None) + start = self.getfirstlinesource() + try: + astnode, _, end = getstatementrange_ast( + self.lineno, source, astnode=astnode + ) + except SyntaxError: + end = self.lineno + 1 + else: + if key is not None: + astcache[key] = astnode + return source[start:end] + + source = property(getsource) + + def ishidden(self): + """ return True if the current frame has a var __tracebackhide__ + resolving to True + + If __tracebackhide__ is a callable, it gets called with the + ExceptionInfo instance and can decide whether to hide the traceback. + + mostly for internal use + """ + try: + tbh = self.frame.f_locals["__tracebackhide__"] + except KeyError: + try: + tbh = self.frame.f_globals["__tracebackhide__"] + except KeyError: + return False + + if callable(tbh): + return tbh(None if self._excinfo is None else self._excinfo()) + else: + return tbh + + def __str__(self): + try: + fn = str(self.path) + except py.error.Error: + fn = "???" + name = self.frame.code.name + try: + line = str(self.statement).lstrip() + except KeyboardInterrupt: + raise + except: # noqa + line = "???" + return " File %r:%d in %s\n %s\n" % (fn, self.lineno + 1, name, line) + + def name(self): + return self.frame.code.raw.co_name + + name = property(name, None, None, "co_name of underlaying code") + + +class Traceback(list): + """ Traceback objects encapsulate and offer higher level + access to Traceback entries. + """ + + Entry = TracebackEntry + + def __init__(self, tb, excinfo=None): + """ initialize from given python traceback object and ExceptionInfo """ + self._excinfo = excinfo + if hasattr(tb, "tb_next"): + + def f(cur): + while cur is not None: + yield self.Entry(cur, excinfo=excinfo) + cur = cur.tb_next + + list.__init__(self, f(tb)) + else: + list.__init__(self, tb) + + def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None): + """ return a Traceback instance wrapping part of this Traceback + + by provding any combination of path, lineno and firstlineno, the + first frame to start the to-be-returned traceback is determined + + this allows cutting the first part of a Traceback instance e.g. + for formatting reasons (removing some uninteresting bits that deal + with handling of the exception/traceback) + """ + for x in self: + code = x.frame.code + codepath = code.path + if ( + (path is None or codepath == path) + and ( + excludepath is None + or not hasattr(codepath, "relto") + or not codepath.relto(excludepath) + ) + and (lineno is None or x.lineno == lineno) + and (firstlineno is None or x.frame.code.firstlineno == firstlineno) + ): + return Traceback(x._rawentry, self._excinfo) + return self + + def __getitem__(self, key): + val = super(Traceback, self).__getitem__(key) + if isinstance(key, type(slice(0))): + val = self.__class__(val) + return val + + def filter(self, fn=lambda x: not x.ishidden()): + """ return a Traceback instance with certain items removed + + fn is a function that gets a single argument, a TracebackEntry + instance, and should return True when the item should be added + to the Traceback, False when not + + by default this removes all the TracebackEntries which are hidden + (see ishidden() above) + """ + return Traceback(filter(fn, self), self._excinfo) + + def getcrashentry(self): + """ return last non-hidden traceback entry that lead + to the exception of a traceback. + """ + for i in range(-1, -len(self) - 1, -1): + entry = self[i] + if not entry.ishidden(): + return entry + return self[-1] + + def recursionindex(self): + """ return the index of the frame/TracebackEntry where recursion + originates if appropriate, None if no recursion occurred + """ + cache = {} + for i, entry in enumerate(self): + # id for the code.raw is needed to work around + # the strange metaprogramming in the decorator lib from pypi + # which generates code objects that have hash/value equality + # XXX needs a test + key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno + # print "checking for recursion at", key + values = cache.setdefault(key, []) + if values: + f = entry.frame + loc = f.f_locals + for otherloc in values: + if f.is_true( + f.eval( + co_equal, + __recursioncache_locals_1=loc, + __recursioncache_locals_2=otherloc, + ) + ): + return i + values.append(entry.frame.f_locals) + return None + + +co_equal = compile( + "__recursioncache_locals_1 == __recursioncache_locals_2", "?", "eval" +) + + +class ExceptionInfo(object): + """ wraps sys.exc_info() objects and offers + help for navigating the traceback. + """ + + _striptext = "" + _assert_start_repr = ( + "AssertionError(u'assert " if _PY2 else "AssertionError('assert " + ) + + def __init__(self, tup=None, exprinfo=None): + import _pytest._code + + if tup is None: + tup = sys.exc_info() + if exprinfo is None and isinstance(tup[1], AssertionError): + exprinfo = getattr(tup[1], "msg", None) + if exprinfo is None: + exprinfo = py.io.saferepr(tup[1]) + if exprinfo and exprinfo.startswith(self._assert_start_repr): + self._striptext = "AssertionError: " + self._excinfo = tup + #: the exception class + self.type = tup[0] + #: the exception instance + self.value = tup[1] + #: the exception raw traceback + self.tb = tup[2] + #: the exception type name + self.typename = self.type.__name__ + #: the exception traceback (_pytest._code.Traceback instance) + self.traceback = _pytest._code.Traceback(self.tb, excinfo=ref(self)) + + def __repr__(self): + return "" % (self.typename, len(self.traceback)) + + def exconly(self, tryshort=False): + """ return the exception as a string + + when 'tryshort' resolves to True, and the exception is a + _pytest._code._AssertionError, only the actual exception part of + the exception representation is returned (so 'AssertionError: ' is + removed from the beginning) + """ + lines = format_exception_only(self.type, self.value) + text = "".join(lines) + text = text.rstrip() + if tryshort: + if text.startswith(self._striptext): + text = text[len(self._striptext) :] + return text + + def errisinstance(self, exc): + """ return True if the exception is an instance of exc """ + return isinstance(self.value, exc) + + def _getreprcrash(self): + exconly = self.exconly(tryshort=True) + entry = self.traceback.getcrashentry() + path, lineno = entry.frame.code.raw.co_filename, entry.lineno + return ReprFileLocation(path, lineno + 1, exconly) + + def getrepr( + self, + showlocals=False, + style="long", + abspath=False, + tbfilter=True, + funcargs=False, + truncate_locals=True, + ): + """ return str()able representation of this exception info. + showlocals: show locals per traceback entry + style: long|short|no|native traceback style + tbfilter: hide entries (where __tracebackhide__ is true) + + in case of style==native, tbfilter and showlocals is ignored. + """ + if style == "native": + return ReprExceptionInfo( + ReprTracebackNative( + traceback.format_exception( + self.type, self.value, self.traceback[0]._rawentry + ) + ), + self._getreprcrash(), + ) + + fmt = FormattedExcinfo( + showlocals=showlocals, + style=style, + abspath=abspath, + tbfilter=tbfilter, + funcargs=funcargs, + truncate_locals=truncate_locals, + ) + return fmt.repr_excinfo(self) + + def __str__(self): + entry = self.traceback[-1] + loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly()) + return str(loc) + + def __unicode__(self): + entry = self.traceback[-1] + loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly()) + return text_type(loc) + + def match(self, regexp): + """ + Match the regular expression 'regexp' on the string representation of + the exception. If it matches then True is returned (so that it is + possible to write 'assert excinfo.match()'). If it doesn't match an + AssertionError is raised. + """ + __tracebackhide__ = True + if not re.search(regexp, str(self.value)): + assert 0, "Pattern '{!s}' not found in '{!s}'".format(regexp, self.value) + return True + + +@attr.s +class FormattedExcinfo(object): + """ presenting information about failing Functions and Generators. """ + + # for traceback entries + flow_marker = ">" + fail_marker = "E" + + showlocals = attr.ib(default=False) + style = attr.ib(default="long") + abspath = attr.ib(default=True) + tbfilter = attr.ib(default=True) + funcargs = attr.ib(default=False) + truncate_locals = attr.ib(default=True) + astcache = attr.ib(default=attr.Factory(dict), init=False, repr=False) + + def _getindent(self, source): + # figure out indent for given source + try: + s = str(source.getstatement(len(source) - 1)) + except KeyboardInterrupt: + raise + except: # noqa + try: + s = str(source[-1]) + except KeyboardInterrupt: + raise + except: # noqa + return 0 + return 4 + (len(s) - len(s.lstrip())) + + def _getentrysource(self, entry): + source = entry.getsource(self.astcache) + if source is not None: + source = source.deindent() + return source + + def _saferepr(self, obj): + return py.io.saferepr(obj) + + def repr_args(self, entry): + if self.funcargs: + args = [] + for argname, argvalue in entry.frame.getargs(var=True): + args.append((argname, self._saferepr(argvalue))) + return ReprFuncArgs(args) + + def get_source(self, source, line_index=-1, excinfo=None, short=False): + """ return formatted and marked up source lines. """ + import _pytest._code + + lines = [] + if source is None or line_index >= len(source.lines): + source = _pytest._code.Source("???") + line_index = 0 + if line_index < 0: + line_index += len(source) + space_prefix = " " + if short: + lines.append(space_prefix + source.lines[line_index].strip()) + else: + for line in source.lines[:line_index]: + lines.append(space_prefix + line) + lines.append(self.flow_marker + " " + source.lines[line_index]) + for line in source.lines[line_index + 1 :]: + lines.append(space_prefix + line) + if excinfo is not None: + indent = 4 if short else self._getindent(source) + lines.extend(self.get_exconly(excinfo, indent=indent, markall=True)) + return lines + + def get_exconly(self, excinfo, indent=4, markall=False): + lines = [] + indent = " " * indent + # get the real exception information out + exlines = excinfo.exconly(tryshort=True).split("\n") + failindent = self.fail_marker + indent[1:] + for line in exlines: + lines.append(failindent + line) + if not markall: + failindent = indent + return lines + + def repr_locals(self, locals): + if self.showlocals: + lines = [] + keys = [loc for loc in locals if loc[0] != "@"] + keys.sort() + for name in keys: + value = locals[name] + if name == "__builtins__": + lines.append("__builtins__ = ") + else: + # This formatting could all be handled by the + # _repr() function, which is only reprlib.Repr in + # disguise, so is very configurable. + if self.truncate_locals: + str_repr = self._saferepr(value) + else: + str_repr = pprint.pformat(value) + # if len(str_repr) < 70 or not isinstance(value, + # (list, tuple, dict)): + lines.append("%-10s = %s" % (name, str_repr)) + # else: + # self._line("%-10s =\\" % (name,)) + # # XXX + # pprint.pprint(value, stream=self.excinfowriter) + return ReprLocals(lines) + + def repr_traceback_entry(self, entry, excinfo=None): + import _pytest._code + + source = self._getentrysource(entry) + if source is None: + source = _pytest._code.Source("???") + line_index = 0 + else: + # entry.getfirstlinesource() can be -1, should be 0 on jython + line_index = entry.lineno - max(entry.getfirstlinesource(), 0) + + lines = [] + style = entry._repr_style + if style is None: + style = self.style + if style in ("short", "long"): + short = style == "short" + reprargs = self.repr_args(entry) if not short else None + s = self.get_source(source, line_index, excinfo, short=short) + lines.extend(s) + if short: + message = "in %s" % (entry.name) + else: + message = excinfo and excinfo.typename or "" + path = self._makepath(entry.path) + filelocrepr = ReprFileLocation(path, entry.lineno + 1, message) + localsrepr = None + if not short: + localsrepr = self.repr_locals(entry.locals) + return ReprEntry(lines, reprargs, localsrepr, filelocrepr, style) + if excinfo: + lines.extend(self.get_exconly(excinfo, indent=4)) + return ReprEntry(lines, None, None, None, style) + + def _makepath(self, path): + if not self.abspath: + try: + np = py.path.local().bestrelpath(path) + except OSError: + return path + if len(np) < len(str(path)): + path = np + return path + + def repr_traceback(self, excinfo): + traceback = excinfo.traceback + if self.tbfilter: + traceback = traceback.filter() + + if is_recursion_error(excinfo): + traceback, extraline = self._truncate_recursive_traceback(traceback) + else: + extraline = None + + last = traceback[-1] + entries = [] + for index, entry in enumerate(traceback): + einfo = (last == entry) and excinfo or None + reprentry = self.repr_traceback_entry(entry, einfo) + entries.append(reprentry) + return ReprTraceback(entries, extraline, style=self.style) + + def _truncate_recursive_traceback(self, traceback): + """ + Truncate the given recursive traceback trying to find the starting point + of the recursion. + + The detection is done by going through each traceback entry and finding the + point in which the locals of the frame are equal to the locals of a previous frame (see ``recursionindex()``. + + Handle the situation where the recursion process might raise an exception (for example + comparing numpy arrays using equality raises a TypeError), in which case we do our best to + warn the user of the error and show a limited traceback. + """ + try: + recursionindex = traceback.recursionindex() + except Exception as e: + max_frames = 10 + extraline = ( + "!!! Recursion error detected, but an error occurred locating the origin of recursion.\n" + " The following exception happened when comparing locals in the stack frame:\n" + " {exc_type}: {exc_msg}\n" + " Displaying first and last {max_frames} stack frames out of {total}." + ).format( + exc_type=type(e).__name__, + exc_msg=safe_str(e), + max_frames=max_frames, + total=len(traceback), + ) + traceback = traceback[:max_frames] + traceback[-max_frames:] + else: + if recursionindex is not None: + extraline = "!!! Recursion detected (same locals & position)" + traceback = traceback[: recursionindex + 1] + else: + extraline = None + + return traceback, extraline + + def repr_excinfo(self, excinfo): + if _PY2: + reprtraceback = self.repr_traceback(excinfo) + reprcrash = excinfo._getreprcrash() + + return ReprExceptionInfo(reprtraceback, reprcrash) + else: + repr_chain = [] + e = excinfo.value + descr = None + while e is not None: + if excinfo: + reprtraceback = self.repr_traceback(excinfo) + reprcrash = excinfo._getreprcrash() + else: + # fallback to native repr if the exception doesn't have a traceback: + # ExceptionInfo objects require a full traceback to work + reprtraceback = ReprTracebackNative( + traceback.format_exception(type(e), e, None) + ) + reprcrash = None + + repr_chain += [(reprtraceback, reprcrash, descr)] + if e.__cause__ is not None: + e = e.__cause__ + excinfo = ( + ExceptionInfo((type(e), e, e.__traceback__)) + if e.__traceback__ + else None + ) + descr = "The above exception was the direct cause of the following exception:" + elif e.__context__ is not None and not e.__suppress_context__: + e = e.__context__ + excinfo = ( + ExceptionInfo((type(e), e, e.__traceback__)) + if e.__traceback__ + else None + ) + descr = "During handling of the above exception, another exception occurred:" + else: + e = None + repr_chain.reverse() + return ExceptionChainRepr(repr_chain) + + +class TerminalRepr(object): + def __str__(self): + s = self.__unicode__() + if _PY2: + s = s.encode("utf-8") + return s + + def __unicode__(self): + # FYI this is called from pytest-xdist's serialization of exception + # information. + io = py.io.TextIO() + tw = py.io.TerminalWriter(file=io) + self.toterminal(tw) + return io.getvalue().strip() + + def __repr__(self): + return "<%s instance at %0x>" % (self.__class__, id(self)) + + +class ExceptionRepr(TerminalRepr): + def __init__(self): + self.sections = [] + + def addsection(self, name, content, sep="-"): + self.sections.append((name, content, sep)) + + def toterminal(self, tw): + for name, content, sep in self.sections: + tw.sep(sep, name) + tw.line(content) + + +class ExceptionChainRepr(ExceptionRepr): + def __init__(self, chain): + super(ExceptionChainRepr, self).__init__() + self.chain = chain + # reprcrash and reprtraceback of the outermost (the newest) exception + # in the chain + self.reprtraceback = chain[-1][0] + self.reprcrash = chain[-1][1] + + def toterminal(self, tw): + for element in self.chain: + element[0].toterminal(tw) + if element[2] is not None: + tw.line("") + tw.line(element[2], yellow=True) + super(ExceptionChainRepr, self).toterminal(tw) + + +class ReprExceptionInfo(ExceptionRepr): + def __init__(self, reprtraceback, reprcrash): + super(ReprExceptionInfo, self).__init__() + self.reprtraceback = reprtraceback + self.reprcrash = reprcrash + + def toterminal(self, tw): + self.reprtraceback.toterminal(tw) + super(ReprExceptionInfo, self).toterminal(tw) + + +class ReprTraceback(TerminalRepr): + entrysep = "_ " + + def __init__(self, reprentries, extraline, style): + self.reprentries = reprentries + self.extraline = extraline + self.style = style + + def toterminal(self, tw): + # the entries might have different styles + for i, entry in enumerate(self.reprentries): + if entry.style == "long": + tw.line("") + entry.toterminal(tw) + if i < len(self.reprentries) - 1: + next_entry = self.reprentries[i + 1] + if ( + entry.style == "long" + or entry.style == "short" + and next_entry.style == "long" + ): + tw.sep(self.entrysep) + + if self.extraline: + tw.line(self.extraline) + + +class ReprTracebackNative(ReprTraceback): + def __init__(self, tblines): + self.style = "native" + self.reprentries = [ReprEntryNative(tblines)] + self.extraline = None + + +class ReprEntryNative(TerminalRepr): + style = "native" + + def __init__(self, tblines): + self.lines = tblines + + def toterminal(self, tw): + tw.write("".join(self.lines)) + + +class ReprEntry(TerminalRepr): + localssep = "_ " + + def __init__(self, lines, reprfuncargs, reprlocals, filelocrepr, style): + self.lines = lines + self.reprfuncargs = reprfuncargs + self.reprlocals = reprlocals + self.reprfileloc = filelocrepr + self.style = style + + def toterminal(self, tw): + if self.style == "short": + self.reprfileloc.toterminal(tw) + for line in self.lines: + red = line.startswith("E ") + tw.line(line, bold=True, red=red) + # tw.line("") + return + if self.reprfuncargs: + self.reprfuncargs.toterminal(tw) + for line in self.lines: + red = line.startswith("E ") + tw.line(line, bold=True, red=red) + if self.reprlocals: + # tw.sep(self.localssep, "Locals") + tw.line("") + self.reprlocals.toterminal(tw) + if self.reprfileloc: + if self.lines: + tw.line("") + self.reprfileloc.toterminal(tw) + + def __str__(self): + return "%s\n%s\n%s" % ("\n".join(self.lines), self.reprlocals, self.reprfileloc) + + +class ReprFileLocation(TerminalRepr): + def __init__(self, path, lineno, message): + self.path = str(path) + self.lineno = lineno + self.message = message + + def toterminal(self, tw): + # filename and lineno output for each entry, + # using an output format that most editors unterstand + msg = self.message + i = msg.find("\n") + if i != -1: + msg = msg[:i] + tw.write(self.path, bold=True, red=True) + tw.line(":%s: %s" % (self.lineno, msg)) + + +class ReprLocals(TerminalRepr): + def __init__(self, lines): + self.lines = lines + + def toterminal(self, tw): + for line in self.lines: + tw.line(line) + + +class ReprFuncArgs(TerminalRepr): + def __init__(self, args): + self.args = args + + def toterminal(self, tw): + if self.args: + linesofar = "" + for name, value in self.args: + ns = "%s = %s" % (safe_str(name), safe_str(value)) + if len(ns) + len(linesofar) + 2 > tw.fullwidth: + if linesofar: + tw.line(linesofar) + linesofar = ns + else: + if linesofar: + linesofar += ", " + ns + else: + linesofar = ns + if linesofar: + tw.line(linesofar) + tw.line("") + + +def getrawcode(obj, trycall=True): + """ return code object for given function. """ + try: + return obj.__code__ + except AttributeError: + obj = getattr(obj, "im_func", obj) + obj = getattr(obj, "func_code", obj) + obj = getattr(obj, "f_code", obj) + obj = getattr(obj, "__code__", obj) + if trycall and not hasattr(obj, "co_firstlineno"): + if hasattr(obj, "__call__") and not inspect.isclass(obj): + x = getrawcode(obj.__call__, trycall=False) + if hasattr(x, "co_firstlineno"): + return x + return obj + + +if PY35: # RecursionError introduced in 3.5 + + def is_recursion_error(excinfo): + return excinfo.errisinstance(RecursionError) # noqa + + +else: + + def is_recursion_error(excinfo): + if not excinfo.errisinstance(RuntimeError): + return False + try: + return "maximum recursion depth exceeded" in str(excinfo.value) + except UnicodeError: + return False diff --git a/Lib/site-packages/_pytest/_code/source.py b/Lib/site-packages/_pytest/_code/source.py new file mode 100644 index 0000000..3b037b7 --- /dev/null +++ b/Lib/site-packages/_pytest/_code/source.py @@ -0,0 +1,373 @@ +from __future__ import absolute_import, division, print_function + +import ast +from ast import PyCF_ONLY_AST as _AST_FLAG +from bisect import bisect_right +import linecache +import sys +import six +import inspect +import tokenize +import py + +cpy_compile = compile + + +class Source(object): + """ an immutable object holding a source code fragment, + possibly deindenting it. + """ + + _compilecounter = 0 + + def __init__(self, *parts, **kwargs): + self.lines = lines = [] + de = kwargs.get("deindent", True) + rstrip = kwargs.get("rstrip", True) + for part in parts: + if not part: + partlines = [] + elif isinstance(part, Source): + partlines = part.lines + elif isinstance(part, (tuple, list)): + partlines = [x.rstrip("\n") for x in part] + elif isinstance(part, six.string_types): + partlines = part.split("\n") + if rstrip: + while partlines: + if partlines[-1].strip(): + break + partlines.pop() + else: + partlines = getsource(part, deindent=de).lines + if de: + partlines = deindent(partlines) + lines.extend(partlines) + + def __eq__(self, other): + try: + return self.lines == other.lines + except AttributeError: + if isinstance(other, str): + return str(self) == other + return False + + __hash__ = None + + def __getitem__(self, key): + if isinstance(key, int): + return self.lines[key] + else: + if key.step not in (None, 1): + raise IndexError("cannot slice a Source with a step") + newsource = Source() + newsource.lines = self.lines[key.start : key.stop] + return newsource + + def __len__(self): + return len(self.lines) + + def strip(self): + """ return new source object with trailing + and leading blank lines removed. + """ + start, end = 0, len(self) + while start < end and not self.lines[start].strip(): + start += 1 + while end > start and not self.lines[end - 1].strip(): + end -= 1 + source = Source() + source.lines[:] = self.lines[start:end] + return source + + def putaround(self, before="", after="", indent=" " * 4): + """ return a copy of the source object with + 'before' and 'after' wrapped around it. + """ + before = Source(before) + after = Source(after) + newsource = Source() + lines = [(indent + line) for line in self.lines] + newsource.lines = before.lines + lines + after.lines + return newsource + + def indent(self, indent=" " * 4): + """ return a copy of the source object with + all lines indented by the given indent-string. + """ + newsource = Source() + newsource.lines = [(indent + line) for line in self.lines] + return newsource + + def getstatement(self, lineno): + """ return Source statement which contains the + given linenumber (counted from 0). + """ + start, end = self.getstatementrange(lineno) + return self[start:end] + + def getstatementrange(self, lineno): + """ return (start, end) tuple which spans the minimal + statement region which containing the given lineno. + """ + if not (0 <= lineno < len(self)): + raise IndexError("lineno out of range") + ast, start, end = getstatementrange_ast(lineno, self) + return start, end + + def deindent(self, offset=None): + """ return a new source object deindented by offset. + If offset is None then guess an indentation offset from + the first non-blank line. Subsequent lines which have a + lower indentation offset will be copied verbatim as + they are assumed to be part of multilines. + """ + # XXX maybe use the tokenizer to properly handle multiline + # strings etc.pp? + newsource = Source() + newsource.lines[:] = deindent(self.lines, offset) + return newsource + + def isparseable(self, deindent=True): + """ return True if source is parseable, heuristically + deindenting it by default. + """ + from parser import suite as syntax_checker + + if deindent: + source = str(self.deindent()) + else: + source = str(self) + try: + # compile(source+'\n', "x", "exec") + syntax_checker(source + "\n") + except KeyboardInterrupt: + raise + except Exception: + return False + else: + return True + + def __str__(self): + return "\n".join(self.lines) + + def compile( + self, filename=None, mode="exec", flag=0, dont_inherit=0, _genframe=None + ): + """ return compiled code object. if filename is None + invent an artificial filename which displays + the source/line position of the caller frame. + """ + if not filename or py.path.local(filename).check(file=0): + if _genframe is None: + _genframe = sys._getframe(1) # the caller + fn, lineno = _genframe.f_code.co_filename, _genframe.f_lineno + base = "<%d-codegen " % self._compilecounter + self.__class__._compilecounter += 1 + if not filename: + filename = base + "%s:%d>" % (fn, lineno) + else: + filename = base + "%r %s:%d>" % (filename, fn, lineno) + source = "\n".join(self.lines) + "\n" + try: + co = cpy_compile(source, filename, mode, flag) + except SyntaxError: + ex = sys.exc_info()[1] + # re-represent syntax errors from parsing python strings + msglines = self.lines[: ex.lineno] + if ex.offset: + msglines.append(" " * ex.offset + "^") + msglines.append("(code was compiled probably from here: %s)" % filename) + newex = SyntaxError("\n".join(msglines)) + newex.offset = ex.offset + newex.lineno = ex.lineno + newex.text = ex.text + raise newex + else: + if flag & _AST_FLAG: + return co + lines = [(x + "\n") for x in self.lines] + linecache.cache[filename] = (1, None, lines, filename) + return co + + +# +# public API shortcut functions +# + + +def compile_(source, filename=None, mode="exec", flags=0, dont_inherit=0): + """ compile the given source to a raw code object, + and maintain an internal cache which allows later + retrieval of the source code for the code object + and any recursively created code objects. + """ + if isinstance(source, ast.AST): + # XXX should Source support having AST? + return cpy_compile(source, filename, mode, flags, dont_inherit) + _genframe = sys._getframe(1) # the caller + s = Source(source) + co = s.compile(filename, mode, flags, _genframe=_genframe) + return co + + +def getfslineno(obj): + """ Return source location (path, lineno) for the given object. + If the source cannot be determined return ("", -1) + """ + from .code import Code + + try: + code = Code(obj) + except TypeError: + try: + fn = inspect.getsourcefile(obj) or inspect.getfile(obj) + except TypeError: + return "", -1 + + fspath = fn and py.path.local(fn) or None + lineno = -1 + if fspath: + try: + _, lineno = findsource(obj) + except IOError: + pass + else: + fspath = code.path + lineno = code.firstlineno + assert isinstance(lineno, int) + return fspath, lineno + + +# +# helper functions +# + + +def findsource(obj): + try: + sourcelines, lineno = inspect.findsource(obj) + except py.builtin._sysex: + raise + except: # noqa + return None, -1 + source = Source() + source.lines = [line.rstrip() for line in sourcelines] + return source, lineno + + +def getsource(obj, **kwargs): + from .code import getrawcode + + obj = getrawcode(obj) + try: + strsrc = inspect.getsource(obj) + except IndentationError: + strsrc = '"Buggy python version consider upgrading, cannot get source"' + assert isinstance(strsrc, str) + return Source(strsrc, **kwargs) + + +def deindent(lines, offset=None): + if offset is None: + for line in lines: + line = line.expandtabs() + s = line.lstrip() + if s: + offset = len(line) - len(s) + break + else: + offset = 0 + if offset == 0: + return list(lines) + newlines = [] + + def readline_generator(lines): + for line in lines: + yield line + "\n" + + it = readline_generator(lines) + + try: + for _, _, (sline, _), (eline, _), _ in tokenize.generate_tokens( + lambda: next(it) + ): + if sline > len(lines): + break # End of input reached + if sline > len(newlines): + line = lines[sline - 1].expandtabs() + if line.lstrip() and line[:offset].isspace(): + line = line[offset:] # Deindent + newlines.append(line) + + for i in range(sline, eline): + # Don't deindent continuing lines of + # multiline tokens (i.e. multiline strings) + newlines.append(lines[i]) + except (IndentationError, tokenize.TokenError): + pass + # Add any lines we didn't see. E.g. if an exception was raised. + newlines.extend(lines[len(newlines) :]) + return newlines + + +def get_statement_startend2(lineno, node): + import ast + + # flatten all statements and except handlers into one lineno-list + # AST's line numbers start indexing at 1 + values = [] + for x in ast.walk(node): + if isinstance(x, (ast.stmt, ast.ExceptHandler)): + values.append(x.lineno - 1) + for name in ("finalbody", "orelse"): + val = getattr(x, name, None) + if val: + # treat the finally/orelse part as its own statement + values.append(val[0].lineno - 1 - 1) + values.sort() + insert_index = bisect_right(values, lineno) + start = values[insert_index - 1] + if insert_index >= len(values): + end = None + else: + end = values[insert_index] + return start, end + + +def getstatementrange_ast(lineno, source, assertion=False, astnode=None): + if astnode is None: + content = str(source) + astnode = compile(content, "source", "exec", 1024) # 1024 for AST + + start, end = get_statement_startend2(lineno, astnode) + # we need to correct the end: + # - ast-parsing strips comments + # - there might be empty lines + # - we might have lesser indented code blocks at the end + if end is None: + end = len(source.lines) + + if end > start + 1: + # make sure we don't span differently indented code blocks + # by using the BlockFinder helper used which inspect.getsource() uses itself + block_finder = inspect.BlockFinder() + # if we start with an indented line, put blockfinder to "started" mode + block_finder.started = source.lines[start][0].isspace() + it = ((x + "\n") for x in source.lines[start:end]) + try: + for tok in tokenize.generate_tokens(lambda: next(it)): + block_finder.tokeneater(*tok) + except (inspect.EndOfBlock, IndentationError): + end = block_finder.last + start + except Exception: + pass + + # the end might still point to a comment or empty line, correct it + while end: + line = source.lines[end - 1].lstrip() + if line.startswith("#") or not line: + end -= 1 + else: + break + return astnode, start, end diff --git a/Lib/site-packages/_pytest/_version.py b/Lib/site-packages/_pytest/_version.py new file mode 100644 index 0000000..dd1b313 --- /dev/null +++ b/Lib/site-packages/_pytest/_version.py @@ -0,0 +1,4 @@ +# coding: utf-8 +# file generated by setuptools_scm +# don't change, don't track in version control +version = '3.7.1' diff --git a/Lib/site-packages/_pytest/assertion/__init__.py b/Lib/site-packages/_pytest/assertion/__init__.py new file mode 100644 index 0000000..2c9a889 --- /dev/null +++ b/Lib/site-packages/_pytest/assertion/__init__.py @@ -0,0 +1,151 @@ +""" +support for presenting detailed information in failing assertions. +""" +from __future__ import absolute_import, division, print_function +import sys +import six + +from _pytest.assertion import util +from _pytest.assertion import rewrite +from _pytest.assertion import truncate + + +def pytest_addoption(parser): + group = parser.getgroup("debugconfig") + group.addoption( + "--assert", + action="store", + dest="assertmode", + choices=("rewrite", "plain"), + default="rewrite", + metavar="MODE", + help="""Control assertion debugging tools. 'plain' + performs no assertion debugging. 'rewrite' + (the default) rewrites assert statements in + test modules on import to provide assert + expression information.""", + ) + + +def register_assert_rewrite(*names): + """Register one or more module names to be rewritten on import. + + This function will make sure that this module or all modules inside + the package will get their assert statements rewritten. + Thus you should make sure to call this before the module is + actually imported, usually in your __init__.py if you are a plugin + using a package. + + :raise TypeError: if the given module names are not strings. + """ + for name in names: + if not isinstance(name, str): + msg = "expected module names as *args, got {0} instead" + raise TypeError(msg.format(repr(names))) + for hook in sys.meta_path: + if isinstance(hook, rewrite.AssertionRewritingHook): + importhook = hook + break + else: + importhook = DummyRewriteHook() + importhook.mark_rewrite(*names) + + +class DummyRewriteHook(object): + """A no-op import hook for when rewriting is disabled.""" + + def mark_rewrite(self, *names): + pass + + +class AssertionState(object): + """State for the assertion plugin.""" + + def __init__(self, config, mode): + self.mode = mode + self.trace = config.trace.root.get("assertion") + self.hook = None + + +def install_importhook(config): + """Try to install the rewrite hook, raise SystemError if it fails.""" + # Jython has an AST bug that make the assertion rewriting hook malfunction. + if sys.platform.startswith("java"): + raise SystemError("rewrite not supported") + + config._assertstate = AssertionState(config, "rewrite") + config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config) + sys.meta_path.insert(0, hook) + config._assertstate.trace("installed rewrite import hook") + + def undo(): + hook = config._assertstate.hook + if hook is not None and hook in sys.meta_path: + sys.meta_path.remove(hook) + + config.add_cleanup(undo) + return hook + + +def pytest_collection(session): + # this hook is only called when test modules are collected + # so for example not in the master process of pytest-xdist + # (which does not collect test modules) + assertstate = getattr(session.config, "_assertstate", None) + if assertstate: + if assertstate.hook is not None: + assertstate.hook.set_session(session) + + +def pytest_runtest_setup(item): + """Setup the pytest_assertrepr_compare hook + + The newinterpret and rewrite modules will use util._reprcompare if + it exists to use custom reporting via the + pytest_assertrepr_compare hook. This sets up this custom + comparison for the test. + """ + + def callbinrepr(op, left, right): + """Call the pytest_assertrepr_compare hook and prepare the result + + This uses the first result from the hook and then ensures the + following: + * Overly verbose explanations are truncated unless configured otherwise + (eg. if running in verbose mode). + * Embedded newlines are escaped to help util.format_explanation() + later. + * If the rewrite mode is used embedded %-characters are replaced + to protect later % formatting. + + The result can be formatted by util.format_explanation() for + pretty printing. + """ + hook_result = item.ihook.pytest_assertrepr_compare( + config=item.config, op=op, left=left, right=right + ) + for new_expl in hook_result: + if new_expl: + new_expl = truncate.truncate_if_required(new_expl, item) + new_expl = [line.replace("\n", "\\n") for line in new_expl] + res = six.text_type("\n~").join(new_expl) + if item.config.getvalue("assertmode") == "rewrite": + res = res.replace("%", "%%") + return res + + util._reprcompare = callbinrepr + + +def pytest_runtest_teardown(item): + util._reprcompare = None + + +def pytest_sessionfinish(session): + assertstate = getattr(session.config, "_assertstate", None) + if assertstate: + if assertstate.hook is not None: + assertstate.hook.set_session(None) + + +# Expose this plugin's implementation for the pytest_assertrepr_compare hook +pytest_assertrepr_compare = util.assertrepr_compare diff --git a/Lib/site-packages/_pytest/assertion/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/_pytest/assertion/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa8774ab979178df94336700a61186abd54ce1c8 GIT binary patch literal 5530 zcmbVQTaVku73NJ6rIpufdu=C3(hx{|k!vey8n}(?ICgC}3D9m*+pSS{1A?m=X{n`1 z?#yT}sT2YqA#Z?T;@-`!ycKqaoyGkOJI7XWKg-Uu3%H+S7uhSguX2BQKD@x($5!Xn$%B?07ey{q(9cCs z2rhZ1l57w#uHq!+EJ!lE8O18eGxUQ#M(KSlB^NX(yRCoXB|D-y-g^_9ScSn-}sB=K`_HF4d?B`>3y zT1SxPv3+1q?I9%1T;{PFtCO@?^XmrWX5nP5H3*Jxj0e3u>nDSWf8&PXxU5N)3tqO& z<0xmm{B*+n|adXvTRhGmyHn&Y$q0_ zx5?9@v zAN*+jUQs-VRlNT5ycehIPxz=rs?s ziHf3bv0tv3x6z!DQ)GT;(O7oN_H5_mUlZps+M`$WtKlMJ`WTmFX!fp8tq0Z@Zy(so zn%c@fbR@k0z){ZBIdYXZwGLs;hxV8DcKxZfcUjejb*-T_G^U+{8Nz-5yZ}C8mK}l`K3Jqo$tD!9*+PMuu)UX;&hfK7Hdt32< z8!FH(mhuEEG;S=~sWD-&)2(huw`a zYrisR&aMYzS&d{wSOg2I4wAm!EC#JODAFjery%|~T#vLzvDk_#OzG6hnm$SC(XDhxasY3|%CKd?g8JGYO@qj2l@~>2g^|(p zjN13eA!vrR)Y3k5!EWR4*>$IGi?=a8_aT}@xPKRyd<6}+LYrBk!|c!{#77kKm5LoM~ikICOl{0NrIDjk1RJ5sdWM7OM(|N}#U1XBKl0oo7~5Q}v_9 zGway)tY_A+7WotshRvfE^QQK(W9!kQC00AOZR-zK-=?JIEB^p%kJ?j*MyEE6-k*H* zMC=omSHVpKQ024%+5Yvwz|`Y?K*&e~72#BZBoEn}?3UgTp?7kAwnn3rNdr04m?6j` zCT~<50IX(Ht1N+b>0yfg(OeP&iBFP+^R#RM_TFM!^TXk`n?nj7ubePJ| zU<&ODD*$l_UvGhec#WFZ(Uf(;NBIu2Lt`1Xc!yriy#Z-t#`0fctg->$K5I{AqNx&5 zVz+xcrPM&)>C%GEDZNGMBXd&(p=ArZ3nh0GwOKALNKVj+#Cz0`k%>2`(L5UVAR{Eg z;yQ-IB_s?{FXeGIE?~o&Q$6*4T0}hK7JtHK$|07fY4D`Scfhp$KooS(a{Rfy(4!)?9Q4#QO7GA@VQtial&l5 zB)N*DN$UWBjjCHN8TU0>dfr#cGgZda%hMF$4UiEMV?G+oTL#R7|2ybE$G?jKy5t2k z+TxMW!{WicBJiLR#hd)=F<0Y48~H3P(=b8-FY4tZB#2y_{Vaz;*yX#ZHn>1?s)9H> zF<*nZ(j+BgL~^P@x`@LG^*n{sSyuZz%xom^?WToqSA-i<uIJWWhK?5d@X!S`oxqkYg*ci(GF`F9@#kL6>k8%QBr#WOLdS z%Q{A1#Ll(g;b?<120}1J)XQL(cI2`b7Z?O~Q`KXv&m?fs0()0G3%dfJxL73psmVBJ zh)i2kW&;_rfX}wQbfdQ!BeY_z*%~TH5oy^1WmD>**j9nwB)CN8hf<%+yGnTJG*9Mg zL;jsn1yN1Ih8z3eeF&O1-;P{S?W4AYV`}n5nSLElLr>}CMd_uyugaQ82Ak?Rq#(P0 zj7z7310dZOD})mG6hI#XoWD5Rlny$j-I_S-nfa)o&x?Gz49 z&UfcaqD_!mwdn!^WKoG_ABrB7h7DUMHLLcU+EvbFs6#1I8NtJ!`{P|Tkj z3FRQ9KOGKR=r9CC%0FQi_KX4XIbI+F>up{LU>9H55VeqzvW-?J>UN~7EaQ^ literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/assertion/__pycache__/rewrite.cpython-37.pyc b/Lib/site-packages/_pytest/assertion/__pycache__/rewrite.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b558d1ff1b8b1fd74d055e32b1fbed7ba00804a3 GIT binary patch literal 27324 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 bhxTFn^S|i7e1Z%Fn}=a9B5b~%%ntn@!|Mh{ literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/assertion/__pycache__/truncate.cpython-37.pyc b/Lib/site-packages/_pytest/assertion/__pycache__/truncate.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14c989b47ab889c48fc7e05fa7b6ca5e4708f70d GIT binary patch literal 2709 zcmZuzU2o&Y6`dg|ilS|;>}(Qmnl_W9jYA+SY=a`%77L?Z+esJL6_R+Jw2T%6trciF(%ehgvb@L$yz@oQ$GP{MtNSY}K7q1( zYQD8s2>Bm&E{hF~zrv$A7*0aMDYp_jvO;TQhxW(`9g1UiQVVNU?S?LQ!aA>o9(ThA zU*&b~y`Z7b8{B_E!X>`Mm!V$fYkY+_VP=Kj;4K(wa(j;iuTB2r?;Dv&BZX%DOfjSK zv=P&?Oojf4WOL8M3IT~lmlpdEyQo}}NbF5@)qCVUOH}0H!@QM7vB4o0fYr!^P{S7>@ z9%j#bh&vXn;T5tCkG=`Ukb<64)iSgor*w}L1TdqMFMS5(@eC=!%n&Yr1=hlane4-? zU;}w1QnW0>0t*8UJ`?-3Lv~35_n)uA&|JuofmM~9S9^0rJy#svpp2OLyVE4|k%@{-gW5UtNP0ch>l(e{S3xh!o;XZGM33B9IQ5yn7w5_Pqo{ zNpH62ZwIurjFGc(0^LD$kZ`T;S|=XHHDhn zw+MIMB-pw~W?zGKPU$+C)`}XheF`;qr!KY+E%jsJ^7>M%BJ6d!^>=i^FF z=3Hb88UX6Ns7jR_3t92z?xoNIfj;@u9o8GhD(-;_Yj&GGAIjcP02ivIWeP&il!#$W zR}1!~(x%NGgN!LLie)9ym2k7?GD#o>z&J>JPjGf{!eW-|cp%sa6dmdr1v@1<|38$8 z-EOzfktLILXnmH$_p{tG&m4TR%0B#VTAi2;CFddyCTsH{Js)#EV&6>zzg*qf{cLOh z;p6Dh*59Lt4?4Sh*N3+Mw)NFsX@e}5&eKe$<(pTEdTy>g7^}R8#>`HY(x8WHxK!qB?BNUb)&KeEm`` zd9>iUaIT`fTJPdG_DBz2Wew6IfJY-AiRV!V1lF;e^d@zjW$N24yM-h0w5%p=(zmF> zZ+b{wEU0YAxQbW*f(9rPJ%jXy{Hb{J1|~UfO|9dPXMETpPd?~cQychVK|%y>0AJ{# zqc*=Fmm|Oh>)G$WL7tJqu6R}}papz$3s+4F;4Cnz4*VcRy_yF`0dIj3z=j&I!R{#3 zErrn$IO@09{vDXIA<}##RBS})#^W)#Bkoa76x44d;onR0O)`d8ix zTUSm{Lc_n9(C_2FkqZ0p)>Zo|PR0;7=2c(31G|3#kA52rvDUy34qc-yYSEUxeBlM~ z303%JKtXpqo!~}Uk0PG+qNwyE_=93{C89{7f0T^|y`wONs`t@gwo$l)dKV4m(kkav ua#{JdT7KbhRm#F_ReJZ}A5@-*O;l3-1{end#j`v(DEw@{;d!3xZ~Owm)!CZ> literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/assertion/__pycache__/util.cpython-37.pyc b/Lib/site-packages/_pytest/assertion/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..297018c06b11332a394ce950f8815bba80e0adeb GIT binary patch literal 10008 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 (3, 5): + ast_Call = ast.Call +else: + + def ast_Call(a, b, c): + return ast.Call(a, b, c, None, None) + + +if sys.version_info >= (3, 4): + from importlib.util import spec_from_file_location +else: + + def spec_from_file_location(*_, **__): + return None + + +class AssertionRewritingHook(object): + """PEP302 Import hook which rewrites asserts.""" + + def __init__(self, config): + self.config = config + self.fnpats = config.getini("python_files") + self.session = None + self.modules = {} + self._rewritten_names = set() + self._register_with_pkg_resources() + self._must_rewrite = set() + + def set_session(self, session): + self.session = session + + def find_module(self, name, path=None): + state = self.config._assertstate + state.trace("find_module called for: %s" % name) + names = name.rsplit(".", 1) + lastname = names[-1] + pth = None + if path is not None: + # Starting with Python 3.3, path is a _NamespacePath(), which + # causes problems if not converted to list. + path = list(path) + if len(path) == 1: + pth = path[0] + if pth is None: + try: + fd, fn, desc = imp.find_module(lastname, path) + except ImportError: + return None + if fd is not None: + fd.close() + tp = desc[2] + if tp == imp.PY_COMPILED: + if hasattr(imp, "source_from_cache"): + try: + fn = imp.source_from_cache(fn) + except ValueError: + # Python 3 doesn't like orphaned but still-importable + # .pyc files. + fn = fn[:-1] + else: + fn = fn[:-1] + elif tp != imp.PY_SOURCE: + # Don't know what this is. + return None + else: + fn = os.path.join(pth, name.rpartition(".")[2] + ".py") + + fn_pypath = py.path.local(fn) + if not self._should_rewrite(name, fn_pypath, state): + return None + + self._rewritten_names.add(name) + + # The requested module looks like a test file, so rewrite it. This is + # the most magical part of the process: load the source, rewrite the + # asserts, and load the rewritten source. We also cache the rewritten + # module code in a special pyc. We must be aware of the possibility of + # concurrent pytest processes rewriting and loading pycs. To avoid + # tricky race conditions, we maintain the following invariant: The + # cached pyc is always a complete, valid pyc. Operations on it must be + # atomic. POSIX's atomic rename comes in handy. + write = not sys.dont_write_bytecode + cache_dir = os.path.join(fn_pypath.dirname, "__pycache__") + if write: + try: + os.mkdir(cache_dir) + except OSError: + e = sys.exc_info()[1].errno + if e == errno.EEXIST: + # Either the __pycache__ directory already exists (the + # common case) or it's blocked by a non-dir node. In the + # latter case, we'll ignore it in _write_pyc. + pass + elif e in [errno.ENOENT, errno.ENOTDIR]: + # One of the path components was not a directory, likely + # because we're in a zip file. + write = False + elif e in [errno.EACCES, errno.EROFS, errno.EPERM]: + state.trace("read only directory: %r" % fn_pypath.dirname) + write = False + else: + raise + cache_name = fn_pypath.basename[:-3] + PYC_TAIL + pyc = os.path.join(cache_dir, cache_name) + # Notice that even if we're in a read-only directory, I'm going + # to check for a cached pyc. This may not be optimal... + co = _read_pyc(fn_pypath, pyc, state.trace) + if co is None: + state.trace("rewriting %r" % (fn,)) + source_stat, co = _rewrite_test(self.config, fn_pypath) + if co is None: + # Probably a SyntaxError in the test. + return None + if write: + _write_pyc(state, co, source_stat, pyc) + else: + state.trace("found cached rewritten pyc for %r" % (fn,)) + self.modules[name] = co, pyc + return self + + def _should_rewrite(self, name, fn_pypath, state): + # always rewrite conftest files + fn = str(fn_pypath) + if fn_pypath.basename == "conftest.py": + state.trace("rewriting conftest file: %r" % (fn,)) + return True + + if self.session is not None: + if self.session.isinitpath(fn): + state.trace("matched test file (was specified on cmdline): %r" % (fn,)) + return True + + # modules not passed explicitly on the command line are only + # rewritten if they match the naming convention for test files + for pat in self.fnpats: + if fn_pypath.fnmatch(pat): + state.trace("matched test file %r" % (fn,)) + return True + + for marked in self._must_rewrite: + if name == marked or name.startswith(marked + "."): + state.trace("matched marked file %r (from %r)" % (name, marked)) + return True + + return False + + def mark_rewrite(self, *names): + """Mark import names as needing to be rewritten. + + The named module or package as well as any nested modules will + be rewritten on import. + """ + already_imported = ( + set(names).intersection(sys.modules).difference(self._rewritten_names) + ) + for name in already_imported: + if not AssertionRewriter.is_rewrite_disabled( + sys.modules[name].__doc__ or "" + ): + self._warn_already_imported(name) + self._must_rewrite.update(names) + + def _warn_already_imported(self, name): + self.config.warn( + "P1", "Module already imported so cannot be rewritten: %s" % name + ) + + def load_module(self, name): + # If there is an existing module object named 'fullname' in + # sys.modules, the loader must use that existing module. (Otherwise, + # the reload() builtin will not work correctly.) + if name in sys.modules: + return sys.modules[name] + + co, pyc = self.modules.pop(name) + # I wish I could just call imp.load_compiled here, but __file__ has to + # be set properly. In Python 3.2+, this all would be handled correctly + # by load_compiled. + mod = sys.modules[name] = imp.new_module(name) + try: + mod.__file__ = co.co_filename + # Normally, this attribute is 3.2+. + mod.__cached__ = pyc + mod.__loader__ = self + # Normally, this attribute is 3.4+ + mod.__spec__ = spec_from_file_location(name, co.co_filename, loader=self) + py.builtin.exec_(co, mod.__dict__) + except: # noqa + if name in sys.modules: + del sys.modules[name] + raise + return sys.modules[name] + + def is_package(self, name): + try: + fd, fn, desc = imp.find_module(name) + except ImportError: + return False + if fd is not None: + fd.close() + tp = desc[2] + return tp == imp.PKG_DIRECTORY + + @classmethod + def _register_with_pkg_resources(cls): + """ + Ensure package resources can be loaded from this loader. May be called + multiple times, as the operation is idempotent. + """ + try: + import pkg_resources + + # access an attribute in case a deferred importer is present + pkg_resources.__name__ + except ImportError: + return + + # Since pytest tests are always located in the file system, the + # DefaultProvider is appropriate. + pkg_resources.register_loader_type(cls, pkg_resources.DefaultProvider) + + def get_data(self, pathname): + """Optional PEP302 get_data API. + """ + with open(pathname, "rb") as f: + return f.read() + + +def _write_pyc(state, co, source_stat, pyc): + # Technically, we don't have to have the same pyc format as + # (C)Python, since these "pycs" should never be seen by builtin + # import. However, there's little reason deviate, and I hope + # sometime to be able to use imp.load_compiled to load them. (See + # the comment in load_module above.) + try: + with atomicwrites.atomic_write(pyc, mode="wb", overwrite=True) as fp: + fp.write(imp.get_magic()) + mtime = int(source_stat.mtime) + size = source_stat.size & 0xFFFFFFFF + fp.write(struct.pack(">", + ast.Add: "+", + ast.Sub: "-", + ast.Mult: "*", + ast.Div: "/", + ast.FloorDiv: "//", + ast.Mod: "%%", # escaped for string formatting + ast.Eq: "==", + ast.NotEq: "!=", + ast.Lt: "<", + ast.LtE: "<=", + ast.Gt: ">", + ast.GtE: ">=", + ast.Pow: "**", + ast.Is: "is", + ast.IsNot: "is not", + ast.In: "in", + ast.NotIn: "not in", +} +# Python 3.5+ compatibility +try: + binop_map[ast.MatMult] = "@" +except AttributeError: + pass + +# Python 3.4+ compatibility +if hasattr(ast, "NameConstant"): + _NameConstant = ast.NameConstant +else: + + def _NameConstant(c): + return ast.Name(str(c), ast.Load()) + + +def set_location(node, lineno, col_offset): + """Set node location information recursively.""" + + def _fix(node, lineno, col_offset): + if "lineno" in node._attributes: + node.lineno = lineno + if "col_offset" in node._attributes: + node.col_offset = col_offset + for child in ast.iter_child_nodes(node): + _fix(child, lineno, col_offset) + + _fix(node, lineno, col_offset) + return node + + +class AssertionRewriter(ast.NodeVisitor): + """Assertion rewriting implementation. + + The main entrypoint is to call .run() with an ast.Module instance, + this will then find all the assert statements and rewrite them to + provide intermediate values and a detailed assertion error. See + http://pybites.blogspot.be/2011/07/behind-scenes-of-pytests-new-assertion.html + for an overview of how this works. + + The entry point here is .run() which will iterate over all the + statements in an ast.Module and for each ast.Assert statement it + finds call .visit() with it. Then .visit_Assert() takes over and + is responsible for creating new ast statements to replace the + original assert statement: it rewrites the test of an assertion + to provide intermediate values and replace it with an if statement + which raises an assertion error with a detailed explanation in + case the expression is false. + + For this .visit_Assert() uses the visitor pattern to visit all the + AST nodes of the ast.Assert.test field, each visit call returning + an AST node and the corresponding explanation string. During this + state is kept in several instance attributes: + + :statements: All the AST statements which will replace the assert + statement. + + :variables: This is populated by .variable() with each variable + used by the statements so that they can all be set to None at + the end of the statements. + + :variable_counter: Counter to create new unique variables needed + by statements. Variables are created using .variable() and + have the form of "@py_assert0". + + :on_failure: The AST statements which will be executed if the + assertion test fails. This is the code which will construct + the failure message and raises the AssertionError. + + :explanation_specifiers: A dict filled by .explanation_param() + with %-formatting placeholders and their corresponding + expressions to use in the building of an assertion message. + This is used by .pop_format_context() to build a message. + + :stack: A stack of the explanation_specifiers dicts maintained by + .push_format_context() and .pop_format_context() which allows + to build another %-formatted string while already building one. + + This state is reset on every new assert statement visited and used + by the other visitors. + + """ + + def __init__(self, module_path, config): + super(AssertionRewriter, self).__init__() + self.module_path = module_path + self.config = config + + def run(self, mod): + """Find all assert statements in *mod* and rewrite them.""" + if not mod.body: + # Nothing to do. + return + # Insert some special imports at the top of the module but after any + # docstrings and __future__ imports. + aliases = [ + ast.alias(py.builtin.builtins.__name__, "@py_builtins"), + ast.alias("_pytest.assertion.rewrite", "@pytest_ar"), + ] + doc = getattr(mod, "docstring", None) + expect_docstring = doc is None + if doc is not None and self.is_rewrite_disabled(doc): + return + pos = 0 + lineno = 1 + for item in mod.body: + if ( + expect_docstring + and isinstance(item, ast.Expr) + and isinstance(item.value, ast.Str) + ): + doc = item.value.s + if self.is_rewrite_disabled(doc): + return + expect_docstring = False + elif ( + not isinstance(item, ast.ImportFrom) + or item.level > 0 + or item.module != "__future__" + ): + lineno = item.lineno + break + pos += 1 + else: + lineno = item.lineno + imports = [ + ast.Import([alias], lineno=lineno, col_offset=0) for alias in aliases + ] + mod.body[pos:pos] = imports + # Collect asserts. + nodes = [mod] + while nodes: + node = nodes.pop() + for name, field in ast.iter_fields(node): + if isinstance(field, list): + new = [] + for i, child in enumerate(field): + if isinstance(child, ast.Assert): + # Transform assert. + new.extend(self.visit(child)) + else: + new.append(child) + if isinstance(child, ast.AST): + nodes.append(child) + setattr(node, name, new) + elif ( + isinstance(field, ast.AST) + and + # Don't recurse into expressions as they can't contain + # asserts. + not isinstance(field, ast.expr) + ): + nodes.append(field) + + @staticmethod + def is_rewrite_disabled(docstring): + return "PYTEST_DONT_REWRITE" in docstring + + def variable(self): + """Get a new variable.""" + # Use a character invalid in python identifiers to avoid clashing. + name = "@py_assert" + str(next(self.variable_counter)) + self.variables.append(name) + return name + + def assign(self, expr): + """Give *expr* a name.""" + name = self.variable() + self.statements.append(ast.Assign([ast.Name(name, ast.Store())], expr)) + return ast.Name(name, ast.Load()) + + def display(self, expr): + """Call py.io.saferepr on the expression.""" + return self.helper("saferepr", expr) + + def helper(self, name, *args): + """Call a helper in this module.""" + py_name = ast.Name("@pytest_ar", ast.Load()) + attr = ast.Attribute(py_name, "_" + name, ast.Load()) + return ast_Call(attr, list(args), []) + + def builtin(self, name): + """Return the builtin called *name*.""" + builtin_name = ast.Name("@py_builtins", ast.Load()) + return ast.Attribute(builtin_name, name, ast.Load()) + + def explanation_param(self, expr): + """Return a new named %-formatting placeholder for expr. + + This creates a %-formatting placeholder for expr in the + current formatting context, e.g. ``%(py0)s``. The placeholder + and expr are placed in the current format context so that it + can be used on the next call to .pop_format_context(). + + """ + specifier = "py" + str(next(self.variable_counter)) + self.explanation_specifiers[specifier] = expr + return "%(" + specifier + ")s" + + def push_format_context(self): + """Create a new formatting context. + + The format context is used for when an explanation wants to + have a variable value formatted in the assertion message. In + this case the value required can be added using + .explanation_param(). Finally .pop_format_context() is used + to format a string of %-formatted values as added by + .explanation_param(). + + """ + self.explanation_specifiers = {} + self.stack.append(self.explanation_specifiers) + + def pop_format_context(self, expl_expr): + """Format the %-formatted string with current format context. + + The expl_expr should be an ast.Str instance constructed from + the %-placeholders created by .explanation_param(). This will + add the required code to format said string to .on_failure and + return the ast.Name instance of the formatted string. + + """ + current = self.stack.pop() + if self.stack: + self.explanation_specifiers = self.stack[-1] + keys = [ast.Str(key) for key in current.keys()] + format_dict = ast.Dict(keys, list(current.values())) + form = ast.BinOp(expl_expr, ast.Mod(), format_dict) + name = "@py_format" + str(next(self.variable_counter)) + self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form)) + return ast.Name(name, ast.Load()) + + def generic_visit(self, node): + """Handle expressions we don't have custom code for.""" + assert isinstance(node, ast.expr) + res = self.assign(node) + return res, self.explanation_param(self.display(res)) + + def visit_Assert(self, assert_): + """Return the AST statements to replace the ast.Assert instance. + + This rewrites the test of an assertion to provide + intermediate values and replace it with an if statement which + raises an assertion error with a detailed explanation in case + the expression is false. + + """ + if isinstance(assert_.test, ast.Tuple) and self.config is not None: + fslocation = (self.module_path, assert_.lineno) + self.config.warn( + "R1", + "assertion is always true, perhaps " "remove parentheses?", + fslocation=fslocation, + ) + self.statements = [] + self.variables = [] + self.variable_counter = itertools.count() + self.stack = [] + self.on_failure = [] + self.push_format_context() + # Rewrite assert into a bunch of statements. + top_condition, explanation = self.visit(assert_.test) + # Create failure message. + body = self.on_failure + negation = ast.UnaryOp(ast.Not(), top_condition) + self.statements.append(ast.If(negation, body, [])) + if assert_.msg: + assertmsg = self.helper("format_assertmsg", assert_.msg) + explanation = "\n>assert " + explanation + else: + assertmsg = ast.Str("") + explanation = "assert " + explanation + template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation)) + msg = self.pop_format_context(template) + fmt = self.helper("format_explanation", msg) + err_name = ast.Name("AssertionError", ast.Load()) + exc = ast_Call(err_name, [fmt], []) + if sys.version_info[0] >= 3: + raise_ = ast.Raise(exc, None) + else: + raise_ = ast.Raise(exc, None, None) + body.append(raise_) + # Clear temporary variables by setting them to None. + if self.variables: + variables = [ast.Name(name, ast.Store()) for name in self.variables] + clear = ast.Assign(variables, _NameConstant(None)) + self.statements.append(clear) + # Fix line numbers. + for stmt in self.statements: + set_location(stmt, assert_.lineno, assert_.col_offset) + return self.statements + + def visit_Name(self, name): + # Display the repr of the name if it's a local variable or + # _should_repr_global_name() thinks it's acceptable. + locs = ast_Call(self.builtin("locals"), [], []) + inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs]) + dorepr = self.helper("should_repr_global_name", name) + test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) + expr = ast.IfExp(test, self.display(name), ast.Str(name.id)) + return name, self.explanation_param(expr) + + def visit_BoolOp(self, boolop): + res_var = self.variable() + expl_list = self.assign(ast.List([], ast.Load())) + app = ast.Attribute(expl_list, "append", ast.Load()) + is_or = int(isinstance(boolop.op, ast.Or)) + body = save = self.statements + fail_save = self.on_failure + levels = len(boolop.values) - 1 + self.push_format_context() + # Process each operand, short-circuting if needed. + for i, v in enumerate(boolop.values): + if i: + fail_inner = [] + # cond is set in a prior loop iteration below + self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa + self.on_failure = fail_inner + self.push_format_context() + res, expl = self.visit(v) + body.append(ast.Assign([ast.Name(res_var, ast.Store())], res)) + expl_format = self.pop_format_context(ast.Str(expl)) + call = ast_Call(app, [expl_format], []) + self.on_failure.append(ast.Expr(call)) + if i < levels: + cond = res + if is_or: + cond = ast.UnaryOp(ast.Not(), cond) + inner = [] + self.statements.append(ast.If(cond, inner, [])) + self.statements = body = inner + self.statements = save + self.on_failure = fail_save + expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or)) + expl = self.pop_format_context(expl_template) + return ast.Name(res_var, ast.Load()), self.explanation_param(expl) + + def visit_UnaryOp(self, unary): + pattern = unary_map[unary.op.__class__] + operand_res, operand_expl = self.visit(unary.operand) + res = self.assign(ast.UnaryOp(unary.op, operand_res)) + return res, pattern % (operand_expl,) + + def visit_BinOp(self, binop): + symbol = binop_map[binop.op.__class__] + left_expr, left_expl = self.visit(binop.left) + right_expr, right_expl = self.visit(binop.right) + explanation = "(%s %s %s)" % (left_expl, symbol, right_expl) + res = self.assign(ast.BinOp(left_expr, binop.op, right_expr)) + return res, explanation + + def visit_Call_35(self, call): + """ + visit `ast.Call` nodes on Python3.5 and after + """ + new_func, func_expl = self.visit(call.func) + arg_expls = [] + new_args = [] + new_kwargs = [] + for arg in call.args: + res, expl = self.visit(arg) + arg_expls.append(expl) + new_args.append(res) + for keyword in call.keywords: + res, expl = self.visit(keyword.value) + new_kwargs.append(ast.keyword(keyword.arg, res)) + if keyword.arg: + arg_expls.append(keyword.arg + "=" + expl) + else: # **args have `arg` keywords with an .arg of None + arg_expls.append("**" + expl) + + expl = "%s(%s)" % (func_expl, ", ".join(arg_expls)) + new_call = ast.Call(new_func, new_args, new_kwargs) + res = self.assign(new_call) + res_expl = self.explanation_param(self.display(res)) + outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl) + return res, outer_expl + + def visit_Starred(self, starred): + # From Python 3.5, a Starred node can appear in a function call + res, expl = self.visit(starred.value) + return starred, "*" + expl + + def visit_Call_legacy(self, call): + """ + visit `ast.Call nodes on 3.4 and below` + """ + new_func, func_expl = self.visit(call.func) + arg_expls = [] + new_args = [] + new_kwargs = [] + new_star = new_kwarg = None + for arg in call.args: + res, expl = self.visit(arg) + new_args.append(res) + arg_expls.append(expl) + for keyword in call.keywords: + res, expl = self.visit(keyword.value) + new_kwargs.append(ast.keyword(keyword.arg, res)) + arg_expls.append(keyword.arg + "=" + expl) + if call.starargs: + new_star, expl = self.visit(call.starargs) + arg_expls.append("*" + expl) + if call.kwargs: + new_kwarg, expl = self.visit(call.kwargs) + arg_expls.append("**" + expl) + expl = "%s(%s)" % (func_expl, ", ".join(arg_expls)) + new_call = ast.Call(new_func, new_args, new_kwargs, new_star, new_kwarg) + res = self.assign(new_call) + res_expl = self.explanation_param(self.display(res)) + outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl) + return res, outer_expl + + # ast.Call signature changed on 3.5, + # conditionally change which methods is named + # visit_Call depending on Python version + if sys.version_info >= (3, 5): + visit_Call = visit_Call_35 + else: + visit_Call = visit_Call_legacy + + def visit_Attribute(self, attr): + if not isinstance(attr.ctx, ast.Load): + return self.generic_visit(attr) + value, value_expl = self.visit(attr.value) + res = self.assign(ast.Attribute(value, attr.attr, ast.Load())) + res_expl = self.explanation_param(self.display(res)) + pat = "%s\n{%s = %s.%s\n}" + expl = pat % (res_expl, res_expl, value_expl, attr.attr) + return res, expl + + def visit_Compare(self, comp): + self.push_format_context() + left_res, left_expl = self.visit(comp.left) + if isinstance(comp.left, (ast.Compare, ast.BoolOp)): + left_expl = "({})".format(left_expl) + res_variables = [self.variable() for i in range(len(comp.ops))] + load_names = [ast.Name(v, ast.Load()) for v in res_variables] + store_names = [ast.Name(v, ast.Store()) for v in res_variables] + it = zip(range(len(comp.ops)), comp.ops, comp.comparators) + expls = [] + syms = [] + results = [left_res] + for i, op, next_operand in it: + next_res, next_expl = self.visit(next_operand) + if isinstance(next_operand, (ast.Compare, ast.BoolOp)): + next_expl = "({})".format(next_expl) + results.append(next_res) + sym = binop_map[op.__class__] + syms.append(ast.Str(sym)) + expl = "%s %s %s" % (left_expl, sym, next_expl) + expls.append(ast.Str(expl)) + res_expr = ast.Compare(left_res, [op], [next_res]) + self.statements.append(ast.Assign([store_names[i]], res_expr)) + left_res, left_expl = next_res, next_expl + # Use pytest.assertion.util._reprcompare if that's available. + expl_call = self.helper( + "call_reprcompare", + ast.Tuple(syms, ast.Load()), + ast.Tuple(load_names, ast.Load()), + ast.Tuple(expls, ast.Load()), + ast.Tuple(results, ast.Load()), + ) + if len(comp.ops) > 1: + res = ast.BoolOp(ast.And(), load_names) + else: + res = load_names[0] + return res, self.explanation_param(self.pop_format_context(expl_call)) diff --git a/Lib/site-packages/_pytest/assertion/truncate.py b/Lib/site-packages/_pytest/assertion/truncate.py new file mode 100644 index 0000000..79adeca --- /dev/null +++ b/Lib/site-packages/_pytest/assertion/truncate.py @@ -0,0 +1,99 @@ +""" +Utilities for truncating assertion output. + +Current default behaviour is to truncate assertion explanations at +~8 terminal lines, unless running in "-vv" mode or running on CI. +""" +from __future__ import absolute_import, division, print_function +import os + +import six + + +DEFAULT_MAX_LINES = 8 +DEFAULT_MAX_CHARS = 8 * 80 +USAGE_MSG = "use '-vv' to show" + + +def truncate_if_required(explanation, item, max_length=None): + """ + Truncate this assertion explanation if the given test item is eligible. + """ + if _should_truncate_item(item): + return _truncate_explanation(explanation) + return explanation + + +def _should_truncate_item(item): + """ + Whether or not this test item is eligible for truncation. + """ + verbose = item.config.option.verbose + return verbose < 2 and not _running_on_ci() + + +def _running_on_ci(): + """Check if we're currently running on a CI system.""" + env_vars = ["CI", "BUILD_NUMBER"] + return any(var in os.environ for var in env_vars) + + +def _truncate_explanation(input_lines, max_lines=None, max_chars=None): + """ + Truncate given list of strings that makes up the assertion explanation. + + Truncates to either 8 lines, or 640 characters - whichever the input reaches + first. The remaining lines will be replaced by a usage message. + """ + + if max_lines is None: + max_lines = DEFAULT_MAX_LINES + if max_chars is None: + max_chars = DEFAULT_MAX_CHARS + + # Check if truncation required + input_char_count = len("".join(input_lines)) + if len(input_lines) <= max_lines and input_char_count <= max_chars: + return input_lines + + # Truncate first to max_lines, and then truncate to max_chars if max_chars + # is exceeded. + truncated_explanation = input_lines[:max_lines] + truncated_explanation = _truncate_by_char_count(truncated_explanation, max_chars) + + # Add ellipsis to final line + truncated_explanation[-1] = truncated_explanation[-1] + "..." + + # Append useful message to explanation + truncated_line_count = len(input_lines) - len(truncated_explanation) + truncated_line_count += 1 # Account for the part-truncated final line + msg = "...Full output truncated" + if truncated_line_count == 1: + msg += " ({} line hidden)".format(truncated_line_count) + else: + msg += " ({} lines hidden)".format(truncated_line_count) + msg += ", {}".format(USAGE_MSG) + truncated_explanation.extend([six.text_type(""), six.text_type(msg)]) + return truncated_explanation + + +def _truncate_by_char_count(input_lines, max_chars): + # Check if truncation required + if len("".join(input_lines)) <= max_chars: + return input_lines + + # Find point at which input length exceeds total allowed length + iterated_char_count = 0 + for iterated_index, input_line in enumerate(input_lines): + if iterated_char_count + len(input_line) > max_chars: + break + iterated_char_count += len(input_line) + + # Create truncated explanation with modified final line + truncated_result = input_lines[:iterated_index] + final_line = input_lines[iterated_index] + if final_line: + final_line_truncate_point = max_chars - iterated_char_count + final_line = final_line[:final_line_truncate_point] + truncated_result.append(final_line) + return truncated_result diff --git a/Lib/site-packages/_pytest/assertion/util.py b/Lib/site-packages/_pytest/assertion/util.py new file mode 100644 index 0000000..08213c8 --- /dev/null +++ b/Lib/site-packages/_pytest/assertion/util.py @@ -0,0 +1,338 @@ +"""Utilities for assertion debugging""" +from __future__ import absolute_import, division, print_function +import pprint + +import _pytest._code +import py +import six +from ..compat import Sequence + +u = six.text_type + +# The _reprcompare attribute on the util module is used by the new assertion +# interpretation code and assertion rewriter to detect this plugin was +# loaded and in turn call the hooks defined here as part of the +# DebugInterpreter. +_reprcompare = None + + +# the re-encoding is needed for python2 repr +# with non-ascii characters (see issue 877 and 1379) +def ecu(s): + try: + return u(s, "utf-8", "replace") + except TypeError: + return s + + +def format_explanation(explanation): + """This formats an explanation + + Normally all embedded newlines are escaped, however there are + three exceptions: \n{, \n} and \n~. The first two are intended + cover nested explanations, see function and attribute explanations + for examples (.visit_Call(), visit_Attribute()). The last one is + for when one explanation needs to span multiple lines, e.g. when + displaying diffs. + """ + explanation = ecu(explanation) + lines = _split_explanation(explanation) + result = _format_lines(lines) + return u("\n").join(result) + + +def _split_explanation(explanation): + """Return a list of individual lines in the explanation + + This will return a list of lines split on '\n{', '\n}' and '\n~'. + Any other newlines will be escaped and appear in the line as the + literal '\n' characters. + """ + raw_lines = (explanation or u("")).split("\n") + lines = [raw_lines[0]] + for values in raw_lines[1:]: + if values and values[0] in ["{", "}", "~", ">"]: + lines.append(values) + else: + lines[-1] += "\\n" + values + return lines + + +def _format_lines(lines): + """Format the individual lines + + This will replace the '{', '}' and '~' characters of our mini + formatting language with the proper 'where ...', 'and ...' and ' + + ...' text, taking care of indentation along the way. + + Return a list of formatted lines. + """ + result = lines[:1] + stack = [0] + stackcnt = [0] + for line in lines[1:]: + if line.startswith("{"): + if stackcnt[-1]: + s = u("and ") + else: + s = u("where ") + stack.append(len(result)) + stackcnt[-1] += 1 + stackcnt.append(0) + result.append(u(" +") + u(" ") * (len(stack) - 1) + s + line[1:]) + elif line.startswith("}"): + stack.pop() + stackcnt.pop() + result[stack[-1]] += line[1:] + else: + assert line[0] in ["~", ">"] + stack[-1] += 1 + indent = len(stack) if line.startswith("~") else len(stack) - 1 + result.append(u(" ") * indent + line[1:]) + assert len(stack) == 1 + return result + + +# Provide basestring in python3 +try: + basestring = basestring +except NameError: + basestring = str + + +def assertrepr_compare(config, op, left, right): + """Return specialised explanations for some operators/operands""" + width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op + left_repr = py.io.saferepr(left, maxsize=int(width // 2)) + right_repr = py.io.saferepr(right, maxsize=width - len(left_repr)) + + summary = u("%s %s %s") % (ecu(left_repr), op, ecu(right_repr)) + + def issequence(x): + return isinstance(x, Sequence) and not isinstance(x, basestring) + + def istext(x): + return isinstance(x, basestring) + + def isdict(x): + return isinstance(x, dict) + + def isset(x): + return isinstance(x, (set, frozenset)) + + def isiterable(obj): + try: + iter(obj) + return not istext(obj) + except TypeError: + return False + + verbose = config.getoption("verbose") + explanation = None + try: + if op == "==": + if istext(left) and istext(right): + explanation = _diff_text(left, right, verbose) + else: + if issequence(left) and issequence(right): + explanation = _compare_eq_sequence(left, right, verbose) + elif isset(left) and isset(right): + explanation = _compare_eq_set(left, right, verbose) + elif isdict(left) and isdict(right): + explanation = _compare_eq_dict(left, right, verbose) + if isiterable(left) and isiterable(right): + expl = _compare_eq_iterable(left, right, verbose) + if explanation is not None: + explanation.extend(expl) + else: + explanation = expl + elif op == "not in": + if istext(left) and istext(right): + explanation = _notin_text(left, right, verbose) + except Exception: + explanation = [ + u( + "(pytest_assertion plugin: representation of details failed. " + "Probably an object has a faulty __repr__.)" + ), + u(_pytest._code.ExceptionInfo()), + ] + + if not explanation: + return None + + return [summary] + explanation + + +def _diff_text(left, right, verbose=False): + """Return the explanation for the diff between text or bytes + + Unless --verbose is used this will skip leading and trailing + characters which are identical to keep the diff minimal. + + If the input are bytes they will be safely converted to text. + """ + from difflib import ndiff + + explanation = [] + + def escape_for_readable_diff(binary_text): + """ + Ensures that the internal string is always valid unicode, converting any bytes safely to valid unicode. + This is done using repr() which then needs post-processing to fix the encompassing quotes and un-escape + newlines and carriage returns (#429). + """ + r = six.text_type(repr(binary_text)[1:-1]) + r = r.replace(r"\n", "\n") + r = r.replace(r"\r", "\r") + return r + + if isinstance(left, six.binary_type): + left = escape_for_readable_diff(left) + if isinstance(right, six.binary_type): + right = escape_for_readable_diff(right) + if not verbose: + i = 0 # just in case left or right has zero length + for i in range(min(len(left), len(right))): + if left[i] != right[i]: + break + if i > 42: + i -= 10 # Provide some context + explanation = [ + u("Skipping %s identical leading " "characters in diff, use -v to show") + % i + ] + left = left[i:] + right = right[i:] + if len(left) == len(right): + for i in range(len(left)): + if left[-i] != right[-i]: + break + if i > 42: + i -= 10 # Provide some context + explanation += [ + u( + "Skipping %s identical trailing " + "characters in diff, use -v to show" + ) + % i + ] + left = left[:-i] + right = right[:-i] + keepends = True + if left.isspace() or right.isspace(): + left = repr(str(left)) + right = repr(str(right)) + explanation += [u"Strings contain only whitespace, escaping them using repr()"] + explanation += [ + line.strip("\n") + for line in ndiff(left.splitlines(keepends), right.splitlines(keepends)) + ] + return explanation + + +def _compare_eq_iterable(left, right, verbose=False): + if not verbose: + return [u("Use -v to get the full diff")] + # dynamic import to speedup pytest + import difflib + + try: + left_formatting = pprint.pformat(left).splitlines() + right_formatting = pprint.pformat(right).splitlines() + explanation = [u("Full diff:")] + except Exception: + # hack: PrettyPrinter.pformat() in python 2 fails when formatting items that can't be sorted(), ie, calling + # sorted() on a list would raise. See issue #718. + # As a workaround, the full diff is generated by using the repr() string of each item of each container. + left_formatting = sorted(repr(x) for x in left) + right_formatting = sorted(repr(x) for x in right) + explanation = [u("Full diff (fallback to calling repr on each item):")] + explanation.extend( + line.strip() for line in difflib.ndiff(left_formatting, right_formatting) + ) + return explanation + + +def _compare_eq_sequence(left, right, verbose=False): + explanation = [] + for i in range(min(len(left), len(right))): + if left[i] != right[i]: + explanation += [u("At index %s diff: %r != %r") % (i, left[i], right[i])] + break + if len(left) > len(right): + explanation += [ + u("Left contains more items, first extra item: %s") + % py.io.saferepr(left[len(right)]) + ] + elif len(left) < len(right): + explanation += [ + u("Right contains more items, first extra item: %s") + % py.io.saferepr(right[len(left)]) + ] + return explanation + + +def _compare_eq_set(left, right, verbose=False): + explanation = [] + diff_left = left - right + diff_right = right - left + if diff_left: + explanation.append(u("Extra items in the left set:")) + for item in diff_left: + explanation.append(py.io.saferepr(item)) + if diff_right: + explanation.append(u("Extra items in the right set:")) + for item in diff_right: + explanation.append(py.io.saferepr(item)) + return explanation + + +def _compare_eq_dict(left, right, verbose=False): + explanation = [] + common = set(left).intersection(set(right)) + same = {k: left[k] for k in common if left[k] == right[k]} + if same and verbose < 2: + explanation += [u("Omitting %s identical items, use -vv to show") % len(same)] + elif same: + explanation += [u("Common items:")] + explanation += pprint.pformat(same).splitlines() + diff = {k for k in common if left[k] != right[k]} + if diff: + explanation += [u("Differing items:")] + for k in diff: + explanation += [ + py.io.saferepr({k: left[k]}) + " != " + py.io.saferepr({k: right[k]}) + ] + extra_left = set(left) - set(right) + if extra_left: + explanation.append(u("Left contains more items:")) + explanation.extend( + pprint.pformat({k: left[k] for k in extra_left}).splitlines() + ) + extra_right = set(right) - set(left) + if extra_right: + explanation.append(u("Right contains more items:")) + explanation.extend( + pprint.pformat({k: right[k] for k in extra_right}).splitlines() + ) + return explanation + + +def _notin_text(term, text, verbose=False): + index = text.find(term) + head = text[:index] + tail = text[index + len(term) :] + correct_text = head + tail + diff = _diff_text(correct_text, text, verbose) + newdiff = [u("%s is contained here:") % py.io.saferepr(term, maxsize=42)] + for line in diff: + if line.startswith(u("Skipping")): + continue + if line.startswith(u("- ")): + continue + if line.startswith(u("+ ")): + newdiff.append(u(" ") + line[2:]) + else: + newdiff.append(line) + return newdiff diff --git a/Lib/site-packages/_pytest/cacheprovider.py b/Lib/site-packages/_pytest/cacheprovider.py new file mode 100644 index 0000000..dc72512 --- /dev/null +++ b/Lib/site-packages/_pytest/cacheprovider.py @@ -0,0 +1,358 @@ +""" +merged implementation of the cache provider + +the name cache was not chosen to ensure pluggy automatically +ignores the external pytest-cache +""" +from __future__ import absolute_import, division, print_function +from collections import OrderedDict + +import py +import six +import attr + +import pytest +import json +import shutil + +from . import paths +from .compat import _PY2 as PY2, Path + +README_CONTENT = u"""\ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/latest/cache.html) for more information. +""" + + +@attr.s +class Cache(object): + _cachedir = attr.ib(repr=False) + _warn = attr.ib(repr=False) + + @classmethod + def for_config(cls, config): + cachedir = cls.cache_dir_from_config(config) + if config.getoption("cacheclear") and cachedir.exists(): + shutil.rmtree(str(cachedir)) + cachedir.mkdir() + return cls(cachedir, config.warn) + + @staticmethod + def cache_dir_from_config(config): + return paths.resolve_from_str(config.getini("cache_dir"), config.rootdir) + + def warn(self, fmt, **args): + self._warn(code="I9", message=fmt.format(**args) if args else fmt) + + def makedir(self, name): + """ return a directory path object with the given name. If the + directory does not yet exist, it will be created. You can use it + to manage files likes e. g. store/retrieve database + dumps across test sessions. + + :param name: must be a string not containing a ``/`` separator. + Make sure the name contains your plugin or application + identifiers to prevent clashes with other cache users. + """ + name = Path(name) + if len(name.parts) > 1: + raise ValueError("name is not allowed to contain path separators") + res = self._cachedir.joinpath("d", name) + res.mkdir(exist_ok=True, parents=True) + return py.path.local(res) + + def _getvaluepath(self, key): + return self._cachedir.joinpath("v", Path(key)) + + def get(self, key, default): + """ return cached value for the given key. If no value + was yet cached or the value cannot be read, the specified + default is returned. + + :param key: must be a ``/`` separated value. Usually the first + name is the name of your plugin or your application. + :param default: must be provided in case of a cache-miss or + invalid cache values. + + """ + path = self._getvaluepath(key) + try: + with path.open("r") as f: + return json.load(f) + except (ValueError, IOError, OSError): + return default + + def set(self, key, value): + """ save value for the given key. + + :param key: must be a ``/`` separated value. Usually the first + name is the name of your plugin or your application. + :param value: must be of any combination of basic + python types, including nested types + like e. g. lists of dictionaries. + """ + path = self._getvaluepath(key) + try: + path.parent.mkdir(exist_ok=True, parents=True) + except (IOError, OSError): + self.warn("could not create cache path {path}", path=path) + return + try: + f = path.open("wb" if PY2 else "w") + except (IOError, OSError): + self.warn("cache could not write path {path}", path=path) + else: + with f: + json.dump(value, f, indent=2, sort_keys=True) + self._ensure_readme() + + def _ensure_readme(self): + + if self._cachedir.is_dir(): + readme_path = self._cachedir / "README.md" + if not readme_path.is_file(): + readme_path.write_text(README_CONTENT) + + +class LFPlugin(object): + """ Plugin which implements the --lf (run last-failing) option """ + + def __init__(self, config): + self.config = config + active_keys = "lf", "failedfirst" + self.active = any(config.getoption(key) for key in active_keys) + self.lastfailed = config.cache.get("cache/lastfailed", {}) + self._previously_failed_count = None + self._no_failures_behavior = self.config.getoption("last_failed_no_failures") + + def pytest_report_collectionfinish(self): + if self.active: + if not self._previously_failed_count: + mode = "run {} (no recorded failures)".format( + self._no_failures_behavior + ) + else: + noun = "failure" if self._previously_failed_count == 1 else "failures" + suffix = " first" if self.config.getoption("failedfirst") else "" + mode = "rerun previous {count} {noun}{suffix}".format( + count=self._previously_failed_count, suffix=suffix, noun=noun + ) + return "run-last-failure: %s" % mode + + def pytest_runtest_logreport(self, report): + if (report.when == "call" and report.passed) or report.skipped: + self.lastfailed.pop(report.nodeid, None) + elif report.failed: + self.lastfailed[report.nodeid] = True + + def pytest_collectreport(self, report): + passed = report.outcome in ("passed", "skipped") + if passed: + if report.nodeid in self.lastfailed: + self.lastfailed.pop(report.nodeid) + self.lastfailed.update((item.nodeid, True) for item in report.result) + else: + self.lastfailed[report.nodeid] = True + + def pytest_collection_modifyitems(self, session, config, items): + if self.active: + if self.lastfailed: + previously_failed = [] + previously_passed = [] + for item in items: + if item.nodeid in self.lastfailed: + previously_failed.append(item) + else: + previously_passed.append(item) + self._previously_failed_count = len(previously_failed) + if not previously_failed: + # running a subset of all tests with recorded failures outside + # of the set of tests currently executing + return + if self.config.getoption("lf"): + items[:] = previously_failed + config.hook.pytest_deselected(items=previously_passed) + else: + items[:] = previously_failed + previously_passed + elif self._no_failures_behavior == "none": + config.hook.pytest_deselected(items=items) + items[:] = [] + + def pytest_sessionfinish(self, session): + config = self.config + if config.getoption("cacheshow") or hasattr(config, "slaveinput"): + return + + saved_lastfailed = config.cache.get("cache/lastfailed", {}) + if saved_lastfailed != self.lastfailed: + config.cache.set("cache/lastfailed", self.lastfailed) + + +class NFPlugin(object): + """ Plugin which implements the --nf (run new-first) option """ + + def __init__(self, config): + self.config = config + self.active = config.option.newfirst + self.cached_nodeids = config.cache.get("cache/nodeids", []) + + def pytest_collection_modifyitems(self, session, config, items): + if self.active: + new_items = OrderedDict() + other_items = OrderedDict() + for item in items: + if item.nodeid not in self.cached_nodeids: + new_items[item.nodeid] = item + else: + other_items[item.nodeid] = item + + items[:] = self._get_increasing_order( + six.itervalues(new_items) + ) + self._get_increasing_order(six.itervalues(other_items)) + self.cached_nodeids = [x.nodeid for x in items if isinstance(x, pytest.Item)] + + def _get_increasing_order(self, items): + return sorted(items, key=lambda item: item.fspath.mtime(), reverse=True) + + def pytest_sessionfinish(self, session): + config = self.config + if config.getoption("cacheshow") or hasattr(config, "slaveinput"): + return + + config.cache.set("cache/nodeids", self.cached_nodeids) + + +def pytest_addoption(parser): + group = parser.getgroup("general") + group.addoption( + "--lf", + "--last-failed", + action="store_true", + dest="lf", + help="rerun only the tests that failed " + "at the last run (or all if none failed)", + ) + group.addoption( + "--ff", + "--failed-first", + action="store_true", + dest="failedfirst", + help="run all tests but run the last failures first. " + "This may re-order tests and thus lead to " + "repeated fixture setup/teardown", + ) + group.addoption( + "--nf", + "--new-first", + action="store_true", + dest="newfirst", + help="run tests from new files first, then the rest of the tests " + "sorted by file mtime", + ) + group.addoption( + "--cache-show", + action="store_true", + dest="cacheshow", + help="show cache contents, don't perform collection or tests", + ) + group.addoption( + "--cache-clear", + action="store_true", + dest="cacheclear", + help="remove all cache contents at start of test run.", + ) + parser.addini("cache_dir", default=".pytest_cache", help="cache directory path.") + group.addoption( + "--lfnf", + "--last-failed-no-failures", + action="store", + dest="last_failed_no_failures", + choices=("all", "none"), + default="all", + help="change the behavior when no test failed in the last run or no " + "information about the last failures was found in the cache", + ) + + +def pytest_cmdline_main(config): + if config.option.cacheshow: + from _pytest.main import wrap_session + + return wrap_session(config, cacheshow) + + +@pytest.hookimpl(tryfirst=True) +def pytest_configure(config): + config.cache = Cache.for_config(config) + config.pluginmanager.register(LFPlugin(config), "lfplugin") + config.pluginmanager.register(NFPlugin(config), "nfplugin") + + +@pytest.fixture +def cache(request): + """ + Return a cache object that can persist state between testing sessions. + + cache.get(key, default) + cache.set(key, value) + + Keys must be a ``/`` separated value, where the first part is usually the + name of your plugin or application to avoid clashes with other cache users. + + Values can be any object handled by the json stdlib module. + """ + return request.config.cache + + +def pytest_report_header(config): + if config.option.verbose: + cachedir = config.cache._cachedir + # TODO: evaluate generating upward relative paths + # starting with .., ../.. if sensible + + try: + displaypath = cachedir.relative_to(config.rootdir) + except ValueError: + displaypath = cachedir + return "cachedir: {}".format(displaypath) + + +def cacheshow(config, session): + from pprint import pformat + + tw = py.io.TerminalWriter() + tw.line("cachedir: " + str(config.cache._cachedir)) + if not config.cache._cachedir.is_dir(): + tw.line("cache is empty") + return 0 + dummy = object() + basedir = config.cache._cachedir + vdir = basedir / "v" + tw.sep("-", "cache values") + for valpath in sorted(x for x in vdir.rglob("*") if x.is_file()): + key = valpath.relative_to(vdir) + val = config.cache.get(key, dummy) + if val is dummy: + tw.line("%s contains unreadable content, " "will be ignored" % key) + else: + tw.line("%s contains:" % key) + for line in pformat(val).splitlines(): + tw.line(" " + line) + + ddir = basedir / "d" + if ddir.is_dir(): + contents = sorted(ddir.rglob("*")) + tw.sep("-", "cache directories") + for p in contents: + # if p.check(dir=1): + # print("%s/" % p.relto(basedir)) + if p.is_file(): + key = p.relative_to(basedir) + tw.line("{} is a file of length {:d}".format(key, p.stat().st_size)) + return 0 diff --git a/Lib/site-packages/_pytest/capture.py b/Lib/site-packages/_pytest/capture.py new file mode 100644 index 0000000..faa767a --- /dev/null +++ b/Lib/site-packages/_pytest/capture.py @@ -0,0 +1,722 @@ +""" +per-test stdout/stderr capturing mechanism. + +""" +from __future__ import absolute_import, division, print_function + +import collections +import contextlib +import sys +import os +import io +from io import UnsupportedOperation +from tempfile import TemporaryFile + +import six +import pytest +from _pytest.compat import CaptureIO + + +patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"} + + +def pytest_addoption(parser): + group = parser.getgroup("general") + group._addoption( + "--capture", + action="store", + default="fd" if hasattr(os, "dup") else "sys", + metavar="method", + choices=["fd", "sys", "no"], + help="per-test capturing method: one of fd|sys|no.", + ) + group._addoption( + "-s", + action="store_const", + const="no", + dest="capture", + help="shortcut for --capture=no.", + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_load_initial_conftests(early_config, parser, args): + ns = early_config.known_args_namespace + if ns.capture == "fd": + _py36_windowsconsoleio_workaround(sys.stdout) + _colorama_workaround() + _readline_workaround() + pluginmanager = early_config.pluginmanager + capman = CaptureManager(ns.capture) + pluginmanager.register(capman, "capturemanager") + + # make sure that capturemanager is properly reset at final shutdown + early_config.add_cleanup(capman.stop_global_capturing) + + # make sure logging does not raise exceptions at the end + def silence_logging_at_shutdown(): + if "logging" in sys.modules: + sys.modules["logging"].raiseExceptions = False + + early_config.add_cleanup(silence_logging_at_shutdown) + + # finally trigger conftest loading but while capturing (issue93) + capman.start_global_capturing() + outcome = yield + out, err = capman.suspend_global_capture() + if outcome.excinfo is not None: + sys.stdout.write(out) + sys.stderr.write(err) + + +class CaptureManager(object): + """ + Capture plugin, manages that the appropriate capture method is enabled/disabled during collection and each + test phase (setup, call, teardown). After each of those points, the captured output is obtained and + attached to the collection/runtest report. + + There are two levels of capture: + * global: which is enabled by default and can be suppressed by the ``-s`` option. This is always enabled/disabled + during collection and each test phase. + * fixture: when a test function or one of its fixture depend on the ``capsys`` or ``capfd`` fixtures. In this + case special handling is needed to ensure the fixtures take precedence over the global capture. + """ + + def __init__(self, method): + self._method = method + self._global_capturing = None + + def _getcapture(self, method): + if method == "fd": + return MultiCapture(out=True, err=True, Capture=FDCapture) + elif method == "sys": + return MultiCapture(out=True, err=True, Capture=SysCapture) + elif method == "no": + return MultiCapture(out=False, err=False, in_=False) + else: + raise ValueError("unknown capturing method: %r" % method) + + def start_global_capturing(self): + assert self._global_capturing is None + self._global_capturing = self._getcapture(self._method) + self._global_capturing.start_capturing() + + def stop_global_capturing(self): + if self._global_capturing is not None: + self._global_capturing.pop_outerr_to_orig() + self._global_capturing.stop_capturing() + self._global_capturing = None + + def resume_global_capture(self): + self._global_capturing.resume_capturing() + + def suspend_global_capture(self, item=None, in_=False): + if item is not None: + self.deactivate_fixture(item) + cap = getattr(self, "_global_capturing", None) + if cap is not None: + try: + outerr = cap.readouterr() + finally: + cap.suspend_capturing(in_=in_) + return outerr + + def activate_fixture(self, item): + """If the current item is using ``capsys`` or ``capfd``, activate them so they take precedence over + the global capture. + """ + fixture = getattr(item, "_capture_fixture", None) + if fixture is not None: + fixture._start() + + def deactivate_fixture(self, item): + """Deactivates the ``capsys`` or ``capfd`` fixture of this item, if any.""" + fixture = getattr(item, "_capture_fixture", None) + if fixture is not None: + fixture.close() + + @pytest.hookimpl(hookwrapper=True) + def pytest_make_collect_report(self, collector): + if isinstance(collector, pytest.File): + self.resume_global_capture() + outcome = yield + out, err = self.suspend_global_capture() + rep = outcome.get_result() + if out: + rep.sections.append(("Captured stdout", out)) + if err: + rep.sections.append(("Captured stderr", err)) + else: + yield + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_setup(self, item): + self.resume_global_capture() + # no need to activate a capture fixture because they activate themselves during creation; this + # only makes sense when a fixture uses a capture fixture, otherwise the capture fixture will + # be activated during pytest_runtest_call + yield + self.suspend_capture_item(item, "setup") + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_call(self, item): + self.resume_global_capture() + # it is important to activate this fixture during the call phase so it overwrites the "global" + # capture + self.activate_fixture(item) + yield + self.suspend_capture_item(item, "call") + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_teardown(self, item): + self.resume_global_capture() + self.activate_fixture(item) + yield + self.suspend_capture_item(item, "teardown") + + @pytest.hookimpl(tryfirst=True) + def pytest_keyboard_interrupt(self, excinfo): + self.stop_global_capturing() + + @pytest.hookimpl(tryfirst=True) + def pytest_internalerror(self, excinfo): + self.stop_global_capturing() + + def suspend_capture_item(self, item, when, in_=False): + out, err = self.suspend_global_capture(item, in_=in_) + item.add_report_section(when, "stdout", out) + item.add_report_section(when, "stderr", err) + + +capture_fixtures = {"capfd", "capfdbinary", "capsys", "capsysbinary"} + + +def _ensure_only_one_capture_fixture(request, name): + fixtures = set(request.fixturenames) & capture_fixtures - {name} + if fixtures: + fixtures = sorted(fixtures) + fixtures = fixtures[0] if len(fixtures) == 1 else fixtures + raise request.raiseerror( + "cannot use {} and {} at the same time".format(fixtures, name) + ) + + +@pytest.fixture +def capsys(request): + """Enable capturing of writes to ``sys.stdout`` and ``sys.stderr`` and make + captured output available via ``capsys.readouterr()`` method calls + which return a ``(out, err)`` namedtuple. ``out`` and ``err`` will be ``text`` + objects. + """ + _ensure_only_one_capture_fixture(request, "capsys") + with _install_capture_fixture_on_item(request, SysCapture) as fixture: + yield fixture + + +@pytest.fixture +def capsysbinary(request): + """Enable capturing of writes to ``sys.stdout`` and ``sys.stderr`` and make + captured output available via ``capsys.readouterr()`` method calls + which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``bytes`` + objects. + """ + _ensure_only_one_capture_fixture(request, "capsysbinary") + # Currently, the implementation uses the python3 specific `.buffer` + # property of CaptureIO. + if sys.version_info < (3,): + raise request.raiseerror("capsysbinary is only supported on python 3") + with _install_capture_fixture_on_item(request, SysCaptureBinary) as fixture: + yield fixture + + +@pytest.fixture +def capfd(request): + """Enable capturing of writes to file descriptors ``1`` and ``2`` and make + captured output available via ``capfd.readouterr()`` method calls + which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``text`` + objects. + """ + _ensure_only_one_capture_fixture(request, "capfd") + if not hasattr(os, "dup"): + pytest.skip( + "capfd fixture needs os.dup function which is not available in this system" + ) + with _install_capture_fixture_on_item(request, FDCapture) as fixture: + yield fixture + + +@pytest.fixture +def capfdbinary(request): + """Enable capturing of write to file descriptors 1 and 2 and make + captured output available via ``capfdbinary.readouterr`` method calls + which return a ``(out, err)`` tuple. ``out`` and ``err`` will be + ``bytes`` objects. + """ + _ensure_only_one_capture_fixture(request, "capfdbinary") + if not hasattr(os, "dup"): + pytest.skip( + "capfdbinary fixture needs os.dup function which is not available in this system" + ) + with _install_capture_fixture_on_item(request, FDCaptureBinary) as fixture: + yield fixture + + +@contextlib.contextmanager +def _install_capture_fixture_on_item(request, capture_class): + """ + Context manager which creates a ``CaptureFixture`` instance and "installs" it on + the item/node of the given request. Used by ``capsys`` and ``capfd``. + + The CaptureFixture is added as attribute of the item because it needs to accessed + by ``CaptureManager`` during its ``pytest_runtest_*`` hooks. + """ + request.node._capture_fixture = fixture = CaptureFixture(capture_class, request) + capmanager = request.config.pluginmanager.getplugin("capturemanager") + # need to active this fixture right away in case it is being used by another fixture (setup phase) + # if this fixture is being used only by a test function (call phase), then we wouldn't need this + # activation, but it doesn't hurt + capmanager.activate_fixture(request.node) + yield fixture + fixture.close() + del request.node._capture_fixture + + +class CaptureFixture(object): + """ + Object returned by :py:func:`capsys`, :py:func:`capsysbinary`, :py:func:`capfd` and :py:func:`capfdbinary` + fixtures. + """ + + def __init__(self, captureclass, request): + self.captureclass = captureclass + self.request = request + + def _start(self): + self._capture = MultiCapture( + out=True, err=True, in_=False, Capture=self.captureclass + ) + self._capture.start_capturing() + + def close(self): + cap = self.__dict__.pop("_capture", None) + if cap is not None: + self._outerr = cap.pop_outerr_to_orig() + cap.stop_capturing() + + def readouterr(self): + """Read and return the captured output so far, resetting the internal buffer. + + :return: captured content as a namedtuple with ``out`` and ``err`` string attributes + """ + try: + return self._capture.readouterr() + except AttributeError: + return self._outerr + + @contextlib.contextmanager + def disabled(self): + """Temporarily disables capture while inside the 'with' block.""" + self._capture.suspend_capturing() + capmanager = self.request.config.pluginmanager.getplugin("capturemanager") + capmanager.suspend_global_capture(item=None, in_=False) + try: + yield + finally: + capmanager.resume_global_capture() + self._capture.resume_capturing() + + +def safe_text_dupfile(f, mode, default_encoding="UTF8"): + """ return an open text file object that's a duplicate of f on the + FD-level if possible. + """ + encoding = getattr(f, "encoding", None) + try: + fd = f.fileno() + except Exception: + if "b" not in getattr(f, "mode", "") and hasattr(f, "encoding"): + # we seem to have a text stream, let's just use it + return f + else: + newfd = os.dup(fd) + if "b" not in mode: + mode += "b" + f = os.fdopen(newfd, mode, 0) # no buffering + return EncodedFile(f, encoding or default_encoding) + + +class EncodedFile(object): + errors = "strict" # possibly needed by py3 code (issue555) + + def __init__(self, buffer, encoding): + self.buffer = buffer + self.encoding = encoding + + def write(self, obj): + if isinstance(obj, six.text_type): + obj = obj.encode(self.encoding, "replace") + self.buffer.write(obj) + + def writelines(self, linelist): + data = "".join(linelist) + self.write(data) + + @property + def name(self): + """Ensure that file.name is a string.""" + return repr(self.buffer) + + def __getattr__(self, name): + return getattr(object.__getattribute__(self, "buffer"), name) + + +CaptureResult = collections.namedtuple("CaptureResult", ["out", "err"]) + + +class MultiCapture(object): + out = err = in_ = None + + def __init__(self, out=True, err=True, in_=True, Capture=None): + if in_: + self.in_ = Capture(0) + if out: + self.out = Capture(1) + if err: + self.err = Capture(2) + + def start_capturing(self): + if self.in_: + self.in_.start() + if self.out: + self.out.start() + if self.err: + self.err.start() + + def pop_outerr_to_orig(self): + """ pop current snapshot out/err capture and flush to orig streams. """ + out, err = self.readouterr() + if out: + self.out.writeorg(out) + if err: + self.err.writeorg(err) + return out, err + + def suspend_capturing(self, in_=False): + if self.out: + self.out.suspend() + if self.err: + self.err.suspend() + if in_ and self.in_: + self.in_.suspend() + self._in_suspended = True + + def resume_capturing(self): + if self.out: + self.out.resume() + if self.err: + self.err.resume() + if hasattr(self, "_in_suspended"): + self.in_.resume() + del self._in_suspended + + def stop_capturing(self): + """ stop capturing and reset capturing streams """ + if hasattr(self, "_reset"): + raise ValueError("was already stopped") + self._reset = True + if self.out: + self.out.done() + if self.err: + self.err.done() + if self.in_: + self.in_.done() + + def readouterr(self): + """ return snapshot unicode value of stdout/stderr capturings. """ + return CaptureResult( + self.out.snap() if self.out is not None else "", + self.err.snap() if self.err is not None else "", + ) + + +class NoCapture(object): + __init__ = start = done = suspend = resume = lambda *args: None + + +class FDCaptureBinary(object): + """Capture IO to/from a given os-level filedescriptor. + + snap() produces `bytes` + """ + + def __init__(self, targetfd, tmpfile=None): + self.targetfd = targetfd + try: + self.targetfd_save = os.dup(self.targetfd) + except OSError: + self.start = lambda: None + self.done = lambda: None + else: + if targetfd == 0: + assert not tmpfile, "cannot set tmpfile with stdin" + tmpfile = open(os.devnull, "r") + self.syscapture = SysCapture(targetfd) + else: + if tmpfile is None: + f = TemporaryFile() + with f: + tmpfile = safe_text_dupfile(f, mode="wb+") + if targetfd in patchsysdict: + self.syscapture = SysCapture(targetfd, tmpfile) + else: + self.syscapture = NoCapture() + self.tmpfile = tmpfile + self.tmpfile_fd = tmpfile.fileno() + + def __repr__(self): + return "" % (self.targetfd, self.targetfd_save) + + def start(self): + """ Start capturing on targetfd using memorized tmpfile. """ + try: + os.fstat(self.targetfd_save) + except (AttributeError, OSError): + raise ValueError("saved filedescriptor not valid anymore") + os.dup2(self.tmpfile_fd, self.targetfd) + self.syscapture.start() + + def snap(self): + self.tmpfile.seek(0) + res = self.tmpfile.read() + self.tmpfile.seek(0) + self.tmpfile.truncate() + return res + + def done(self): + """ stop capturing, restore streams, return original capture file, + seeked to position zero. """ + targetfd_save = self.__dict__.pop("targetfd_save") + os.dup2(targetfd_save, self.targetfd) + os.close(targetfd_save) + self.syscapture.done() + _attempt_to_close_capture_file(self.tmpfile) + + def suspend(self): + self.syscapture.suspend() + os.dup2(self.targetfd_save, self.targetfd) + + def resume(self): + self.syscapture.resume() + os.dup2(self.tmpfile_fd, self.targetfd) + + def writeorg(self, data): + """ write to original file descriptor. """ + if isinstance(data, six.text_type): + data = data.encode("utf8") # XXX use encoding of original stream + os.write(self.targetfd_save, data) + + +class FDCapture(FDCaptureBinary): + """Capture IO to/from a given os-level filedescriptor. + + snap() produces text + """ + + def snap(self): + res = FDCaptureBinary.snap(self) + enc = getattr(self.tmpfile, "encoding", None) + if enc and isinstance(res, bytes): + res = six.text_type(res, enc, "replace") + return res + + +class SysCapture(object): + def __init__(self, fd, tmpfile=None): + name = patchsysdict[fd] + self._old = getattr(sys, name) + self.name = name + if tmpfile is None: + if name == "stdin": + tmpfile = DontReadFromInput() + else: + tmpfile = CaptureIO() + self.tmpfile = tmpfile + + def start(self): + setattr(sys, self.name, self.tmpfile) + + def snap(self): + res = self.tmpfile.getvalue() + self.tmpfile.seek(0) + self.tmpfile.truncate() + return res + + def done(self): + setattr(sys, self.name, self._old) + del self._old + _attempt_to_close_capture_file(self.tmpfile) + + def suspend(self): + setattr(sys, self.name, self._old) + + def resume(self): + setattr(sys, self.name, self.tmpfile) + + def writeorg(self, data): + self._old.write(data) + self._old.flush() + + +class SysCaptureBinary(SysCapture): + def snap(self): + res = self.tmpfile.buffer.getvalue() + self.tmpfile.seek(0) + self.tmpfile.truncate() + return res + + +class DontReadFromInput(six.Iterator): + """Temporary stub class. Ideally when stdin is accessed, the + capturing should be turned off, with possibly all data captured + so far sent to the screen. This should be configurable, though, + because in automated test runs it is better to crash than + hang indefinitely. + """ + + encoding = None + + def read(self, *args): + raise IOError("reading from stdin while output is captured") + + readline = read + readlines = read + __next__ = read + + def __iter__(self): + return self + + def fileno(self): + raise UnsupportedOperation("redirected stdin is pseudofile, " "has no fileno()") + + def isatty(self): + return False + + def close(self): + pass + + @property + def buffer(self): + if sys.version_info >= (3, 0): + return self + else: + raise AttributeError("redirected stdin has no attribute buffer") + + +def _colorama_workaround(): + """ + Ensure colorama is imported so that it attaches to the correct stdio + handles on Windows. + + colorama uses the terminal on import time. So if something does the + first import of colorama while I/O capture is active, colorama will + fail in various ways. + """ + + if not sys.platform.startswith("win32"): + return + try: + import colorama # noqa + except ImportError: + pass + + +def _readline_workaround(): + """ + Ensure readline is imported so that it attaches to the correct stdio + handles on Windows. + + Pdb uses readline support where available--when not running from the Python + prompt, the readline module is not imported until running the pdb REPL. If + running pytest with the --pdb option this means the readline module is not + imported until after I/O capture has been started. + + This is a problem for pyreadline, which is often used to implement readline + support on Windows, as it does not attach to the correct handles for stdout + and/or stdin if they have been redirected by the FDCapture mechanism. This + workaround ensures that readline is imported before I/O capture is setup so + that it can attach to the actual stdin/out for the console. + + See https://github.com/pytest-dev/pytest/pull/1281 + """ + + if not sys.platform.startswith("win32"): + return + try: + import readline # noqa + except ImportError: + pass + + +def _py36_windowsconsoleio_workaround(stream): + """ + Python 3.6 implemented unicode console handling for Windows. This works + by reading/writing to the raw console handle using + ``{Read,Write}ConsoleW``. + + The problem is that we are going to ``dup2`` over the stdio file + descriptors when doing ``FDCapture`` and this will ``CloseHandle`` the + handles used by Python to write to the console. Though there is still some + weirdness and the console handle seems to only be closed randomly and not + on the first call to ``CloseHandle``, or maybe it gets reopened with the + same handle value when we suspend capturing. + + The workaround in this case will reopen stdio with a different fd which + also means a different handle by replicating the logic in + "Py_lifecycle.c:initstdio/create_stdio". + + :param stream: in practice ``sys.stdout`` or ``sys.stderr``, but given + here as parameter for unittesting purposes. + + See https://github.com/pytest-dev/py/issues/103 + """ + if not sys.platform.startswith("win32") or sys.version_info[:2] < (3, 6): + return + + # bail out if ``stream`` doesn't seem like a proper ``io`` stream (#2666) + if not hasattr(stream, "buffer"): + return + + buffered = hasattr(stream.buffer, "raw") + raw_stdout = stream.buffer.raw if buffered else stream.buffer + + if not isinstance(raw_stdout, io._WindowsConsoleIO): + return + + def _reopen_stdio(f, mode): + if not buffered and mode[0] == "w": + buffering = 0 + else: + buffering = -1 + + return io.TextIOWrapper( + open(os.dup(f.fileno()), mode, buffering), + f.encoding, + f.errors, + f.newlines, + f.line_buffering, + ) + + sys.__stdin__ = sys.stdin = _reopen_stdio(sys.stdin, "rb") + sys.__stdout__ = sys.stdout = _reopen_stdio(sys.stdout, "wb") + sys.__stderr__ = sys.stderr = _reopen_stdio(sys.stderr, "wb") + + +def _attempt_to_close_capture_file(f): + """Suppress IOError when closing the temporary file used for capturing streams in py27 (#2370)""" + if six.PY2: + try: + f.close() + except IOError: + pass + else: + f.close() diff --git a/Lib/site-packages/_pytest/compat.py b/Lib/site-packages/_pytest/compat.py new file mode 100644 index 0000000..52051ff --- /dev/null +++ b/Lib/site-packages/_pytest/compat.py @@ -0,0 +1,383 @@ +""" +python version compatibility code +""" +from __future__ import absolute_import, division, print_function + +import codecs +import functools +import inspect +import re +import sys + +import py + +import _pytest +from _pytest.outcomes import TEST_OUTCOME +from six import text_type +import six + +try: + import enum +except ImportError: # pragma: no cover + # Only available in Python 3.4+ or as a backport + enum = None + +__all__ = ["Path"] + +_PY3 = sys.version_info > (3, 0) +_PY2 = not _PY3 + + +if _PY3: + from inspect import signature, Parameter as Parameter +else: + from funcsigs import signature, Parameter as Parameter + +NoneType = type(None) +NOTSET = object() + +PY35 = sys.version_info[:2] >= (3, 5) +PY36 = sys.version_info[:2] >= (3, 6) +MODULE_NOT_FOUND_ERROR = "ModuleNotFoundError" if PY36 else "ImportError" + +if PY36: + from pathlib import Path +else: + from pathlib2 import Path + + +if _PY3: + from collections.abc import MutableMapping as MappingMixin + from collections.abc import Mapping, Sequence +else: + # those raise DeprecationWarnings in Python >=3.7 + from collections import MutableMapping as MappingMixin # noqa + from collections import Mapping, Sequence # noqa + + +def _format_args(func): + return str(signature(func)) + + +isfunction = inspect.isfunction +isclass = inspect.isclass +# used to work around a python2 exception info leak +exc_clear = getattr(sys, "exc_clear", lambda: None) +# The type of re.compile objects is not exposed in Python. +REGEX_TYPE = type(re.compile("")) + + +def is_generator(func): + genfunc = inspect.isgeneratorfunction(func) + return genfunc and not iscoroutinefunction(func) + + +def iscoroutinefunction(func): + """Return True if func is a decorated coroutine function. + + Note: copied and modified from Python 3.5's builtin couroutines.py to avoid import asyncio directly, + which in turns also initializes the "logging" module as side-effect (see issue #8). + """ + return getattr(func, "_is_coroutine", False) or ( + hasattr(inspect, "iscoroutinefunction") and inspect.iscoroutinefunction(func) + ) + + +def getlocation(function, curdir): + function = get_real_func(function) + fn = py.path.local(inspect.getfile(function)) + lineno = function.__code__.co_firstlineno + if fn.relto(curdir): + fn = fn.relto(curdir) + return "%s:%d" % (fn, lineno + 1) + + +def num_mock_patch_args(function): + """ return number of arguments used up by mock arguments (if any) """ + patchings = getattr(function, "patchings", None) + if not patchings: + return 0 + mock_modules = [sys.modules.get("mock"), sys.modules.get("unittest.mock")] + if any(mock_modules): + sentinels = [m.DEFAULT for m in mock_modules if m is not None] + return len( + [p for p in patchings if not p.attribute_name and p.new in sentinels] + ) + return len(patchings) + + +def getfuncargnames(function, is_method=False, cls=None): + """Returns the names of a function's mandatory arguments. + + This should return the names of all function arguments that: + * Aren't bound to an instance or type as in instance or class methods. + * Don't have default values. + * Aren't bound with functools.partial. + * Aren't replaced with mocks. + + The is_method and cls arguments indicate that the function should + be treated as a bound method even though it's not unless, only in + the case of cls, the function is a static method. + + @RonnyPfannschmidt: This function should be refactored when we + revisit fixtures. The fixture mechanism should ask the node for + the fixture names, and not try to obtain directly from the + function object well after collection has occurred. + + """ + # The parameters attribute of a Signature object contains an + # ordered mapping of parameter names to Parameter instances. This + # creates a tuple of the names of the parameters that don't have + # defaults. + arg_names = tuple( + p.name + for p in signature(function).parameters.values() + if ( + p.kind is Parameter.POSITIONAL_OR_KEYWORD + or p.kind is Parameter.KEYWORD_ONLY + ) + and p.default is Parameter.empty + ) + # If this function should be treated as a bound method even though + # it's passed as an unbound method or function, remove the first + # parameter name. + if is_method or ( + cls and not isinstance(cls.__dict__.get(function.__name__, None), staticmethod) + ): + arg_names = arg_names[1:] + # Remove any names that will be replaced with mocks. + if hasattr(function, "__wrapped__"): + arg_names = arg_names[num_mock_patch_args(function) :] + return arg_names + + +def get_default_arg_names(function): + # Note: this code intentionally mirrors the code at the beginning of getfuncargnames, + # to get the arguments which were excluded from its result because they had default values + return tuple( + p.name + for p in signature(function).parameters.values() + if p.kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY) + and p.default is not Parameter.empty + ) + + +if _PY3: + STRING_TYPES = bytes, str + UNICODE_TYPES = six.text_type + + if PY35: + + def _bytes_to_ascii(val): + return val.decode("ascii", "backslashreplace") + + else: + + def _bytes_to_ascii(val): + if val: + # source: http://goo.gl/bGsnwC + encoded_bytes, _ = codecs.escape_encode(val) + return encoded_bytes.decode("ascii") + else: + # empty bytes crashes codecs.escape_encode (#1087) + return "" + + def ascii_escaped(val): + """If val is pure ascii, returns it as a str(). Otherwise, escapes + bytes objects into a sequence of escaped bytes: + + b'\xc3\xb4\xc5\xd6' -> u'\\xc3\\xb4\\xc5\\xd6' + + and escapes unicode objects into a sequence of escaped unicode + ids, e.g.: + + '4\\nV\\U00043efa\\x0eMXWB\\x1e\\u3028\\u15fd\\xcd\\U0007d944' + + note: + the obvious "v.decode('unicode-escape')" will return + valid utf-8 unicode if it finds them in bytes, but we + want to return escaped bytes for any byte, even if they match + a utf-8 string. + + """ + if isinstance(val, bytes): + return _bytes_to_ascii(val) + else: + return val.encode("unicode_escape").decode("ascii") + + +else: + STRING_TYPES = six.string_types + UNICODE_TYPES = six.text_type + + def ascii_escaped(val): + """In py2 bytes and str are the same type, so return if it's a bytes + object, return it unchanged if it is a full ascii string, + otherwise escape it into its binary form. + + If it's a unicode string, change the unicode characters into + unicode escapes. + + """ + if isinstance(val, bytes): + try: + return val.encode("ascii") + except UnicodeDecodeError: + return val.encode("string-escape") + else: + return val.encode("unicode-escape") + + +def get_real_func(obj): + """ gets the real function object of the (possibly) wrapped object by + functools.wraps or functools.partial. + """ + start_obj = obj + for i in range(100): + new_obj = getattr(obj, "__wrapped__", None) + if new_obj is None: + break + obj = new_obj + else: + raise ValueError( + ("could not find real function of {start}" "\nstopped at {current}").format( + start=py.io.saferepr(start_obj), current=py.io.saferepr(obj) + ) + ) + if isinstance(obj, functools.partial): + obj = obj.func + return obj + + +def get_real_method(obj, holder): + """ + Attempts to obtain the real function object that might be wrapping ``obj``, while at the same time + returning a bound method to ``holder`` if the original object was a bound method. + """ + try: + is_method = hasattr(obj, "__func__") + obj = get_real_func(obj) + except Exception: + return obj + if is_method and hasattr(obj, "__get__") and callable(obj.__get__): + obj = obj.__get__(holder) + return obj + + +def getfslineno(obj): + # xxx let decorators etc specify a sane ordering + obj = get_real_func(obj) + if hasattr(obj, "place_as"): + obj = obj.place_as + fslineno = _pytest._code.getfslineno(obj) + assert isinstance(fslineno[1], int), obj + return fslineno + + +def getimfunc(func): + try: + return func.__func__ + except AttributeError: + return func + + +def safe_getattr(object, name, default): + """ Like getattr but return default upon any Exception or any OutcomeException. + + Attribute access can potentially fail for 'evil' Python objects. + See issue #214. + It catches OutcomeException because of #2490 (issue #580), new outcomes are derived from BaseException + instead of Exception (for more details check #2707) + """ + try: + return getattr(object, name, default) + except TEST_OUTCOME: + return default + + +def _is_unittest_unexpected_success_a_failure(): + """Return if the test suite should fail if an @expectedFailure unittest test PASSES. + + From https://docs.python.org/3/library/unittest.html?highlight=unittest#unittest.TestResult.wasSuccessful: + Changed in version 3.4: Returns False if there were any + unexpectedSuccesses from tests marked with the expectedFailure() decorator. + """ + return sys.version_info >= (3, 4) + + +if _PY3: + + def safe_str(v): + """returns v as string""" + return str(v) + + +else: + + def safe_str(v): + """returns v as string, converting to ascii if necessary""" + try: + return str(v) + except UnicodeError: + if not isinstance(v, text_type): + v = text_type(v) + errors = "replace" + return v.encode("utf-8", errors) + + +COLLECT_FAKEMODULE_ATTRIBUTES = ( + "Collector", + "Module", + "Generator", + "Function", + "Instance", + "Session", + "Item", + "Class", + "File", + "_fillfuncargs", +) + + +def _setup_collect_fakemodule(): + from types import ModuleType + import pytest + + pytest.collect = ModuleType("pytest.collect") + pytest.collect.__all__ = [] # used for setns + for attr in COLLECT_FAKEMODULE_ATTRIBUTES: + setattr(pytest.collect, attr, getattr(pytest, attr)) + + +if _PY2: + # Without this the test_dupfile_on_textio will fail, otherwise CaptureIO could directly inherit from StringIO. + from py.io import TextIO + + class CaptureIO(TextIO): + @property + def encoding(self): + return getattr(self, "_encoding", "UTF-8") + + +else: + import io + + class CaptureIO(io.TextIOWrapper): + def __init__(self): + super(CaptureIO, self).__init__( + io.BytesIO(), encoding="UTF-8", newline="", write_through=True + ) + + def getvalue(self): + return self.buffer.getvalue().decode("UTF-8") + + +class FuncargnamesCompatAttr(object): + """ helper class so that Metafunc, Function and FixtureRequest + don't need to each define the "funcargnames" compatibility attribute. + """ + + @property + def funcargnames(self): + """ alias attribute for ``fixturenames`` for pre-2.3 compatibility""" + return self.fixturenames diff --git a/Lib/site-packages/_pytest/config/__init__.py b/Lib/site-packages/_pytest/config/__init__.py new file mode 100644 index 0000000..421d124 --- /dev/null +++ b/Lib/site-packages/_pytest/config/__init__.py @@ -0,0 +1,984 @@ +""" command line options, ini-file and conftest.py processing. """ +from __future__ import absolute_import, division, print_function +import argparse +import shlex +import traceback +import types +import warnings +import copy +import six +import py + +# DON't import pytest here because it causes import cycle troubles +import sys +import os +from _pytest.outcomes import Skipped + +import _pytest._code +import _pytest.hookspec # the extension point definitions +import _pytest.assertion +from pluggy import PluginManager, HookimplMarker, HookspecMarker +from _pytest.compat import safe_str +from .exceptions import UsageError, PrintHelp +from .findpaths import determine_setup, exists + +hookimpl = HookimplMarker("pytest") +hookspec = HookspecMarker("pytest") + +# pytest startup +# + + +class ConftestImportFailure(Exception): + def __init__(self, path, excinfo): + Exception.__init__(self, path, excinfo) + self.path = path + self.excinfo = excinfo + + def __str__(self): + etype, evalue, etb = self.excinfo + formatted = traceback.format_tb(etb) + # The level of the tracebacks we want to print is hand crafted :( + return repr(evalue) + "\n" + "".join(formatted[2:]) + + +def main(args=None, plugins=None): + """ return exit code, after performing an in-process test run. + + :arg args: list of command line arguments. + + :arg plugins: list of plugin objects to be auto-registered during + initialization. + """ + try: + try: + config = _prepareconfig(args, plugins) + except ConftestImportFailure as e: + tw = py.io.TerminalWriter(sys.stderr) + for line in traceback.format_exception(*e.excinfo): + tw.line(line.rstrip(), red=True) + tw.line("ERROR: could not load %s\n" % (e.path,), red=True) + return 4 + else: + try: + return config.hook.pytest_cmdline_main(config=config) + finally: + config._ensure_unconfigure() + except UsageError as e: + tw = py.io.TerminalWriter(sys.stderr) + for msg in e.args: + tw.line("ERROR: {}\n".format(msg), red=True) + return 4 + + +class cmdline(object): # compatibility namespace + main = staticmethod(main) + + +def filename_arg(path, optname): + """ Argparse type validator for filename arguments. + + :path: path of filename + :optname: name of the option + """ + if os.path.isdir(path): + raise UsageError("{} must be a filename, given: {}".format(optname, path)) + return path + + +def directory_arg(path, optname): + """Argparse type validator for directory arguments. + + :path: path of directory + :optname: name of the option + """ + if not os.path.isdir(path): + raise UsageError("{} must be a directory, given: {}".format(optname, path)) + return path + + +default_plugins = ( + "mark", + "main", + "terminal", + "runner", + "python", + "fixtures", + "debugging", + "unittest", + "capture", + "skipping", + "tmpdir", + "monkeypatch", + "recwarn", + "pastebin", + "helpconfig", + "nose", + "assertion", + "junitxml", + "resultlog", + "doctest", + "cacheprovider", + "freeze_support", + "setuponly", + "setupplan", + "warnings", + "logging", +) + + +builtin_plugins = set(default_plugins) +builtin_plugins.add("pytester") + + +def get_config(): + # subsequent calls to main will create a fresh instance + pluginmanager = PytestPluginManager() + config = Config(pluginmanager) + for spec in default_plugins: + pluginmanager.import_plugin(spec) + return config + + +def get_plugin_manager(): + """ + Obtain a new instance of the + :py:class:`_pytest.config.PytestPluginManager`, with default plugins + already loaded. + + This function can be used by integration with other tools, like hooking + into pytest to run tests into an IDE. + """ + return get_config().pluginmanager + + +def _prepareconfig(args=None, plugins=None): + warning = None + if args is None: + args = sys.argv[1:] + elif isinstance(args, py.path.local): + args = [str(args)] + elif not isinstance(args, (tuple, list)): + if not isinstance(args, str): + raise ValueError("not a string or argument list: %r" % (args,)) + args = shlex.split(args, posix=sys.platform != "win32") + from _pytest import deprecated + + warning = deprecated.MAIN_STR_ARGS + config = get_config() + pluginmanager = config.pluginmanager + try: + if plugins: + for plugin in plugins: + if isinstance(plugin, six.string_types): + pluginmanager.consider_pluginarg(plugin) + else: + pluginmanager.register(plugin) + if warning: + config.warn("C1", warning) + return pluginmanager.hook.pytest_cmdline_parse( + pluginmanager=pluginmanager, args=args + ) + except BaseException: + config._ensure_unconfigure() + raise + + +class PytestPluginManager(PluginManager): + """ + Overwrites :py:class:`pluggy.PluginManager ` to add pytest-specific + functionality: + + * loading plugins from the command line, ``PYTEST_PLUGINS`` env variable and + ``pytest_plugins`` global variables found in plugins being loaded; + * ``conftest.py`` loading during start-up; + """ + + def __init__(self): + super(PytestPluginManager, self).__init__("pytest") + self._conftest_plugins = set() + + # state related to local conftest plugins + self._path2confmods = {} + self._conftestpath2mod = {} + self._confcutdir = None + self._noconftest = False + self._duplicatepaths = set() + + self.add_hookspecs(_pytest.hookspec) + self.register(self) + if os.environ.get("PYTEST_DEBUG"): + err = sys.stderr + encoding = getattr(err, "encoding", "utf8") + try: + err = py.io.dupfile(err, encoding=encoding) + except Exception: + pass + self.trace.root.setwriter(err.write) + self.enable_tracing() + + # Config._consider_importhook will set a real object if required. + self.rewrite_hook = _pytest.assertion.DummyRewriteHook() + # Used to know when we are importing conftests after the pytest_configure stage + self._configured = False + + def addhooks(self, module_or_class): + """ + .. deprecated:: 2.8 + + Use :py:meth:`pluggy.PluginManager.add_hookspecs ` + instead. + """ + warning = dict( + code="I2", + fslocation=_pytest._code.getfslineno(sys._getframe(1)), + nodeid=None, + message="use pluginmanager.add_hookspecs instead of " + "deprecated addhooks() method.", + ) + self._warn(warning) + return self.add_hookspecs(module_or_class) + + def parse_hookimpl_opts(self, plugin, name): + # pytest hooks are always prefixed with pytest_ + # so we avoid accessing possibly non-readable attributes + # (see issue #1073) + if not name.startswith("pytest_"): + return + # ignore some historic special names which can not be hooks anyway + if name == "pytest_plugins" or name.startswith("pytest_funcarg__"): + return + + method = getattr(plugin, name) + opts = super(PytestPluginManager, self).parse_hookimpl_opts(plugin, name) + + # collect unmarked hooks as long as they have the `pytest_' prefix + if opts is None and name.startswith("pytest_"): + opts = {} + + if opts is not None: + for name in ("tryfirst", "trylast", "optionalhook", "hookwrapper"): + opts.setdefault(name, hasattr(method, name)) + return opts + + def parse_hookspec_opts(self, module_or_class, name): + opts = super(PytestPluginManager, self).parse_hookspec_opts( + module_or_class, name + ) + if opts is None: + method = getattr(module_or_class, name) + if name.startswith("pytest_"): + opts = { + "firstresult": hasattr(method, "firstresult"), + "historic": hasattr(method, "historic"), + } + return opts + + def register(self, plugin, name=None): + if name in ["pytest_catchlog", "pytest_capturelog"]: + self._warn( + "{} plugin has been merged into the core, " + "please remove it from your requirements.".format( + name.replace("_", "-") + ) + ) + return + ret = super(PytestPluginManager, self).register(plugin, name) + if ret: + self.hook.pytest_plugin_registered.call_historic( + kwargs=dict(plugin=plugin, manager=self) + ) + + if isinstance(plugin, types.ModuleType): + self.consider_module(plugin) + return ret + + def getplugin(self, name): + # support deprecated naming because plugins (xdist e.g.) use it + return self.get_plugin(name) + + def hasplugin(self, name): + """Return True if the plugin with the given name is registered.""" + return bool(self.get_plugin(name)) + + def pytest_configure(self, config): + # XXX now that the pluginmanager exposes hookimpl(tryfirst...) + # we should remove tryfirst/trylast as markers + config.addinivalue_line( + "markers", + "tryfirst: mark a hook implementation function such that the " + "plugin machinery will try to call it first/as early as possible.", + ) + config.addinivalue_line( + "markers", + "trylast: mark a hook implementation function such that the " + "plugin machinery will try to call it last/as late as possible.", + ) + self._configured = True + + def _warn(self, message): + kwargs = ( + message + if isinstance(message, dict) + else {"code": "I1", "message": message, "fslocation": None, "nodeid": None} + ) + self.hook.pytest_logwarning.call_historic(kwargs=kwargs) + + # + # internal API for local conftest plugin handling + # + def _set_initial_conftests(self, namespace): + """ load initial conftest files given a preparsed "namespace". + As conftest files may add their own command line options + which have arguments ('--my-opt somepath') we might get some + false positives. All builtin and 3rd party plugins will have + been loaded, however, so common options will not confuse our logic + here. + """ + current = py.path.local() + self._confcutdir = ( + current.join(namespace.confcutdir, abs=True) + if namespace.confcutdir + else None + ) + self._noconftest = namespace.noconftest + testpaths = namespace.file_or_dir + foundanchor = False + for path in testpaths: + path = str(path) + # remove node-id syntax + i = path.find("::") + if i != -1: + path = path[:i] + anchor = current.join(path, abs=1) + if exists(anchor): # we found some file object + self._try_load_conftest(anchor) + foundanchor = True + if not foundanchor: + self._try_load_conftest(current) + + def _try_load_conftest(self, anchor): + self._getconftestmodules(anchor) + # let's also consider test* subdirs + if anchor.check(dir=1): + for x in anchor.listdir("test*"): + if x.check(dir=1): + self._getconftestmodules(x) + + def _getconftestmodules(self, path): + if self._noconftest: + return [] + try: + return self._path2confmods[path] + except KeyError: + if path.isfile(): + clist = self._getconftestmodules(path.dirpath()) + else: + # XXX these days we may rather want to use config.rootdir + # and allow users to opt into looking into the rootdir parent + # directories instead of requiring to specify confcutdir + clist = [] + for parent in path.parts(): + if self._confcutdir and self._confcutdir.relto(parent): + continue + conftestpath = parent.join("conftest.py") + if conftestpath.isfile(): + mod = self._importconftest(conftestpath) + clist.append(mod) + + self._path2confmods[path] = clist + return clist + + def _rget_with_confmod(self, name, path): + modules = self._getconftestmodules(path) + for mod in reversed(modules): + try: + return mod, getattr(mod, name) + except AttributeError: + continue + raise KeyError(name) + + def _importconftest(self, conftestpath): + try: + return self._conftestpath2mod[conftestpath] + except KeyError: + pkgpath = conftestpath.pypkgpath() + if pkgpath is None: + _ensure_removed_sysmodule(conftestpath.purebasename) + try: + mod = conftestpath.pyimport() + if hasattr(mod, "pytest_plugins") and self._configured: + from _pytest.deprecated import ( + PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST + ) + + warnings.warn(PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST) + except Exception: + raise ConftestImportFailure(conftestpath, sys.exc_info()) + + self._conftest_plugins.add(mod) + self._conftestpath2mod[conftestpath] = mod + dirpath = conftestpath.dirpath() + if dirpath in self._path2confmods: + for path, mods in self._path2confmods.items(): + if path and path.relto(dirpath) or path == dirpath: + assert mod not in mods + mods.append(mod) + self.trace("loaded conftestmodule %r" % (mod)) + self.consider_conftest(mod) + return mod + + # + # API for bootstrapping plugin loading + # + # + + def consider_preparse(self, args): + for opt1, opt2 in zip(args, args[1:]): + if opt1 == "-p": + self.consider_pluginarg(opt2) + + def consider_pluginarg(self, arg): + if arg.startswith("no:"): + name = arg[3:] + self.set_blocked(name) + if not name.startswith("pytest_"): + self.set_blocked("pytest_" + name) + else: + self.import_plugin(arg) + + def consider_conftest(self, conftestmodule): + self.register(conftestmodule, name=conftestmodule.__file__) + + def consider_env(self): + self._import_plugin_specs(os.environ.get("PYTEST_PLUGINS")) + + def consider_module(self, mod): + self._import_plugin_specs(getattr(mod, "pytest_plugins", [])) + + def _import_plugin_specs(self, spec): + plugins = _get_plugin_specs_as_list(spec) + for import_spec in plugins: + self.import_plugin(import_spec) + + def import_plugin(self, modname): + # most often modname refers to builtin modules, e.g. "pytester", + # "terminal" or "capture". Those plugins are registered under their + # basename for historic purposes but must be imported with the + # _pytest prefix. + assert isinstance(modname, (six.text_type, str)), ( + "module name as text required, got %r" % modname + ) + modname = str(modname) + if self.is_blocked(modname) or self.get_plugin(modname) is not None: + return + if modname in builtin_plugins: + importspec = "_pytest." + modname + else: + importspec = modname + self.rewrite_hook.mark_rewrite(importspec) + try: + __import__(importspec) + except ImportError as e: + new_exc_type = ImportError + new_exc_message = 'Error importing plugin "%s": %s' % ( + modname, + safe_str(e.args[0]), + ) + new_exc = new_exc_type(new_exc_message) + + six.reraise(new_exc_type, new_exc, sys.exc_info()[2]) + + except Skipped as e: + self._warn("skipped plugin %r: %s" % ((modname, e.msg))) + else: + mod = sys.modules[importspec] + self.register(mod, modname) + + +def _get_plugin_specs_as_list(specs): + """ + Parses a list of "plugin specs" and returns a list of plugin names. + + Plugin specs can be given as a list of strings separated by "," or already as a list/tuple in + which case it is returned as a list. Specs can also be `None` in which case an + empty list is returned. + """ + if specs is not None: + if isinstance(specs, str): + specs = specs.split(",") if specs else [] + if not isinstance(specs, (list, tuple)): + raise UsageError( + "Plugin specs must be a ','-separated string or a " + "list/tuple of strings for plugin names. Given: %r" % specs + ) + return list(specs) + return [] + + +def _ensure_removed_sysmodule(modname): + try: + del sys.modules[modname] + except KeyError: + pass + + +class Notset(object): + def __repr__(self): + return "" + + +notset = Notset() + + +def _iter_rewritable_modules(package_files): + for fn in package_files: + is_simple_module = "/" not in fn and fn.endswith(".py") + is_package = fn.count("/") == 1 and fn.endswith("__init__.py") + if is_simple_module: + module_name, _ = os.path.splitext(fn) + yield module_name + elif is_package: + package_name = os.path.dirname(fn) + yield package_name + + +class Config(object): + """ access to configuration values, pluginmanager and plugin hooks. """ + + def __init__(self, pluginmanager): + #: access to command line option as attributes. + #: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead + self.option = argparse.Namespace() + from .argparsing import Parser, FILE_OR_DIR + + _a = FILE_OR_DIR + self._parser = Parser( + usage="%%(prog)s [options] [%s] [%s] [...]" % (_a, _a), + processopt=self._processopt, + ) + #: a pluginmanager instance + self.pluginmanager = pluginmanager + self.trace = self.pluginmanager.trace.root.get("config") + self.hook = self.pluginmanager.hook + self._inicache = {} + self._override_ini = () + self._opt2dest = {} + self._cleanup = [] + self._warn = self.pluginmanager._warn + self.pluginmanager.register(self, "pytestconfig") + self._configured = False + + def do_setns(dic): + import pytest + + setns(pytest, dic) + + self.hook.pytest_namespace.call_historic(do_setns, {}) + self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser)) + + def add_cleanup(self, func): + """ Add a function to be called when the config object gets out of + use (usually coninciding with pytest_unconfigure).""" + self._cleanup.append(func) + + def _do_configure(self): + assert not self._configured + self._configured = True + self.hook.pytest_configure.call_historic(kwargs=dict(config=self)) + + def _ensure_unconfigure(self): + if self._configured: + self._configured = False + self.hook.pytest_unconfigure(config=self) + self.hook.pytest_configure._call_history = [] + while self._cleanup: + fin = self._cleanup.pop() + fin() + + def warn(self, code, message, fslocation=None, nodeid=None): + """ generate a warning for this test session. """ + self.hook.pytest_logwarning.call_historic( + kwargs=dict( + code=code, message=message, fslocation=fslocation, nodeid=nodeid + ) + ) + + def get_terminal_writer(self): + return self.pluginmanager.get_plugin("terminalreporter")._tw + + def pytest_cmdline_parse(self, pluginmanager, args): + # REF1 assert self == pluginmanager.config, (self, pluginmanager.config) + self.parse(args) + return self + + def notify_exception(self, excinfo, option=None): + if option and option.fulltrace: + style = "long" + else: + style = "native" + excrepr = excinfo.getrepr( + funcargs=True, showlocals=getattr(option, "showlocals", False), style=style + ) + res = self.hook.pytest_internalerror(excrepr=excrepr, excinfo=excinfo) + if not any(res): + for line in str(excrepr).split("\n"): + sys.stderr.write("INTERNALERROR> %s\n" % line) + sys.stderr.flush() + + def cwd_relative_nodeid(self, nodeid): + # nodeid's are relative to the rootpath, compute relative to cwd + if self.invocation_dir != self.rootdir: + fullpath = self.rootdir.join(nodeid) + nodeid = self.invocation_dir.bestrelpath(fullpath) + return nodeid + + @classmethod + def fromdictargs(cls, option_dict, args): + """ constructor useable for subprocesses. """ + config = get_config() + config.option.__dict__.update(option_dict) + config.parse(args, addopts=False) + for x in config.option.plugins: + config.pluginmanager.consider_pluginarg(x) + return config + + def _processopt(self, opt): + for name in opt._short_opts + opt._long_opts: + self._opt2dest[name] = opt.dest + + if hasattr(opt, "default") and opt.dest: + if not hasattr(self.option, opt.dest): + setattr(self.option, opt.dest, opt.default) + + @hookimpl(trylast=True) + def pytest_load_initial_conftests(self, early_config): + self.pluginmanager._set_initial_conftests(early_config.known_args_namespace) + + def _initini(self, args): + ns, unknown_args = self._parser.parse_known_and_unknown_args( + args, namespace=copy.copy(self.option) + ) + r = determine_setup( + ns.inifilename, + ns.file_or_dir + unknown_args, + warnfunc=self.warn, + rootdir_cmd_arg=ns.rootdir or None, + ) + self.rootdir, self.inifile, self.inicfg = r + self._parser.extra_info["rootdir"] = self.rootdir + self._parser.extra_info["inifile"] = self.inifile + self.invocation_dir = py.path.local() + self._parser.addini("addopts", "extra command line options", "args") + self._parser.addini("minversion", "minimally required pytest version") + self._override_ini = ns.override_ini or () + + def _consider_importhook(self, args): + """Install the PEP 302 import hook if using assertion rewriting. + + Needs to parse the --assert= option from the commandline + and find all the installed plugins to mark them for rewriting + by the importhook. + """ + ns, unknown_args = self._parser.parse_known_and_unknown_args(args) + mode = ns.assertmode + if mode == "rewrite": + try: + hook = _pytest.assertion.install_importhook(self) + except SystemError: + mode = "plain" + else: + self._mark_plugins_for_rewrite(hook) + _warn_about_missing_assertion(mode) + + def _mark_plugins_for_rewrite(self, hook): + """ + Given an importhook, mark for rewrite any top-level + modules or packages in the distribution package for + all pytest plugins. + """ + import pkg_resources + + self.pluginmanager.rewrite_hook = hook + + # 'RECORD' available for plugins installed normally (pip install) + # 'SOURCES.txt' available for plugins installed in dev mode (pip install -e) + # for installed plugins 'SOURCES.txt' returns an empty list, and vice-versa + # so it shouldn't be an issue + metadata_files = "RECORD", "SOURCES.txt" + + package_files = ( + entry.split(",")[0] + for entrypoint in pkg_resources.iter_entry_points("pytest11") + for metadata in metadata_files + for entry in entrypoint.dist._get_metadata(metadata) + ) + + for name in _iter_rewritable_modules(package_files): + hook.mark_rewrite(name) + + def _preparse(self, args, addopts=True): + if addopts: + args[:] = shlex.split(os.environ.get("PYTEST_ADDOPTS", "")) + args + self._initini(args) + if addopts: + args[:] = self.getini("addopts") + args + self._checkversion() + self._consider_importhook(args) + self.pluginmanager.consider_preparse(args) + self.pluginmanager.load_setuptools_entrypoints("pytest11") + self.pluginmanager.consider_env() + self.known_args_namespace = ns = self._parser.parse_known_args( + args, namespace=copy.copy(self.option) + ) + if self.known_args_namespace.confcutdir is None and self.inifile: + confcutdir = py.path.local(self.inifile).dirname + self.known_args_namespace.confcutdir = confcutdir + try: + self.hook.pytest_load_initial_conftests( + early_config=self, args=args, parser=self._parser + ) + except ConftestImportFailure: + e = sys.exc_info()[1] + if ns.help or ns.version: + # we don't want to prevent --help/--version to work + # so just let is pass and print a warning at the end + self._warn("could not load initial conftests (%s)\n" % e.path) + else: + raise + + def _checkversion(self): + import pytest + + minver = self.inicfg.get("minversion", None) + if minver: + ver = minver.split(".") + myver = pytest.__version__.split(".") + if myver < ver: + raise pytest.UsageError( + "%s:%d: requires pytest-%s, actual pytest-%s'" + % ( + self.inicfg.config.path, + self.inicfg.lineof("minversion"), + minver, + pytest.__version__, + ) + ) + + def parse(self, args, addopts=True): + # parse given cmdline arguments into this config object. + assert not hasattr( + self, "args" + ), "can only parse cmdline args at most once per Config object" + self._origargs = args + self.hook.pytest_addhooks.call_historic( + kwargs=dict(pluginmanager=self.pluginmanager) + ) + self._preparse(args, addopts=addopts) + # XXX deprecated hook: + self.hook.pytest_cmdline_preparse(config=self, args=args) + self._parser.after_preparse = True + try: + args = self._parser.parse_setoption( + args, self.option, namespace=self.option + ) + if not args: + cwd = os.getcwd() + if cwd == self.rootdir: + args = self.getini("testpaths") + if not args: + args = [cwd] + self.args = args + except PrintHelp: + pass + + def addinivalue_line(self, name, line): + """ add a line to an ini-file option. The option must have been + declared but might not yet be set in which case the line becomes the + the first line in its value. """ + x = self.getini(name) + assert isinstance(x, list) + x.append(line) # modifies the cached list inline + + def getini(self, name): + """ return configuration value from an :ref:`ini file `. If the + specified name hasn't been registered through a prior + :py:func:`parser.addini <_pytest.config.Parser.addini>` + call (usually from a plugin), a ValueError is raised. """ + try: + return self._inicache[name] + except KeyError: + self._inicache[name] = val = self._getini(name) + return val + + def _getini(self, name): + try: + description, type, default = self._parser._inidict[name] + except KeyError: + raise ValueError("unknown configuration value: %r" % (name,)) + value = self._get_override_ini_value(name) + if value is None: + try: + value = self.inicfg[name] + except KeyError: + if default is not None: + return default + if type is None: + return "" + return [] + if type == "pathlist": + dp = py.path.local(self.inicfg.config.path).dirpath() + values = [] + for relpath in shlex.split(value): + values.append(dp.join(relpath, abs=True)) + return values + elif type == "args": + return shlex.split(value) + elif type == "linelist": + return [t for t in map(lambda x: x.strip(), value.split("\n")) if t] + elif type == "bool": + return bool(_strtobool(value.strip())) + else: + assert type is None + return value + + def _getconftest_pathlist(self, name, path): + try: + mod, relroots = self.pluginmanager._rget_with_confmod(name, path) + except KeyError: + return None + modpath = py.path.local(mod.__file__).dirpath() + values = [] + for relroot in relroots: + if not isinstance(relroot, py.path.local): + relroot = relroot.replace("/", py.path.local.sep) + relroot = modpath.join(relroot, abs=True) + values.append(relroot) + return values + + def _get_override_ini_value(self, name): + value = None + # override_ini is a list of "ini=value" options + # always use the last item if multiple values are set for same ini-name, + # e.g. -o foo=bar1 -o foo=bar2 will set foo to bar2 + for ini_config in self._override_ini: + try: + key, user_ini_value = ini_config.split("=", 1) + except ValueError: + raise UsageError("-o/--override-ini expects option=value style.") + else: + if key == name: + value = user_ini_value + return value + + def getoption(self, name, default=notset, skip=False): + """ return command line option value. + + :arg name: name of the option. You may also specify + the literal ``--OPT`` option instead of the "dest" option name. + :arg default: default value if no option of that name exists. + :arg skip: if True raise pytest.skip if option does not exists + or has a None value. + """ + name = self._opt2dest.get(name, name) + try: + val = getattr(self.option, name) + if val is None and skip: + raise AttributeError(name) + return val + except AttributeError: + if default is not notset: + return default + if skip: + import pytest + + pytest.skip("no %r option found" % (name,)) + raise ValueError("no option named %r" % (name,)) + + def getvalue(self, name, path=None): + """ (deprecated, use getoption()) """ + return self.getoption(name) + + def getvalueorskip(self, name, path=None): + """ (deprecated, use getoption(skip=True)) """ + return self.getoption(name, skip=True) + + +def _assertion_supported(): + try: + assert False + except AssertionError: + return True + else: + return False + + +def _warn_about_missing_assertion(mode): + if not _assertion_supported(): + if mode == "plain": + sys.stderr.write( + "WARNING: ASSERTIONS ARE NOT EXECUTED" + " and FAILING TESTS WILL PASS. Are you" + " using python -O?" + ) + else: + sys.stderr.write( + "WARNING: assertions not in test modules or" + " plugins will be ignored" + " because assert statements are not executed " + "by the underlying Python interpreter " + "(are you using python -O?)\n" + ) + + +def setns(obj, dic): + import pytest + + for name, value in dic.items(): + if isinstance(value, dict): + mod = getattr(obj, name, None) + if mod is None: + modname = "pytest.%s" % name + mod = types.ModuleType(modname) + sys.modules[modname] = mod + mod.__all__ = [] + setattr(obj, name, mod) + obj.__all__.append(name) + setns(mod, value) + else: + setattr(obj, name, value) + obj.__all__.append(name) + # if obj != pytest: + # pytest.__all__.append(name) + setattr(pytest, name, value) + + +def create_terminal_writer(config, *args, **kwargs): + """Create a TerminalWriter instance configured according to the options + in the config object. Every code which requires a TerminalWriter object + and has access to a config object should use this function. + """ + tw = py.io.TerminalWriter(*args, **kwargs) + if config.option.color == "yes": + tw.hasmarkup = True + if config.option.color == "no": + tw.hasmarkup = False + return tw + + +def _strtobool(val): + """Convert a string representation of truth to true (1) or false (0). + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + + .. note:: copied from distutils.util + """ + val = val.lower() + if val in ("y", "yes", "t", "true", "on", "1"): + return 1 + elif val in ("n", "no", "f", "false", "off", "0"): + return 0 + else: + raise ValueError("invalid truth value %r" % (val,)) diff --git a/Lib/site-packages/_pytest/config/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/_pytest/config/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b70646a8c24781b631f65f438306d316c23c9604 GIT binary patch literal 28643 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 MVpL|XoO$kl03o#Oh5!Hn literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/config/__pycache__/exceptions.cpython-37.pyc b/Lib/site-packages/_pytest/config/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99384d0eb959f901e480dac32fb80bdeedd92bbb GIT binary patch literal 639 zcmb7B%Sr<=6rGoLEDC-?7J_u4pbKA!_$s=PB5DO|AcRTU2B(uW$*6T(f5uH%1D>>s}%equ4R1d?NLw+3(#h(Ltz;4&D;oe=6s#8Ago z9f{;NXe?yFoLdOlF}Pa=kU=LDK_?PnCl(QK<4L{kcuzL1)%IG3VTKdIiVl^iB>8HOg$L!g-$O8^b-J?e@+-oi0S#Z_ISjRXr+SGih)u zw`oQe--_-cfHbV?e~GblZB^kfWp3WOH(WU>$V*?&)o^`X=7Ja`5#`q%=>wH`P27`$ z*q6kjYPySgoq%!MD+dzjhFhnK9^r)`&pcP65_1#Ow79K}5%9C^0>WIfX;#Bt3V=h0 hv@}Yhs?&l`Tx!mAsNP)l|2krl9!`JjXfD%g@&gC}omBt; literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/config/__pycache__/findpaths.cpython-37.pyc b/Lib/site-packages/_pytest/config/__pycache__/findpaths.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a76799c60654b6b5728ca32d7e79ee53cc4849bd GIT binary patch literal 4007 zcmai1Pj4H?6`$E%E|*J+l4ZrQ(==Vwt!<)~YNu}M2!@bWmW!Y+Yd}hDGfLSNXGyI@ z?ou-=SyGolQ5kR=Ac0f#P!v6ox3=gf$gv+|54rS|uVD1h-k0R=)8lX?x7M)@GfiQEpKpP2(xSS%!bKXV70lhMBy=S z6hu|nqKKX?98r4A8b#rXGFnGWi;9@SN=filR-5?>Tv`1qj=IJ(_dVrzf)y!a*)nJa zAGHq3GK%^xsskrwLpEZo%wj3ucIE4w(T^BDfM{TA)bD^>p|u&bwrfUa_5EZsv%^jl z%i!-!7QyA&2g{4=@2Nnl^_BYj554O@S^sIjf7?&|^}BJ)@2;-}z5aSX?9YdhO8jnj ze&?o$<(qH4z1}}a0+p;c$89T)+F@tC9Y%uAQ49Tp%ntTLl_;BJCgB-3xWlVlme8ME zjRupe{Raa9jdod&4-8z#ByD!gfvI)LQg)ji@c~+OBQdtjp*3P1jQ9UVD<6I_u=3f| z8u5X(|F_iIDvc{PDCiL5+TuD^;+%Dya-!KZNb%q zQJe&e-XmW|?cJ#5h060IFYYH{9Qj?3=BVrKsz7*2tT$>p65HR1caw=s3iA62?es*@ zmqE)S?*&O9J+&F{c7?YQK>l952a-pdLFDC^n-KW|GAR$1 z83|vC$q6JI2_Hrsl)k#}Cg9cmhv6;zKUjh$}1QpBpjVkJSh&?C z&s0n39B*5LpBH7Y2R{xnJHJL|EMLd8Lk}E5tB2(zj=PKbV$H1A>$OTYJ9giNledu+ z1v8_6AnA@-L7$ct@HC0atgSeVwEJcys3~{)tn_XaE^GhK92IEOP?-%2?fFTqlv%J^ zl{v@Oqz`CRK)&HCEt<+qY{@JdH_Fc~WV|m)1*bHW*|{pFu%s4HF}Gs42rL$_a2I73 zwTn=bj|@IzR1Jr_MwL6pIW8}PV)B|622^xp{R|z!27LcFI-EQh7^y)~R-NB*;rwjd zk(W|qz%eq0Jmq+2^bmgyd27d|J(x8{T;84R!YTranVO(3NjEi#`aUd0b307TEo)d9 z;ml|T)b@zUPtX==CZ*)S>orGfyit%rH;FSFmeGqNc@DDbHLwCo9gVzdoW6wYI0HXY>o6NY435-w&C zzK=*7<@$s*xg)XGZdgSJ?uSiqKPVhqjk+vjwr0o*8cD`d<8qq%l=@B_4yLS{d2stB z7PP-He)xUT1eB?oZ5j8PWW*=FH=+1uac05id2xhsfikjLKQtB>^B9zil@(OK8zwIh zj9k7+ui7N{%jJk-5i~c3t5u%P@(?=>er~!7Netc=~gF* zg8jZ+YG6U>@BxQ-xw%Yez9ux$o+T!)qtZ!aj+~wXjZ3$$hkJ9W35oUbV6815be z{#vqFQUZ+r%NRz3(?iTYK)KHnH?@E|%h6xQy-HF}D;Z z{UohyRVZ|6+&MQWr{&?4D3AECinsmp9^3g6T+6BTA`XcQJxmX0Mhxc|barwE<5@^v zK7uwxd;B6Be=-# zd0Hh2Q1k!=j3bRw5zz_7!)y!j3qpb>cn?IFMbVJAQd za?xk}hle+Bhk$^{K?mOD-wrN&z?lH8yOCJ%mg#SbcM$JN@ACZo7@}StgU*H8Ic-9@ zyJ|@AEwI#)J#&IcXhbDnp*g}Y^4q8~=NG|&{u`xpl1}^bJgr`!iY)NC{At7r=!}A~ zkl|jCx$tqo$~|8yd6l+OuBlBoiohonlC`f$x^H88EN!#Z6O<=13xP^$<=OglRxcL2 Y-C&8*yP{xB;G$wyitZKXRp;D)0nT{O6aWAK literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/config/argparsing.py b/Lib/site-packages/_pytest/config/argparsing.py new file mode 100644 index 0000000..21d99b0 --- /dev/null +++ b/Lib/site-packages/_pytest/config/argparsing.py @@ -0,0 +1,392 @@ +import six +import warnings +import argparse + +FILE_OR_DIR = "file_or_dir" + + +class Parser(object): + """ Parser for command line arguments and ini-file values. + + :ivar extra_info: dict of generic param -> value to display in case + there's an error processing the command line arguments. + """ + + def __init__(self, usage=None, processopt=None): + self._anonymous = OptionGroup("custom options", parser=self) + self._groups = [] + self._processopt = processopt + self._usage = usage + self._inidict = {} + self._ininames = [] + self.extra_info = {} + + def processoption(self, option): + if self._processopt: + if option.dest: + self._processopt(option) + + def getgroup(self, name, description="", after=None): + """ get (or create) a named option Group. + + :name: name of the option group. + :description: long description for --help output. + :after: name of other group, used for ordering --help output. + + The returned group object has an ``addoption`` method with the same + signature as :py:func:`parser.addoption + <_pytest.config.Parser.addoption>` but will be shown in the + respective group in the output of ``pytest. --help``. + """ + for group in self._groups: + if group.name == name: + return group + group = OptionGroup(name, description, parser=self) + i = 0 + for i, grp in enumerate(self._groups): + if grp.name == after: + break + self._groups.insert(i + 1, group) + return group + + def addoption(self, *opts, **attrs): + """ register a command line option. + + :opts: option names, can be short or long options. + :attrs: same attributes which the ``add_option()`` function of the + `argparse library + `_ + accepts. + + After command line parsing options are available on the pytest config + object via ``config.option.NAME`` where ``NAME`` is usually set + by passing a ``dest`` attribute, for example + ``addoption("--long", dest="NAME", ...)``. + """ + self._anonymous.addoption(*opts, **attrs) + + def parse(self, args, namespace=None): + from _pytest._argcomplete import try_argcomplete + + self.optparser = self._getparser() + try_argcomplete(self.optparser) + return self.optparser.parse_args([str(x) for x in args], namespace=namespace) + + def _getparser(self): + from _pytest._argcomplete import filescompleter + + optparser = MyOptionParser(self, self.extra_info) + groups = self._groups + [self._anonymous] + for group in groups: + if group.options: + desc = group.description or group.name + arggroup = optparser.add_argument_group(desc) + for option in group.options: + n = option.names() + a = option.attrs() + arggroup.add_argument(*n, **a) + # bash like autocompletion for dirs (appending '/') + optparser.add_argument(FILE_OR_DIR, nargs="*").completer = filescompleter + return optparser + + def parse_setoption(self, args, option, namespace=None): + parsedoption = self.parse(args, namespace=namespace) + for name, value in parsedoption.__dict__.items(): + setattr(option, name, value) + return getattr(parsedoption, FILE_OR_DIR) + + def parse_known_args(self, args, namespace=None): + """parses and returns a namespace object with known arguments at this + point. + """ + return self.parse_known_and_unknown_args(args, namespace=namespace)[0] + + def parse_known_and_unknown_args(self, args, namespace=None): + """parses and returns a namespace object with known arguments, and + the remaining arguments unknown at this point. + """ + optparser = self._getparser() + args = [str(x) for x in args] + return optparser.parse_known_args(args, namespace=namespace) + + def addini(self, name, help, type=None, default=None): + """ register an ini-file option. + + :name: name of the ini-variable + :type: type of the variable, can be ``pathlist``, ``args``, ``linelist`` + or ``bool``. + :default: default value if no ini-file option exists but is queried. + + The value of ini-variables can be retrieved via a call to + :py:func:`config.getini(name) <_pytest.config.Config.getini>`. + """ + assert type in (None, "pathlist", "args", "linelist", "bool") + self._inidict[name] = (help, type, default) + self._ininames.append(name) + + +class ArgumentError(Exception): + """ + Raised if an Argument instance is created with invalid or + inconsistent arguments. + """ + + def __init__(self, msg, option): + self.msg = msg + self.option_id = str(option) + + def __str__(self): + if self.option_id: + return "option %s: %s" % (self.option_id, self.msg) + else: + return self.msg + + +class Argument(object): + """class that mimics the necessary behaviour of optparse.Option + + its currently a least effort implementation + and ignoring choices and integer prefixes + https://docs.python.org/3/library/optparse.html#optparse-standard-option-types + """ + + _typ_map = {"int": int, "string": str, "float": float, "complex": complex} + + def __init__(self, *names, **attrs): + """store parms in private vars for use in add_argument""" + self._attrs = attrs + self._short_opts = [] + self._long_opts = [] + self.dest = attrs.get("dest") + if "%default" in (attrs.get("help") or ""): + warnings.warn( + 'pytest now uses argparse. "%default" should be' + ' changed to "%(default)s" ', + DeprecationWarning, + stacklevel=3, + ) + try: + typ = attrs["type"] + except KeyError: + pass + else: + # this might raise a keyerror as well, don't want to catch that + if isinstance(typ, six.string_types): + if typ == "choice": + warnings.warn( + "type argument to addoption() is a string %r." + " For parsearg this is optional and when supplied" + " should be a type." + " (options: %s)" % (typ, names), + DeprecationWarning, + stacklevel=3, + ) + # argparse expects a type here take it from + # the type of the first element + attrs["type"] = type(attrs["choices"][0]) + else: + warnings.warn( + "type argument to addoption() is a string %r." + " For parsearg this should be a type." + " (options: %s)" % (typ, names), + DeprecationWarning, + stacklevel=3, + ) + attrs["type"] = Argument._typ_map[typ] + # used in test_parseopt -> test_parse_defaultgetter + self.type = attrs["type"] + else: + self.type = typ + try: + # attribute existence is tested in Config._processopt + self.default = attrs["default"] + except KeyError: + pass + self._set_opt_strings(names) + if not self.dest: + if self._long_opts: + self.dest = self._long_opts[0][2:].replace("-", "_") + else: + try: + self.dest = self._short_opts[0][1:] + except IndexError: + raise ArgumentError("need a long or short option", self) + + def names(self): + return self._short_opts + self._long_opts + + def attrs(self): + # update any attributes set by processopt + attrs = "default dest help".split() + if self.dest: + attrs.append(self.dest) + for attr in attrs: + try: + self._attrs[attr] = getattr(self, attr) + except AttributeError: + pass + if self._attrs.get("help"): + a = self._attrs["help"] + a = a.replace("%default", "%(default)s") + # a = a.replace('%prog', '%(prog)s') + self._attrs["help"] = a + return self._attrs + + def _set_opt_strings(self, opts): + """directly from optparse + + might not be necessary as this is passed to argparse later on""" + for opt in opts: + if len(opt) < 2: + raise ArgumentError( + "invalid option string %r: " + "must be at least two characters long" % opt, + self, + ) + elif len(opt) == 2: + if not (opt[0] == "-" and opt[1] != "-"): + raise ArgumentError( + "invalid short option string %r: " + "must be of the form -x, (x any non-dash char)" % opt, + self, + ) + self._short_opts.append(opt) + else: + if not (opt[0:2] == "--" and opt[2] != "-"): + raise ArgumentError( + "invalid long option string %r: " + "must start with --, followed by non-dash" % opt, + self, + ) + self._long_opts.append(opt) + + def __repr__(self): + args = [] + if self._short_opts: + args += ["_short_opts: " + repr(self._short_opts)] + if self._long_opts: + args += ["_long_opts: " + repr(self._long_opts)] + args += ["dest: " + repr(self.dest)] + if hasattr(self, "type"): + args += ["type: " + repr(self.type)] + if hasattr(self, "default"): + args += ["default: " + repr(self.default)] + return "Argument({})".format(", ".join(args)) + + +class OptionGroup(object): + def __init__(self, name, description="", parser=None): + self.name = name + self.description = description + self.options = [] + self.parser = parser + + def addoption(self, *optnames, **attrs): + """ add an option to this group. + + if a shortened version of a long option is specified it will + be suppressed in the help. addoption('--twowords', '--two-words') + results in help showing '--two-words' only, but --twowords gets + accepted **and** the automatic destination is in args.twowords + """ + conflict = set(optnames).intersection( + name for opt in self.options for name in opt.names() + ) + if conflict: + raise ValueError("option names %s already added" % conflict) + option = Argument(*optnames, **attrs) + self._addoption_instance(option, shortupper=False) + + def _addoption(self, *optnames, **attrs): + option = Argument(*optnames, **attrs) + self._addoption_instance(option, shortupper=True) + + def _addoption_instance(self, option, shortupper=False): + if not shortupper: + for opt in option._short_opts: + if opt[0] == "-" and opt[1].islower(): + raise ValueError("lowercase shortoptions reserved") + if self.parser: + self.parser.processoption(option) + self.options.append(option) + + +class MyOptionParser(argparse.ArgumentParser): + def __init__(self, parser, extra_info=None): + if not extra_info: + extra_info = {} + self._parser = parser + argparse.ArgumentParser.__init__( + self, + usage=parser._usage, + add_help=False, + formatter_class=DropShorterLongHelpFormatter, + ) + # extra_info is a dict of (param -> value) to display if there's + # an usage error to provide more contextual information to the user + self.extra_info = extra_info + + def parse_args(self, args=None, namespace=None): + """allow splitting of positional arguments""" + args, argv = self.parse_known_args(args, namespace) + if argv: + for arg in argv: + if arg and arg[0] == "-": + lines = ["unrecognized arguments: %s" % (" ".join(argv))] + for k, v in sorted(self.extra_info.items()): + lines.append(" %s: %s" % (k, v)) + self.error("\n".join(lines)) + getattr(args, FILE_OR_DIR).extend(argv) + return args + + +class DropShorterLongHelpFormatter(argparse.HelpFormatter): + """shorten help for long options that differ only in extra hyphens + + - collapse **long** options that are the same except for extra hyphens + - special action attribute map_long_option allows surpressing additional + long options + - shortcut if there are only two options and one of them is a short one + - cache result on action object as this is called at least 2 times + """ + + def _format_action_invocation(self, action): + orgstr = argparse.HelpFormatter._format_action_invocation(self, action) + if orgstr and orgstr[0] != "-": # only optional arguments + return orgstr + res = getattr(action, "_formatted_action_invocation", None) + if res: + return res + options = orgstr.split(", ") + if len(options) == 2 and (len(options[0]) == 2 or len(options[1]) == 2): + # a shortcut for '-h, --help' or '--abc', '-a' + action._formatted_action_invocation = orgstr + return orgstr + return_list = [] + option_map = getattr(action, "map_long_option", {}) + if option_map is None: + option_map = {} + short_long = {} + for option in options: + if len(option) == 2 or option[2] == " ": + continue + if not option.startswith("--"): + raise ArgumentError( + 'long optional argument without "--": [%s]' % (option), self + ) + xxoption = option[2:] + if xxoption.split()[0] not in option_map: + shortened = xxoption.replace("-", "") + if shortened not in short_long or len(short_long[shortened]) < len( + xxoption + ): + short_long[shortened] = xxoption + # now short_long has been filled out to the longest with dashes + # **and** we keep the right option ordering from add_argument + for option in options: + if len(option) == 2 or option[2] == " ": + return_list.append(option) + if option[2:] == short_long.get(option.replace("-", "")): + return_list.append(option.replace(" ", "=", 1)) + action._formatted_action_invocation = ", ".join(return_list) + return action._formatted_action_invocation diff --git a/Lib/site-packages/_pytest/config/exceptions.py b/Lib/site-packages/_pytest/config/exceptions.py new file mode 100644 index 0000000..19fe5cb --- /dev/null +++ b/Lib/site-packages/_pytest/config/exceptions.py @@ -0,0 +1,9 @@ +class UsageError(Exception): + """ error in pytest usage or invocation""" + + +class PrintHelp(Exception): + """Raised when pytest should print it's help to skip the rest of the + argument parsing and validation.""" + + pass diff --git a/Lib/site-packages/_pytest/config/findpaths.py b/Lib/site-packages/_pytest/config/findpaths.py new file mode 100644 index 0000000..234aa69 --- /dev/null +++ b/Lib/site-packages/_pytest/config/findpaths.py @@ -0,0 +1,139 @@ +import py +import os +from .exceptions import UsageError + + +def exists(path, ignore=EnvironmentError): + try: + return path.check() + except ignore: + return False + + +def getcfg(args, warnfunc=None): + """ + Search the list of arguments for a valid ini-file for pytest, + and return a tuple of (rootdir, inifile, cfg-dict). + + note: warnfunc is an optional function used to warn + about ini-files that use deprecated features. + This parameter should be removed when pytest + adopts standard deprecation warnings (#1804). + """ + from _pytest.deprecated import CFG_PYTEST_SECTION + + inibasenames = ["pytest.ini", "tox.ini", "setup.cfg"] + args = [x for x in args if not str(x).startswith("-")] + if not args: + args = [py.path.local()] + for arg in args: + arg = py.path.local(arg) + for base in arg.parts(reverse=True): + for inibasename in inibasenames: + p = base.join(inibasename) + if exists(p): + iniconfig = py.iniconfig.IniConfig(p) + if "pytest" in iniconfig.sections: + if inibasename == "setup.cfg" and warnfunc: + warnfunc( + "C1", CFG_PYTEST_SECTION.format(filename=inibasename) + ) + return base, p, iniconfig["pytest"] + if ( + inibasename == "setup.cfg" + and "tool:pytest" in iniconfig.sections + ): + return base, p, iniconfig["tool:pytest"] + elif inibasename == "pytest.ini": + # allowed to be empty + return base, p, {} + return None, None, None + + +def get_common_ancestor(paths): + common_ancestor = None + for path in paths: + if not path.exists(): + continue + if common_ancestor is None: + common_ancestor = path + else: + if path.relto(common_ancestor) or path == common_ancestor: + continue + elif common_ancestor.relto(path): + common_ancestor = path + else: + shared = path.common(common_ancestor) + if shared is not None: + common_ancestor = shared + if common_ancestor is None: + common_ancestor = py.path.local() + elif common_ancestor.isfile(): + common_ancestor = common_ancestor.dirpath() + return common_ancestor + + +def get_dirs_from_args(args): + def is_option(x): + return str(x).startswith("-") + + def get_file_part_from_node_id(x): + return str(x).split("::")[0] + + def get_dir_from_path(path): + if path.isdir(): + return path + return py.path.local(path.dirname) + + # These look like paths but may not exist + possible_paths = ( + py.path.local(get_file_part_from_node_id(arg)) + for arg in args + if not is_option(arg) + ) + + return [get_dir_from_path(path) for path in possible_paths if path.exists()] + + +def determine_setup(inifile, args, warnfunc=None, rootdir_cmd_arg=None): + dirs = get_dirs_from_args(args) + if inifile: + iniconfig = py.iniconfig.IniConfig(inifile) + is_cfg_file = str(inifile).endswith(".cfg") + # TODO: [pytest] section in *.cfg files is depricated. Need refactoring. + sections = ["tool:pytest", "pytest"] if is_cfg_file else ["pytest"] + for section in sections: + try: + inicfg = iniconfig[section] + if is_cfg_file and section == "pytest" and warnfunc: + from _pytest.deprecated import CFG_PYTEST_SECTION + + warnfunc("C1", CFG_PYTEST_SECTION.format(filename=str(inifile))) + break + except KeyError: + inicfg = None + rootdir = get_common_ancestor(dirs) + else: + ancestor = get_common_ancestor(dirs) + rootdir, inifile, inicfg = getcfg([ancestor], warnfunc=warnfunc) + if rootdir is None: + for rootdir in ancestor.parts(reverse=True): + if rootdir.join("setup.py").exists(): + break + else: + rootdir, inifile, inicfg = getcfg(dirs, warnfunc=warnfunc) + if rootdir is None: + rootdir = get_common_ancestor([py.path.local(), ancestor]) + is_fs_root = os.path.splitdrive(str(rootdir))[1] == "/" + if is_fs_root: + rootdir = ancestor + if rootdir_cmd_arg: + rootdir_abs_path = py.path.local(os.path.expandvars(rootdir_cmd_arg)) + if not os.path.isdir(str(rootdir_abs_path)): + raise UsageError( + "Directory '{}' not found. Check your '--rootdir' option.".format( + rootdir_abs_path + ) + ) + rootdir = rootdir_abs_path + return rootdir, inifile, inicfg or {} diff --git a/Lib/site-packages/_pytest/debugging.py b/Lib/site-packages/_pytest/debugging.py new file mode 100644 index 0000000..9991307 --- /dev/null +++ b/Lib/site-packages/_pytest/debugging.py @@ -0,0 +1,197 @@ +""" interactive debugging with PDB, the Python Debugger. """ +from __future__ import absolute_import, division, print_function +import pdb +import sys +import os +from doctest import UnexpectedException + +from _pytest.config import hookimpl + +try: + from builtins import breakpoint # noqa + + SUPPORTS_BREAKPOINT_BUILTIN = True +except ImportError: + SUPPORTS_BREAKPOINT_BUILTIN = False + + +def pytest_addoption(parser): + group = parser.getgroup("general") + group._addoption( + "--pdb", + dest="usepdb", + action="store_true", + help="start the interactive Python debugger on errors or KeyboardInterrupt.", + ) + group._addoption( + "--pdbcls", + dest="usepdb_cls", + metavar="modulename:classname", + help="start a custom interactive Python debugger on errors. " + "For example: --pdbcls=IPython.terminal.debugger:TerminalPdb", + ) + group._addoption( + "--trace", + dest="trace", + action="store_true", + help="Immediately break when running each test.", + ) + + +def pytest_configure(config): + if config.getvalue("usepdb_cls"): + modname, classname = config.getvalue("usepdb_cls").split(":") + __import__(modname) + pdb_cls = getattr(sys.modules[modname], classname) + else: + pdb_cls = pdb.Pdb + + if config.getvalue("trace"): + config.pluginmanager.register(PdbTrace(), "pdbtrace") + if config.getvalue("usepdb"): + config.pluginmanager.register(PdbInvoke(), "pdbinvoke") + + # Use custom Pdb class set_trace instead of default Pdb on breakpoint() call + if SUPPORTS_BREAKPOINT_BUILTIN: + _environ_pythonbreakpoint = os.environ.get("PYTHONBREAKPOINT", "") + if _environ_pythonbreakpoint == "": + sys.breakpointhook = pytestPDB.set_trace + + old = (pdb.set_trace, pytestPDB._pluginmanager) + + def fin(): + pdb.set_trace, pytestPDB._pluginmanager = old + pytestPDB._config = None + pytestPDB._pdb_cls = pdb.Pdb + if SUPPORTS_BREAKPOINT_BUILTIN: + sys.breakpointhook = sys.__breakpointhook__ + + pdb.set_trace = pytestPDB.set_trace + pytestPDB._pluginmanager = config.pluginmanager + pytestPDB._config = config + pytestPDB._pdb_cls = pdb_cls + config._cleanup.append(fin) + + +class pytestPDB(object): + """ Pseudo PDB that defers to the real pdb. """ + + _pluginmanager = None + _config = None + _pdb_cls = pdb.Pdb + + @classmethod + def set_trace(cls, set_break=True): + """ invoke PDB set_trace debugging, dropping any IO capturing. """ + import _pytest.config + + frame = sys._getframe().f_back + if cls._pluginmanager is not None: + capman = cls._pluginmanager.getplugin("capturemanager") + if capman: + capman.suspend_global_capture(in_=True) + tw = _pytest.config.create_terminal_writer(cls._config) + tw.line() + tw.sep(">", "PDB set_trace (IO-capturing turned off)") + cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config) + if set_break: + cls._pdb_cls().set_trace(frame) + + +class PdbInvoke(object): + def pytest_exception_interact(self, node, call, report): + capman = node.config.pluginmanager.getplugin("capturemanager") + if capman: + out, err = capman.suspend_global_capture(in_=True) + sys.stdout.write(out) + sys.stdout.write(err) + _enter_pdb(node, call.excinfo, report) + + def pytest_internalerror(self, excrepr, excinfo): + for line in str(excrepr).split("\n"): + sys.stderr.write("INTERNALERROR> %s\n" % line) + sys.stderr.flush() + tb = _postmortem_traceback(excinfo) + post_mortem(tb) + + +class PdbTrace(object): + @hookimpl(hookwrapper=True) + def pytest_pyfunc_call(self, pyfuncitem): + _test_pytest_function(pyfuncitem) + yield + + +def _test_pytest_function(pyfuncitem): + pytestPDB.set_trace(set_break=False) + testfunction = pyfuncitem.obj + pyfuncitem.obj = pdb.runcall + if pyfuncitem._isyieldedfunction(): + arg_list = list(pyfuncitem._args) + arg_list.insert(0, testfunction) + pyfuncitem._args = tuple(arg_list) + else: + if "func" in pyfuncitem._fixtureinfo.argnames: + raise ValueError("--trace can't be used with a fixture named func!") + pyfuncitem.funcargs["func"] = testfunction + new_list = list(pyfuncitem._fixtureinfo.argnames) + new_list.append("func") + pyfuncitem._fixtureinfo.argnames = tuple(new_list) + + +def _enter_pdb(node, excinfo, rep): + # XXX we re-use the TerminalReporter's terminalwriter + # because this seems to avoid some encoding related troubles + # for not completely clear reasons. + tw = node.config.pluginmanager.getplugin("terminalreporter")._tw + tw.line() + + showcapture = node.config.option.showcapture + + for sectionname, content in ( + ("stdout", rep.capstdout), + ("stderr", rep.capstderr), + ("log", rep.caplog), + ): + if showcapture in (sectionname, "all") and content: + tw.sep(">", "captured " + sectionname) + if content[-1:] == "\n": + content = content[:-1] + tw.line(content) + + tw.sep(">", "traceback") + rep.toterminal(tw) + tw.sep(">", "entering PDB") + tb = _postmortem_traceback(excinfo) + post_mortem(tb) + rep._pdbshown = True + return rep + + +def _postmortem_traceback(excinfo): + if isinstance(excinfo.value, UnexpectedException): + # A doctest.UnexpectedException is not useful for post_mortem. + # Use the underlying exception instead: + return excinfo.value.exc_info[2] + else: + return excinfo._excinfo[2] + + +def _find_last_non_hidden_frame(stack): + i = max(0, len(stack) - 1) + while i and stack[i][0].f_locals.get("__tracebackhide__", False): + i -= 1 + return i + + +def post_mortem(t): + class Pdb(pytestPDB._pdb_cls): + def get_stack(self, f, t): + stack, i = pdb.Pdb.get_stack(self, f, t) + if f is None: + i = _find_last_non_hidden_frame(stack) + return stack, i + + p = Pdb() + p.reset() + p.interaction(None, t) diff --git a/Lib/site-packages/_pytest/deprecated.py b/Lib/site-packages/_pytest/deprecated.py new file mode 100644 index 0000000..20f1cc2 --- /dev/null +++ b/Lib/site-packages/_pytest/deprecated.py @@ -0,0 +1,77 @@ +""" +This module contains deprecation messages and bits of code used elsewhere in the codebase +that is planned to be removed in the next pytest release. + +Keeping it in a central location makes it easy to track what is deprecated and should +be removed when the time comes. +""" +from __future__ import absolute_import, division, print_function + + +class RemovedInPytest4Warning(DeprecationWarning): + """warning class for features removed in pytest 4.0""" + + +MAIN_STR_ARGS = "passing a string to pytest.main() is deprecated, " "pass a list of arguments instead." + +YIELD_TESTS = "yield tests are deprecated, and scheduled to be removed in pytest 4.0" + +FUNCARG_PREFIX = ( + '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' + "and scheduled to be removed in pytest 4.0. " + "Please remove the prefix and use the @pytest.fixture decorator instead." +) + +FIXTURE_FUNCTION_CALL = ( + "Fixture {name} called directly. Fixtures are not meant to be called directly, " + "are created automatically when test functions request them as parameters. " + "See https://docs.pytest.org/en/latest/fixture.html for more information." +) + +CFG_PYTEST_SECTION = ( + "[pytest] section in {filename} files is deprecated, use [tool:pytest] instead." +) + +GETFUNCARGVALUE = "use of getfuncargvalue is deprecated, use getfixturevalue" + +RESULT_LOG = ( + "--result-log is deprecated and scheduled for removal in pytest 4.0.\n" + "See https://docs.pytest.org/en/latest/usage.html#creating-resultlog-format-files for more information." +) + +MARK_INFO_ATTRIBUTE = RemovedInPytest4Warning( + "MarkInfo objects are deprecated as they contain merged marks which are hard to deal with correctly.\n" + "Please use node.get_closest_marker(name) or node.iter_markers(name).\n" + "Docs: https://docs.pytest.org/en/latest/mark.html#updating-code" +) + +MARK_PARAMETERSET_UNPACKING = RemovedInPytest4Warning( + "Applying marks directly to parameters is deprecated," + " please use pytest.param(..., marks=...) instead.\n" + "For more details, see: https://docs.pytest.org/en/latest/parametrize.html" +) + +RECORD_XML_PROPERTY = ( + 'Fixture renamed from "record_xml_property" to "record_property" as user ' + "properties are now available to all reporters.\n" + '"record_xml_property" is now deprecated.' +) + +COLLECTOR_MAKEITEM = RemovedInPytest4Warning( + "pycollector makeitem was removed " "as it is an accidentially leaked internal api" +) + +METAFUNC_ADD_CALL = ( + "Metafunc.addcall is deprecated and scheduled to be removed in pytest 4.0.\n" + "Please use Metafunc.parametrize instead." +) + +PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = RemovedInPytest4Warning( + "Defining pytest_plugins in a non-top-level conftest is deprecated, " + "because it affects the entire directory tree in a non-explicit way.\n" + "Please move it to the top level conftest file instead." +) + +PYTEST_NAMESPACE = RemovedInPytest4Warning( + "pytest_namespace is deprecated and will be removed soon" +) diff --git a/Lib/site-packages/_pytest/doctest.py b/Lib/site-packages/_pytest/doctest.py new file mode 100644 index 0000000..57d3367 --- /dev/null +++ b/Lib/site-packages/_pytest/doctest.py @@ -0,0 +1,511 @@ +""" discover and run doctests in modules and test files.""" +from __future__ import absolute_import, division, print_function + +import traceback +import sys +import platform + +import pytest +from _pytest._code.code import ExceptionInfo, ReprFileLocation, TerminalRepr +from _pytest.fixtures import FixtureRequest + + +DOCTEST_REPORT_CHOICE_NONE = "none" +DOCTEST_REPORT_CHOICE_CDIFF = "cdiff" +DOCTEST_REPORT_CHOICE_NDIFF = "ndiff" +DOCTEST_REPORT_CHOICE_UDIFF = "udiff" +DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE = "only_first_failure" + +DOCTEST_REPORT_CHOICES = ( + DOCTEST_REPORT_CHOICE_NONE, + DOCTEST_REPORT_CHOICE_CDIFF, + DOCTEST_REPORT_CHOICE_NDIFF, + DOCTEST_REPORT_CHOICE_UDIFF, + DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE, +) + +# Lazy definition of runner class +RUNNER_CLASS = None + + +def pytest_addoption(parser): + parser.addini( + "doctest_optionflags", + "option flags for doctests", + type="args", + default=["ELLIPSIS"], + ) + parser.addini( + "doctest_encoding", "encoding used for doctest files", default="utf-8" + ) + group = parser.getgroup("collect") + group.addoption( + "--doctest-modules", + action="store_true", + default=False, + help="run doctests in all .py modules", + dest="doctestmodules", + ) + group.addoption( + "--doctest-report", + type=str.lower, + default="udiff", + help="choose another output format for diffs on doctest failure", + choices=DOCTEST_REPORT_CHOICES, + dest="doctestreport", + ) + group.addoption( + "--doctest-glob", + action="append", + default=[], + metavar="pat", + help="doctests file matching pattern, default: test*.txt", + dest="doctestglob", + ) + group.addoption( + "--doctest-ignore-import-errors", + action="store_true", + default=False, + help="ignore doctest ImportErrors", + dest="doctest_ignore_import_errors", + ) + group.addoption( + "--doctest-continue-on-failure", + action="store_true", + default=False, + help="for a given doctest, continue to run after the first failure", + dest="doctest_continue_on_failure", + ) + + +def pytest_collect_file(path, parent): + config = parent.config + if path.ext == ".py": + if config.option.doctestmodules and not _is_setup_py(config, path, parent): + return DoctestModule(path, parent) + elif _is_doctest(config, path, parent): + return DoctestTextfile(path, parent) + + +def _is_setup_py(config, path, parent): + if path.basename != "setup.py": + return False + contents = path.read() + return "setuptools" in contents or "distutils" in contents + + +def _is_doctest(config, path, parent): + if path.ext in (".txt", ".rst") and parent.session.isinitpath(path): + return True + globs = config.getoption("doctestglob") or ["test*.txt"] + for glob in globs: + if path.check(fnmatch=glob): + return True + return False + + +class ReprFailDoctest(TerminalRepr): + def __init__(self, reprlocation_lines): + # List of (reprlocation, lines) tuples + self.reprlocation_lines = reprlocation_lines + + def toterminal(self, tw): + for reprlocation, lines in self.reprlocation_lines: + for line in lines: + tw.line(line) + reprlocation.toterminal(tw) + + +class MultipleDoctestFailures(Exception): + def __init__(self, failures): + super(MultipleDoctestFailures, self).__init__() + self.failures = failures + + +def _init_runner_class(): + import doctest + + class PytestDoctestRunner(doctest.DebugRunner): + """ + Runner to collect failures. Note that the out variable in this case is + a list instead of a stdout-like object + """ + + def __init__( + self, checker=None, verbose=None, optionflags=0, continue_on_failure=True + ): + doctest.DebugRunner.__init__( + self, checker=checker, verbose=verbose, optionflags=optionflags + ) + self.continue_on_failure = continue_on_failure + + def report_failure(self, out, test, example, got): + failure = doctest.DocTestFailure(test, example, got) + if self.continue_on_failure: + out.append(failure) + else: + raise failure + + def report_unexpected_exception(self, out, test, example, exc_info): + failure = doctest.UnexpectedException(test, example, exc_info) + if self.continue_on_failure: + out.append(failure) + else: + raise failure + + return PytestDoctestRunner + + +def _get_runner(checker=None, verbose=None, optionflags=0, continue_on_failure=True): + # We need this in order to do a lazy import on doctest + global RUNNER_CLASS + if RUNNER_CLASS is None: + RUNNER_CLASS = _init_runner_class() + return RUNNER_CLASS( + checker=checker, + verbose=verbose, + optionflags=optionflags, + continue_on_failure=continue_on_failure, + ) + + +class DoctestItem(pytest.Item): + def __init__(self, name, parent, runner=None, dtest=None): + super(DoctestItem, self).__init__(name, parent) + self.runner = runner + self.dtest = dtest + self.obj = None + self.fixture_request = None + + def setup(self): + if self.dtest is not None: + self.fixture_request = _setup_fixtures(self) + globs = dict(getfixture=self.fixture_request.getfixturevalue) + for name, value in self.fixture_request.getfixturevalue( + "doctest_namespace" + ).items(): + globs[name] = value + self.dtest.globs.update(globs) + + def runtest(self): + _check_all_skipped(self.dtest) + self._disable_output_capturing_for_darwin() + failures = [] + self.runner.run(self.dtest, out=failures) + if failures: + raise MultipleDoctestFailures(failures) + + def _disable_output_capturing_for_darwin(self): + """ + Disable output capturing. Otherwise, stdout is lost to doctest (#985) + """ + if platform.system() != "Darwin": + return + capman = self.config.pluginmanager.getplugin("capturemanager") + if capman: + out, err = capman.suspend_global_capture(in_=True) + sys.stdout.write(out) + sys.stderr.write(err) + + def repr_failure(self, excinfo): + import doctest + + failures = None + if excinfo.errisinstance((doctest.DocTestFailure, doctest.UnexpectedException)): + failures = [excinfo.value] + elif excinfo.errisinstance(MultipleDoctestFailures): + failures = excinfo.value.failures + + if failures is not None: + reprlocation_lines = [] + for failure in failures: + example = failure.example + test = failure.test + filename = test.filename + if test.lineno is None: + lineno = None + else: + lineno = test.lineno + example.lineno + 1 + message = type(failure).__name__ + reprlocation = ReprFileLocation(filename, lineno, message) + checker = _get_checker() + report_choice = _get_report_choice( + self.config.getoption("doctestreport") + ) + if lineno is not None: + lines = failure.test.docstring.splitlines(False) + # add line numbers to the left of the error message + lines = [ + "%03d %s" % (i + test.lineno + 1, x) + for (i, x) in enumerate(lines) + ] + # trim docstring error lines to 10 + lines = lines[max(example.lineno - 9, 0) : example.lineno + 1] + else: + lines = [ + "EXAMPLE LOCATION UNKNOWN, not showing all tests of that example" + ] + indent = ">>>" + for line in example.source.splitlines(): + lines.append("??? %s %s" % (indent, line)) + indent = "..." + if isinstance(failure, doctest.DocTestFailure): + lines += checker.output_difference( + example, failure.got, report_choice + ).split("\n") + else: + inner_excinfo = ExceptionInfo(failure.exc_info) + lines += ["UNEXPECTED EXCEPTION: %s" % repr(inner_excinfo.value)] + lines += traceback.format_exception(*failure.exc_info) + reprlocation_lines.append((reprlocation, lines)) + return ReprFailDoctest(reprlocation_lines) + else: + return super(DoctestItem, self).repr_failure(excinfo) + + def reportinfo(self): + return self.fspath, self.dtest.lineno, "[doctest] %s" % self.name + + +def _get_flag_lookup(): + import doctest + + return dict( + DONT_ACCEPT_TRUE_FOR_1=doctest.DONT_ACCEPT_TRUE_FOR_1, + DONT_ACCEPT_BLANKLINE=doctest.DONT_ACCEPT_BLANKLINE, + NORMALIZE_WHITESPACE=doctest.NORMALIZE_WHITESPACE, + ELLIPSIS=doctest.ELLIPSIS, + IGNORE_EXCEPTION_DETAIL=doctest.IGNORE_EXCEPTION_DETAIL, + COMPARISON_FLAGS=doctest.COMPARISON_FLAGS, + ALLOW_UNICODE=_get_allow_unicode_flag(), + ALLOW_BYTES=_get_allow_bytes_flag(), + ) + + +def get_optionflags(parent): + optionflags_str = parent.config.getini("doctest_optionflags") + flag_lookup_table = _get_flag_lookup() + flag_acc = 0 + for flag in optionflags_str: + flag_acc |= flag_lookup_table[flag] + return flag_acc + + +def _get_continue_on_failure(config): + continue_on_failure = config.getvalue("doctest_continue_on_failure") + if continue_on_failure: + # We need to turn off this if we use pdb since we should stop at + # the first failure + if config.getvalue("usepdb"): + continue_on_failure = False + return continue_on_failure + + +class DoctestTextfile(pytest.Module): + obj = None + + def collect(self): + import doctest + + # inspired by doctest.testfile; ideally we would use it directly, + # but it doesn't support passing a custom checker + encoding = self.config.getini("doctest_encoding") + text = self.fspath.read_text(encoding) + filename = str(self.fspath) + name = self.fspath.basename + globs = {"__name__": "__main__"} + + optionflags = get_optionflags(self) + + runner = _get_runner( + verbose=0, + optionflags=optionflags, + checker=_get_checker(), + continue_on_failure=_get_continue_on_failure(self.config), + ) + _fix_spoof_python2(runner, encoding) + + parser = doctest.DocTestParser() + test = parser.get_doctest(text, globs, name, filename, 0) + if test.examples: + yield DoctestItem(test.name, self, runner, test) + + +def _check_all_skipped(test): + """raises pytest.skip() if all examples in the given DocTest have the SKIP + option set. + """ + import doctest + + all_skipped = all(x.options.get(doctest.SKIP, False) for x in test.examples) + if all_skipped: + pytest.skip("all tests skipped by +SKIP option") + + +class DoctestModule(pytest.Module): + def collect(self): + import doctest + + if self.fspath.basename == "conftest.py": + module = self.config.pluginmanager._importconftest(self.fspath) + else: + try: + module = self.fspath.pyimport() + except ImportError: + if self.config.getvalue("doctest_ignore_import_errors"): + pytest.skip("unable to import module %r" % self.fspath) + else: + raise + # uses internal doctest module parsing mechanism + finder = doctest.DocTestFinder() + optionflags = get_optionflags(self) + runner = _get_runner( + verbose=0, + optionflags=optionflags, + checker=_get_checker(), + continue_on_failure=_get_continue_on_failure(self.config), + ) + + for test in finder.find(module, module.__name__): + if test.examples: # skip empty doctests + yield DoctestItem(test.name, self, runner, test) + + +def _setup_fixtures(doctest_item): + """ + Used by DoctestTextfile and DoctestItem to setup fixture information. + """ + + def func(): + pass + + doctest_item.funcargs = {} + fm = doctest_item.session._fixturemanager + doctest_item._fixtureinfo = fm.getfixtureinfo( + node=doctest_item, func=func, cls=None, funcargs=False + ) + fixture_request = FixtureRequest(doctest_item) + fixture_request._fillfixtures() + return fixture_request + + +def _get_checker(): + """ + Returns a doctest.OutputChecker subclass that takes in account the + ALLOW_UNICODE option to ignore u'' prefixes in strings and ALLOW_BYTES + to strip b'' prefixes. + Useful when the same doctest should run in Python 2 and Python 3. + + An inner class is used to avoid importing "doctest" at the module + level. + """ + if hasattr(_get_checker, "LiteralsOutputChecker"): + return _get_checker.LiteralsOutputChecker() + + import doctest + import re + + class LiteralsOutputChecker(doctest.OutputChecker): + """ + Copied from doctest_nose_plugin.py from the nltk project: + https://github.com/nltk/nltk + + Further extended to also support byte literals. + """ + + _unicode_literal_re = re.compile(r"(\W|^)[uU]([rR]?[\'\"])", re.UNICODE) + _bytes_literal_re = re.compile(r"(\W|^)[bB]([rR]?[\'\"])", re.UNICODE) + + def check_output(self, want, got, optionflags): + res = doctest.OutputChecker.check_output(self, want, got, optionflags) + if res: + return True + + allow_unicode = optionflags & _get_allow_unicode_flag() + allow_bytes = optionflags & _get_allow_bytes_flag() + if not allow_unicode and not allow_bytes: + return False + + else: # pragma: no cover + + def remove_prefixes(regex, txt): + return re.sub(regex, r"\1\2", txt) + + if allow_unicode: + want = remove_prefixes(self._unicode_literal_re, want) + got = remove_prefixes(self._unicode_literal_re, got) + if allow_bytes: + want = remove_prefixes(self._bytes_literal_re, want) + got = remove_prefixes(self._bytes_literal_re, got) + res = doctest.OutputChecker.check_output(self, want, got, optionflags) + return res + + _get_checker.LiteralsOutputChecker = LiteralsOutputChecker + return _get_checker.LiteralsOutputChecker() + + +def _get_allow_unicode_flag(): + """ + Registers and returns the ALLOW_UNICODE flag. + """ + import doctest + + return doctest.register_optionflag("ALLOW_UNICODE") + + +def _get_allow_bytes_flag(): + """ + Registers and returns the ALLOW_BYTES flag. + """ + import doctest + + return doctest.register_optionflag("ALLOW_BYTES") + + +def _get_report_choice(key): + """ + This function returns the actual `doctest` module flag value, we want to do it as late as possible to avoid + importing `doctest` and all its dependencies when parsing options, as it adds overhead and breaks tests. + """ + import doctest + + return { + DOCTEST_REPORT_CHOICE_UDIFF: doctest.REPORT_UDIFF, + DOCTEST_REPORT_CHOICE_CDIFF: doctest.REPORT_CDIFF, + DOCTEST_REPORT_CHOICE_NDIFF: doctest.REPORT_NDIFF, + DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE: doctest.REPORT_ONLY_FIRST_FAILURE, + DOCTEST_REPORT_CHOICE_NONE: 0, + }[key] + + +def _fix_spoof_python2(runner, encoding): + """ + Installs a "SpoofOut" into the given DebugRunner so it properly deals with unicode output. This + should patch only doctests for text files because they don't have a way to declare their + encoding. Doctests in docstrings from Python modules don't have the same problem given that + Python already decoded the strings. + + This fixes the problem related in issue #2434. + """ + from _pytest.compat import _PY2 + + if not _PY2: + return + + from doctest import _SpoofOut + + class UnicodeSpoof(_SpoofOut): + def getvalue(self): + result = _SpoofOut.getvalue(self) + if encoding and isinstance(result, bytes): + result = result.decode(encoding) + return result + + runner._fakeout = UnicodeSpoof() + + +@pytest.fixture(scope="session") +def doctest_namespace(): + """ + Fixture that returns a :py:class:`dict` that will be injected into the namespace of doctests. + """ + return dict() diff --git a/Lib/site-packages/_pytest/experiments.py b/Lib/site-packages/_pytest/experiments.py new file mode 100644 index 0000000..aa6b664 --- /dev/null +++ b/Lib/site-packages/_pytest/experiments.py @@ -0,0 +1,13 @@ +class PytestExerimentalApiWarning(FutureWarning): + "warning category used to denote experiments in pytest" + + @classmethod + def simple(cls, apiname): + return cls( + "{apiname} is an experimental api that may change over time".format( + apiname=apiname + ) + ) + + +PYTESTER_COPY_EXAMPLE = PytestExerimentalApiWarning.simple("testdir.copy_example") diff --git a/Lib/site-packages/_pytest/fixtures.py b/Lib/site-packages/_pytest/fixtures.py new file mode 100644 index 0000000..818c5b8 --- /dev/null +++ b/Lib/site-packages/_pytest/fixtures.py @@ -0,0 +1,1350 @@ +from __future__ import absolute_import, division, print_function + +import functools +import inspect +import os +import sys +import warnings +from collections import OrderedDict, deque, defaultdict + +import six +from more_itertools import flatten + +import attr +import py +from py._code.code import FormattedExcinfo + +import _pytest +from _pytest import nodes +from _pytest._code.code import TerminalRepr +from _pytest.compat import ( + NOTSET, + exc_clear, + _format_args, + getfslineno, + get_real_func, + is_generator, + isclass, + getimfunc, + getlocation, + getfuncargnames, + safe_getattr, + FuncargnamesCompatAttr, + get_real_method, +) +from _pytest.deprecated import FIXTURE_FUNCTION_CALL, RemovedInPytest4Warning +from _pytest.outcomes import fail, TEST_OUTCOME + +FIXTURE_MSG = 'fixtures cannot have "pytest_funcarg__" prefix and be decorated with @pytest.fixture:\n{}' + + +@attr.s(frozen=True) +class PseudoFixtureDef(object): + cached_result = attr.ib() + scope = attr.ib() + + +def pytest_sessionstart(session): + import _pytest.python + import _pytest.nodes + + scopename2class.update( + { + "package": _pytest.python.Package, + "class": _pytest.python.Class, + "module": _pytest.python.Module, + "function": _pytest.nodes.Item, + "session": _pytest.main.Session, + } + ) + session._fixturemanager = FixtureManager(session) + + +scopename2class = {} + + +scope2props = dict(session=()) +scope2props["package"] = ("fspath",) +scope2props["module"] = ("fspath", "module") +scope2props["class"] = scope2props["module"] + ("cls",) +scope2props["instance"] = scope2props["class"] + ("instance",) +scope2props["function"] = scope2props["instance"] + ("function", "keywords") + + +def scopeproperty(name=None, doc=None): + def decoratescope(func): + scopename = name or func.__name__ + + def provide(self): + if func.__name__ in scope2props[self.scope]: + return func(self) + raise AttributeError( + "%s not available in %s-scoped context" % (scopename, self.scope) + ) + + return property(provide, None, None, func.__doc__) + + return decoratescope + + +def get_scope_package(node, fixturedef): + import pytest + + cls = pytest.Package + current = node + fixture_package_name = os.path.join(fixturedef.baseid, "__init__.py") + while current and ( + type(current) is not cls or fixture_package_name != current.nodeid + ): + current = current.parent + if current is None: + return node.session + return current + + +def get_scope_node(node, scope): + cls = scopename2class.get(scope) + if cls is None: + raise ValueError("unknown scope") + return node.getparent(cls) + + +def add_funcarg_pseudo_fixture_def(collector, metafunc, fixturemanager): + # this function will transform all collected calls to a functions + # if they use direct funcargs (i.e. direct parametrization) + # because we want later test execution to be able to rely on + # an existing FixtureDef structure for all arguments. + # XXX we can probably avoid this algorithm if we modify CallSpec2 + # to directly care for creating the fixturedefs within its methods. + if not metafunc._calls[0].funcargs: + return # this function call does not have direct parametrization + # collect funcargs of all callspecs into a list of values + arg2params = {} + arg2scope = {} + for callspec in metafunc._calls: + for argname, argvalue in callspec.funcargs.items(): + assert argname not in callspec.params + callspec.params[argname] = argvalue + arg2params_list = arg2params.setdefault(argname, []) + callspec.indices[argname] = len(arg2params_list) + arg2params_list.append(argvalue) + if argname not in arg2scope: + scopenum = callspec._arg2scopenum.get(argname, scopenum_function) + arg2scope[argname] = scopes[scopenum] + callspec.funcargs.clear() + + # register artificial FixtureDef's so that later at test execution + # time we can rely on a proper FixtureDef to exist for fixture setup. + arg2fixturedefs = metafunc._arg2fixturedefs + for argname, valuelist in arg2params.items(): + # if we have a scope that is higher than function we need + # to make sure we only ever create an according fixturedef on + # a per-scope basis. We thus store and cache the fixturedef on the + # node related to the scope. + scope = arg2scope[argname] + node = None + if scope != "function": + node = get_scope_node(collector, scope) + if node is None: + assert scope == "class" and isinstance(collector, _pytest.python.Module) + # use module-level collector for class-scope (for now) + node = collector + if node and argname in node._name2pseudofixturedef: + arg2fixturedefs[argname] = [node._name2pseudofixturedef[argname]] + else: + fixturedef = FixtureDef( + fixturemanager, + "", + argname, + get_direct_param_fixture_func, + arg2scope[argname], + valuelist, + False, + False, + ) + arg2fixturedefs[argname] = [fixturedef] + if node is not None: + node._name2pseudofixturedef[argname] = fixturedef + + +def getfixturemarker(obj): + """ return fixturemarker or None if it doesn't exist or raised + exceptions.""" + try: + return getattr(obj, "_pytestfixturefunction", None) + except TEST_OUTCOME: + # some objects raise errors like request (from flask import request) + # we don't expect them to be fixture functions + return None + + +def get_parametrized_fixture_keys(item, scopenum): + """ return list of keys for all parametrized arguments which match + the specified scope. """ + assert scopenum < scopenum_function # function + try: + cs = item.callspec + except AttributeError: + pass + else: + # cs.indices.items() is random order of argnames. Need to + # sort this so that different calls to + # get_parametrized_fixture_keys will be deterministic. + for argname, param_index in sorted(cs.indices.items()): + if cs._arg2scopenum[argname] != scopenum: + continue + if scopenum == 0: # session + key = (argname, param_index) + elif scopenum == 1: # package + key = (argname, param_index, item.fspath.dirpath()) + elif scopenum == 2: # module + key = (argname, param_index, item.fspath) + elif scopenum == 3: # class + key = (argname, param_index, item.fspath, item.cls) + yield key + + +# algorithm for sorting on a per-parametrized resource setup basis +# it is called for scopenum==0 (session) first and performs sorting +# down to the lower scopes such as to minimize number of "high scope" +# setups and teardowns + + +def reorder_items(items): + argkeys_cache = {} + items_by_argkey = {} + for scopenum in range(0, scopenum_function): + argkeys_cache[scopenum] = d = {} + items_by_argkey[scopenum] = item_d = defaultdict(deque) + for item in items: + keys = OrderedDict.fromkeys(get_parametrized_fixture_keys(item, scopenum)) + if keys: + d[item] = keys + for key in keys: + item_d[key].append(item) + items = OrderedDict.fromkeys(items) + return list(reorder_items_atscope(items, argkeys_cache, items_by_argkey, 0)) + + +def fix_cache_order(item, argkeys_cache, items_by_argkey): + for scopenum in range(0, scopenum_function): + for key in argkeys_cache[scopenum].get(item, []): + items_by_argkey[scopenum][key].appendleft(item) + + +def reorder_items_atscope(items, argkeys_cache, items_by_argkey, scopenum): + if scopenum >= scopenum_function or len(items) < 3: + return items + ignore = set() + items_deque = deque(items) + items_done = OrderedDict() + scoped_items_by_argkey = items_by_argkey[scopenum] + scoped_argkeys_cache = argkeys_cache[scopenum] + while items_deque: + no_argkey_group = OrderedDict() + slicing_argkey = None + while items_deque: + item = items_deque.popleft() + if item in items_done or item in no_argkey_group: + continue + argkeys = OrderedDict.fromkeys( + k for k in scoped_argkeys_cache.get(item, []) if k not in ignore + ) + if not argkeys: + no_argkey_group[item] = None + else: + slicing_argkey, _ = argkeys.popitem() + # we don't have to remove relevant items from later in the deque because they'll just be ignored + matching_items = [ + i for i in scoped_items_by_argkey[slicing_argkey] if i in items + ] + for i in reversed(matching_items): + fix_cache_order(i, argkeys_cache, items_by_argkey) + items_deque.appendleft(i) + break + if no_argkey_group: + no_argkey_group = reorder_items_atscope( + no_argkey_group, argkeys_cache, items_by_argkey, scopenum + 1 + ) + for item in no_argkey_group: + items_done[item] = None + ignore.add(slicing_argkey) + return items_done + + +def fillfixtures(function): + """ fill missing funcargs for a test function. """ + try: + request = function._request + except AttributeError: + # XXX this special code path is only expected to execute + # with the oejskit plugin. It uses classes with funcargs + # and we thus have to work a bit to allow this. + fm = function.session._fixturemanager + fi = fm.getfixtureinfo(function.parent, function.obj, None) + function._fixtureinfo = fi + request = function._request = FixtureRequest(function) + request._fillfixtures() + # prune out funcargs for jstests + newfuncargs = {} + for name in fi.argnames: + newfuncargs[name] = function.funcargs[name] + function.funcargs = newfuncargs + else: + request._fillfixtures() + + +def get_direct_param_fixture_func(request): + return request.param + + +@attr.s(slots=True) +class FuncFixtureInfo(object): + # original function argument names + argnames = attr.ib(type=tuple) + # argnames that function immediately requires. These include argnames + + # fixture names specified via usefixtures and via autouse=True in fixture + # definitions. + initialnames = attr.ib(type=tuple) + names_closure = attr.ib(type="List[str]") + name2fixturedefs = attr.ib(type="List[str, List[FixtureDef]]") + + def prune_dependency_tree(self): + """Recompute names_closure from initialnames and name2fixturedefs + + Can only reduce names_closure, which means that the new closure will + always be a subset of the old one. The order is preserved. + + This method is needed because direct parametrization may shadow some + of the fixtures that were included in the originally built dependency + tree. In this way the dependency tree can get pruned, and the closure + of argnames may get reduced. + """ + closure = set() + working_set = set(self.initialnames) + while working_set: + argname = working_set.pop() + # argname may be smth not included in the original names_closure, + # in which case we ignore it. This currently happens with pseudo + # FixtureDefs which wrap 'get_direct_param_fixture_func(request)'. + # So they introduce the new dependency 'request' which might have + # been missing in the original tree (closure). + if argname not in closure and argname in self.names_closure: + closure.add(argname) + if argname in self.name2fixturedefs: + working_set.update(self.name2fixturedefs[argname][-1].argnames) + + self.names_closure[:] = sorted(closure, key=self.names_closure.index) + + +class FixtureRequest(FuncargnamesCompatAttr): + """ A request for a fixture from a test or fixture function. + + A request object gives access to the requesting test context + and has an optional ``param`` attribute in case + the fixture is parametrized indirectly. + """ + + def __init__(self, pyfuncitem): + self._pyfuncitem = pyfuncitem + #: fixture for which this request is being performed + self.fixturename = None + #: Scope string, one of "function", "class", "module", "session" + self.scope = "function" + self._fixture_defs = {} # argname -> FixtureDef + fixtureinfo = pyfuncitem._fixtureinfo + self._arg2fixturedefs = fixtureinfo.name2fixturedefs.copy() + self._arg2index = {} + self._fixturemanager = pyfuncitem.session._fixturemanager + + @property + def fixturenames(self): + # backward incompatible note: now a readonly property + return list(self._pyfuncitem._fixtureinfo.names_closure) + + @property + def node(self): + """ underlying collection node (depends on current request scope)""" + return self._getscopeitem(self.scope) + + def _getnextfixturedef(self, argname): + fixturedefs = self._arg2fixturedefs.get(argname, None) + if fixturedefs is None: + # we arrive here because of a dynamic call to + # getfixturevalue(argname) usage which was naturally + # not known at parsing/collection time + parentid = self._pyfuncitem.parent.nodeid + fixturedefs = self._fixturemanager.getfixturedefs(argname, parentid) + self._arg2fixturedefs[argname] = fixturedefs + # fixturedefs list is immutable so we maintain a decreasing index + index = self._arg2index.get(argname, 0) - 1 + if fixturedefs is None or (-index > len(fixturedefs)): + raise FixtureLookupError(argname, self) + self._arg2index[argname] = index + return fixturedefs[index] + + @property + def config(self): + """ the pytest config object associated with this request. """ + return self._pyfuncitem.config + + @scopeproperty() + def function(self): + """ test function object if the request has a per-function scope. """ + return self._pyfuncitem.obj + + @scopeproperty("class") + def cls(self): + """ class (can be None) where the test function was collected. """ + clscol = self._pyfuncitem.getparent(_pytest.python.Class) + if clscol: + return clscol.obj + + @property + def instance(self): + """ instance (can be None) on which test function was collected. """ + # unittest support hack, see _pytest.unittest.TestCaseFunction + try: + return self._pyfuncitem._testcase + except AttributeError: + function = getattr(self, "function", None) + return getattr(function, "__self__", None) + + @scopeproperty() + def module(self): + """ python module object where the test function was collected. """ + return self._pyfuncitem.getparent(_pytest.python.Module).obj + + @scopeproperty() + def fspath(self): + """ the file system path of the test module which collected this test. """ + return self._pyfuncitem.fspath + + @property + def keywords(self): + """ keywords/markers dictionary for the underlying node. """ + return self.node.keywords + + @property + def session(self): + """ pytest session object. """ + return self._pyfuncitem.session + + def addfinalizer(self, finalizer): + """ add finalizer/teardown function to be called after the + last test within the requesting test context finished + execution. """ + # XXX usually this method is shadowed by fixturedef specific ones + self._addfinalizer(finalizer, scope=self.scope) + + def _addfinalizer(self, finalizer, scope): + colitem = self._getscopeitem(scope) + self._pyfuncitem.session._setupstate.addfinalizer( + finalizer=finalizer, colitem=colitem + ) + + def applymarker(self, marker): + """ Apply a marker to a single test function invocation. + This method is useful if you don't want to have a keyword/marker + on all function invocations. + + :arg marker: a :py:class:`_pytest.mark.MarkDecorator` object + created by a call to ``pytest.mark.NAME(...)``. + """ + self.node.add_marker(marker) + + def raiseerror(self, msg): + """ raise a FixtureLookupError with the given message. """ + raise self._fixturemanager.FixtureLookupError(None, self, msg) + + def _fillfixtures(self): + item = self._pyfuncitem + fixturenames = getattr(item, "fixturenames", self.fixturenames) + for argname in fixturenames: + if argname not in item.funcargs: + item.funcargs[argname] = self.getfixturevalue(argname) + + def cached_setup(self, setup, teardown=None, scope="module", extrakey=None): + """ (deprecated) Return a testing resource managed by ``setup`` & + ``teardown`` calls. ``scope`` and ``extrakey`` determine when the + ``teardown`` function will be called so that subsequent calls to + ``setup`` would recreate the resource. With pytest-2.3 you often + do not need ``cached_setup()`` as you can directly declare a scope + on a fixture function and register a finalizer through + ``request.addfinalizer()``. + + :arg teardown: function receiving a previously setup resource. + :arg setup: a no-argument function creating a resource. + :arg scope: a string value out of ``function``, ``class``, ``module`` + or ``session`` indicating the caching lifecycle of the resource. + :arg extrakey: added to internal caching key of (funcargname, scope). + """ + if not hasattr(self.config, "_setupcache"): + self.config._setupcache = {} # XXX weakref? + cachekey = (self.fixturename, self._getscopeitem(scope), extrakey) + cache = self.config._setupcache + try: + val = cache[cachekey] + except KeyError: + self._check_scope(self.fixturename, self.scope, scope) + val = setup() + cache[cachekey] = val + if teardown is not None: + + def finalizer(): + del cache[cachekey] + teardown(val) + + self._addfinalizer(finalizer, scope=scope) + return val + + def getfixturevalue(self, argname): + """ Dynamically run a named fixture function. + + Declaring fixtures via function argument is recommended where possible. + But if you can only decide whether to use another fixture at test + setup time, you may use this function to retrieve it inside a fixture + or test function body. + """ + return self._get_active_fixturedef(argname).cached_result[0] + + def getfuncargvalue(self, argname): + """ Deprecated, use getfixturevalue. """ + from _pytest import deprecated + + warnings.warn(deprecated.GETFUNCARGVALUE, DeprecationWarning, stacklevel=2) + return self.getfixturevalue(argname) + + def _get_active_fixturedef(self, argname): + try: + return self._fixture_defs[argname] + except KeyError: + try: + fixturedef = self._getnextfixturedef(argname) + except FixtureLookupError: + if argname == "request": + cached_result = (self, [0], None) + scope = "function" + return PseudoFixtureDef(cached_result, scope) + raise + # remove indent to prevent the python3 exception + # from leaking into the call + self._compute_fixture_value(fixturedef) + self._fixture_defs[argname] = fixturedef + return fixturedef + + def _get_fixturestack(self): + current = self + values = [] + while 1: + fixturedef = getattr(current, "_fixturedef", None) + if fixturedef is None: + values.reverse() + return values + values.append(fixturedef) + current = current._parent_request + + def _compute_fixture_value(self, fixturedef): + """ + Creates a SubRequest based on "self" and calls the execute method of the given fixturedef object. This will + force the FixtureDef object to throw away any previous results and compute a new fixture value, which + will be stored into the FixtureDef object itself. + + :param FixtureDef fixturedef: + """ + # prepare a subrequest object before calling fixture function + # (latter managed by fixturedef) + argname = fixturedef.argname + funcitem = self._pyfuncitem + scope = fixturedef.scope + try: + param = funcitem.callspec.getparam(argname) + except (AttributeError, ValueError): + param = NOTSET + param_index = 0 + if fixturedef.params is not None: + frame = inspect.stack()[3] + frameinfo = inspect.getframeinfo(frame[0]) + source_path = frameinfo.filename + source_lineno = frameinfo.lineno + source_path = py.path.local(source_path) + if source_path.relto(funcitem.config.rootdir): + source_path = source_path.relto(funcitem.config.rootdir) + msg = ( + "The requested fixture has no parameter defined for the " + "current test.\n\nRequested fixture '{}' defined in:\n{}" + "\n\nRequested here:\n{}:{}".format( + fixturedef.argname, + getlocation(fixturedef.func, funcitem.config.rootdir), + source_path, + source_lineno, + ) + ) + fail(msg) + else: + # indices might not be set if old-style metafunc.addcall() was used + param_index = funcitem.callspec.indices.get(argname, 0) + # if a parametrize invocation set a scope it will override + # the static scope defined with the fixture function + paramscopenum = funcitem.callspec._arg2scopenum.get(argname) + if paramscopenum is not None: + scope = scopes[paramscopenum] + + subrequest = SubRequest(self, scope, param, param_index, fixturedef) + + # check if a higher-level scoped fixture accesses a lower level one + subrequest._check_scope(argname, self.scope, scope) + + # clear sys.exc_info before invoking the fixture (python bug?) + # if its not explicitly cleared it will leak into the call + exc_clear() + try: + # call the fixture function + fixturedef.execute(request=subrequest) + finally: + # if fixture function failed it might have registered finalizers + self.session._setupstate.addfinalizer( + functools.partial(fixturedef.finish, request=subrequest), + subrequest.node, + ) + + def _check_scope(self, argname, invoking_scope, requested_scope): + if argname == "request": + return + if scopemismatch(invoking_scope, requested_scope): + # try to report something helpful + lines = self._factorytraceback() + fail( + "ScopeMismatch: You tried to access the %r scoped " + "fixture %r with a %r scoped request object, " + "involved factories\n%s" + % ((requested_scope, argname, invoking_scope, "\n".join(lines))), + pytrace=False, + ) + + def _factorytraceback(self): + lines = [] + for fixturedef in self._get_fixturestack(): + factory = fixturedef.func + fs, lineno = getfslineno(factory) + p = self._pyfuncitem.session.fspath.bestrelpath(fs) + args = _format_args(factory) + lines.append("%s:%d: def %s%s" % (p, lineno, factory.__name__, args)) + return lines + + def _getscopeitem(self, scope): + if scope == "function": + # this might also be a non-function Item despite its attribute name + return self._pyfuncitem + if scope == "package": + node = get_scope_package(self._pyfuncitem, self._fixturedef) + else: + node = get_scope_node(self._pyfuncitem, scope) + if node is None and scope == "class": + # fallback to function item itself + node = self._pyfuncitem + assert node, 'Could not obtain a node for scope "{}" for function {!r}'.format( + scope, self._pyfuncitem + ) + return node + + def __repr__(self): + return "" % (self.node) + + +class SubRequest(FixtureRequest): + """ a sub request for handling getting a fixture from a + test function/fixture. """ + + def __init__(self, request, scope, param, param_index, fixturedef): + self._parent_request = request + self.fixturename = fixturedef.argname + if param is not NOTSET: + self.param = param + self.param_index = param_index + self.scope = scope + self._fixturedef = fixturedef + self._pyfuncitem = request._pyfuncitem + self._fixture_defs = request._fixture_defs + self._arg2fixturedefs = request._arg2fixturedefs + self._arg2index = request._arg2index + self._fixturemanager = request._fixturemanager + + def __repr__(self): + return "" % (self.fixturename, self._pyfuncitem) + + def addfinalizer(self, finalizer): + self._fixturedef.addfinalizer(finalizer) + + +class ScopeMismatchError(Exception): + """ A fixture function tries to use a different fixture function which + which has a lower scope (e.g. a Session one calls a function one) + """ + + +scopes = "session package module class function".split() +scopenum_function = scopes.index("function") + + +def scopemismatch(currentscope, newscope): + return scopes.index(newscope) > scopes.index(currentscope) + + +def scope2index(scope, descr, where=None): + """Look up the index of ``scope`` and raise a descriptive value error + if not defined. + """ + try: + return scopes.index(scope) + except ValueError: + raise ValueError( + "{} {}has an unsupported scope value '{}'".format( + descr, "from {} ".format(where) if where else "", scope + ) + ) + + +class FixtureLookupError(LookupError): + """ could not return a requested Fixture (missing or invalid). """ + + def __init__(self, argname, request, msg=None): + self.argname = argname + self.request = request + self.fixturestack = request._get_fixturestack() + self.msg = msg + + def formatrepr(self): + tblines = [] + addline = tblines.append + stack = [self.request._pyfuncitem.obj] + stack.extend(map(lambda x: x.func, self.fixturestack)) + msg = self.msg + if msg is not None: + # the last fixture raise an error, let's present + # it at the requesting side + stack = stack[:-1] + for function in stack: + fspath, lineno = getfslineno(function) + try: + lines, _ = inspect.getsourcelines(get_real_func(function)) + except (IOError, IndexError, TypeError): + error_msg = "file %s, line %s: source code not available" + addline(error_msg % (fspath, lineno + 1)) + else: + addline("file %s, line %s" % (fspath, lineno + 1)) + for i, line in enumerate(lines): + line = line.rstrip() + addline(" " + line) + if line.lstrip().startswith("def"): + break + + if msg is None: + fm = self.request._fixturemanager + available = [] + parentid = self.request._pyfuncitem.parent.nodeid + for name, fixturedefs in fm._arg2fixturedefs.items(): + faclist = list(fm._matchfactories(fixturedefs, parentid)) + if faclist and name not in available: + available.append(name) + msg = "fixture %r not found" % (self.argname,) + msg += "\n available fixtures: %s" % (", ".join(sorted(available)),) + msg += "\n use 'pytest --fixtures [testpath]' for help on them." + + return FixtureLookupErrorRepr(fspath, lineno, tblines, msg, self.argname) + + +class FixtureLookupErrorRepr(TerminalRepr): + def __init__(self, filename, firstlineno, tblines, errorstring, argname): + self.tblines = tblines + self.errorstring = errorstring + self.filename = filename + self.firstlineno = firstlineno + self.argname = argname + + def toterminal(self, tw): + # tw.line("FixtureLookupError: %s" %(self.argname), red=True) + for tbline in self.tblines: + tw.line(tbline.rstrip()) + lines = self.errorstring.split("\n") + if lines: + tw.line( + "{} {}".format(FormattedExcinfo.fail_marker, lines[0].strip()), + red=True, + ) + for line in lines[1:]: + tw.line( + "{} {}".format(FormattedExcinfo.flow_marker, line.strip()), + red=True, + ) + tw.line() + tw.line("%s:%d" % (self.filename, self.firstlineno + 1)) + + +def fail_fixturefunc(fixturefunc, msg): + fs, lineno = getfslineno(fixturefunc) + location = "%s:%s" % (fs, lineno + 1) + source = _pytest._code.Source(fixturefunc) + fail(msg + ":\n\n" + str(source.indent()) + "\n" + location, pytrace=False) + + +def call_fixture_func(fixturefunc, request, kwargs): + yieldctx = is_generator(fixturefunc) + if yieldctx: + it = fixturefunc(**kwargs) + res = next(it) + finalizer = functools.partial(_teardown_yield_fixture, fixturefunc, it) + request.addfinalizer(finalizer) + else: + res = fixturefunc(**kwargs) + return res + + +def _teardown_yield_fixture(fixturefunc, it): + """Executes the teardown of a fixture function by advancing the iterator after the + yield and ensure the iteration ends (if not it means there is more than one yield in the function)""" + try: + next(it) + except StopIteration: + pass + else: + fail_fixturefunc( + fixturefunc, "yield_fixture function has more than one 'yield'" + ) + + +class FixtureDef(object): + """ A container for a factory definition. """ + + def __init__( + self, + fixturemanager, + baseid, + argname, + func, + scope, + params, + unittest=False, + ids=None, + ): + self._fixturemanager = fixturemanager + self.baseid = baseid or "" + self.has_location = baseid is not None + self.func = func + self.argname = argname + self.scope = scope + self.scopenum = scope2index( + scope or "function", descr="fixture {}".format(func.__name__), where=baseid + ) + self.params = params + self.argnames = getfuncargnames(func, is_method=unittest) + self.unittest = unittest + self.ids = ids + self._finalizers = [] + + def addfinalizer(self, finalizer): + self._finalizers.append(finalizer) + + def finish(self, request): + exceptions = [] + try: + while self._finalizers: + try: + func = self._finalizers.pop() + func() + except: # noqa + exceptions.append(sys.exc_info()) + if exceptions: + e = exceptions[0] + del exceptions # ensure we don't keep all frames alive because of the traceback + py.builtin._reraise(*e) + + finally: + hook = self._fixturemanager.session.gethookproxy(request.node.fspath) + hook.pytest_fixture_post_finalizer(fixturedef=self, request=request) + # even if finalization fails, we invalidate + # the cached fixture value and remove + # all finalizers because they may be bound methods which will + # keep instances alive + if hasattr(self, "cached_result"): + del self.cached_result + self._finalizers = [] + + def execute(self, request): + # get required arguments and register our own finish() + # with their finalization + for argname in self.argnames: + fixturedef = request._get_active_fixturedef(argname) + if argname != "request": + fixturedef.addfinalizer(functools.partial(self.finish, request=request)) + + my_cache_key = request.param_index + cached_result = getattr(self, "cached_result", None) + if cached_result is not None: + result, cache_key, err = cached_result + if my_cache_key == cache_key: + if err is not None: + py.builtin._reraise(*err) + else: + return result + # we have a previous but differently parametrized fixture instance + # so we need to tear it down before creating a new one + self.finish(request) + assert not hasattr(self, "cached_result") + + hook = self._fixturemanager.session.gethookproxy(request.node.fspath) + return hook.pytest_fixture_setup(fixturedef=self, request=request) + + def __repr__(self): + return "" % ( + self.argname, + self.scope, + self.baseid, + ) + + +def resolve_fixture_function(fixturedef, request): + """Gets the actual callable that can be called to obtain the fixture value, dealing with unittest-specific + instances and bound methods. + """ + fixturefunc = fixturedef.func + if fixturedef.unittest: + if request.instance is not None: + # bind the unbound method to the TestCase instance + fixturefunc = fixturedef.func.__get__(request.instance) + else: + # the fixture function needs to be bound to the actual + # request.instance so that code working with "fixturedef" behaves + # as expected. + if request.instance is not None: + fixturefunc = getimfunc(fixturedef.func) + if fixturefunc != fixturedef.func: + fixturefunc = fixturefunc.__get__(request.instance) + return fixturefunc + + +def pytest_fixture_setup(fixturedef, request): + """ Execution of fixture setup. """ + kwargs = {} + for argname in fixturedef.argnames: + fixdef = request._get_active_fixturedef(argname) + result, arg_cache_key, exc = fixdef.cached_result + request._check_scope(argname, request.scope, fixdef.scope) + kwargs[argname] = result + + fixturefunc = resolve_fixture_function(fixturedef, request) + my_cache_key = request.param_index + try: + result = call_fixture_func(fixturefunc, request, kwargs) + except TEST_OUTCOME: + fixturedef.cached_result = (None, my_cache_key, sys.exc_info()) + raise + fixturedef.cached_result = (result, my_cache_key, None) + return result + + +def _ensure_immutable_ids(ids): + if ids is None: + return + if callable(ids): + return ids + return tuple(ids) + + +def wrap_function_to_warning_if_called_directly(function, fixture_marker): + """Wrap the given fixture function so we can issue warnings about it being called directly, instead of + used as an argument in a test function. + + The warning is emitted only in Python 3, because I didn't find a reliable way to make the wrapper function + keep the original signature, and we probably will drop Python 2 in Pytest 4 anyway. + """ + is_yield_function = is_generator(function) + msg = FIXTURE_FUNCTION_CALL.format(name=fixture_marker.name or function.__name__) + warning = RemovedInPytest4Warning(msg) + + if is_yield_function: + + @functools.wraps(function) + def result(*args, **kwargs): + __tracebackhide__ = True + warnings.warn(warning, stacklevel=3) + for x in function(*args, **kwargs): + yield x + + else: + + @functools.wraps(function) + def result(*args, **kwargs): + __tracebackhide__ = True + warnings.warn(warning, stacklevel=3) + return function(*args, **kwargs) + + if six.PY2: + result.__wrapped__ = function + + return result + + +@attr.s(frozen=True) +class FixtureFunctionMarker(object): + scope = attr.ib() + params = attr.ib(converter=attr.converters.optional(tuple)) + autouse = attr.ib(default=False) + ids = attr.ib(default=None, converter=_ensure_immutable_ids) + name = attr.ib(default=None) + + def __call__(self, function): + if isclass(function): + raise ValueError("class fixtures not supported (may be in the future)") + + if getattr(function, "_pytestfixturefunction", False): + raise ValueError( + "fixture is being applied more than once to the same function" + ) + + function = wrap_function_to_warning_if_called_directly(function, self) + + function._pytestfixturefunction = self + return function + + +def fixture(scope="function", params=None, autouse=False, ids=None, name=None): + """Decorator to mark a fixture factory function. + + This decorator can be used, with or without parameters, to define a + fixture function. + + The name of the fixture function can later be referenced to cause its + invocation ahead of running tests: test + modules or classes can use the ``pytest.mark.usefixtures(fixturename)`` + marker. + + Test functions can directly use fixture names as input + arguments in which case the fixture instance returned from the fixture + function will be injected. + + Fixtures can provide their values to test functions using ``return`` or ``yield`` + statements. When using ``yield`` the code block after the ``yield`` statement is executed + as teardown code regardless of the test outcome, and must yield exactly once. + + :arg scope: the scope for which this fixture is shared, one of + ``"function"`` (default), ``"class"``, ``"module"``, + ``"package"`` or ``"session"``. + + ``"package"`` is considered **experimental** at this time. + + :arg params: an optional list of parameters which will cause multiple + invocations of the fixture function and all of the tests + using it. + + :arg autouse: if True, the fixture func is activated for all tests that + can see it. If False (the default) then an explicit + reference is needed to activate the fixture. + + :arg ids: list of string ids each corresponding to the params + so that they are part of the test id. If no ids are provided + they will be generated automatically from the params. + + :arg name: the name of the fixture. This defaults to the name of the + decorated function. If a fixture is used in the same module in + which it is defined, the function name of the fixture will be + shadowed by the function arg that requests the fixture; one way + to resolve this is to name the decorated function + ``fixture_`` and then use + ``@pytest.fixture(name='')``. + """ + if callable(scope) and params is None and autouse is False: + # direct decoration + return FixtureFunctionMarker("function", params, autouse, name=name)(scope) + if params is not None and not isinstance(params, (list, tuple)): + params = list(params) + return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name) + + +def yield_fixture(scope="function", params=None, autouse=False, ids=None, name=None): + """ (return a) decorator to mark a yield-fixture factory function. + + .. deprecated:: 3.0 + Use :py:func:`pytest.fixture` directly instead. + """ + return fixture(scope=scope, params=params, autouse=autouse, ids=ids, name=name) + + +defaultfuncargprefixmarker = fixture() + + +@fixture(scope="session") +def pytestconfig(request): + """Session-scoped fixture that returns the :class:`_pytest.config.Config` object. + + Example:: + + def test_foo(pytestconfig): + if pytestconfig.getoption("verbose"): + ... + + """ + return request.config + + +class FixtureManager(object): + """ + pytest fixtures definitions and information is stored and managed + from this class. + + During collection fm.parsefactories() is called multiple times to parse + fixture function definitions into FixtureDef objects and internal + data structures. + + During collection of test functions, metafunc-mechanics instantiate + a FuncFixtureInfo object which is cached per node/func-name. + This FuncFixtureInfo object is later retrieved by Function nodes + which themselves offer a fixturenames attribute. + + The FuncFixtureInfo object holds information about fixtures and FixtureDefs + relevant for a particular function. An initial list of fixtures is + assembled like this: + + - ini-defined usefixtures + - autouse-marked fixtures along the collection chain up from the function + - usefixtures markers at module/class/function level + - test function funcargs + + Subsequently the funcfixtureinfo.fixturenames attribute is computed + as the closure of the fixtures needed to setup the initial fixtures, + i. e. fixtures needed by fixture functions themselves are appended + to the fixturenames list. + + Upon the test-setup phases all fixturenames are instantiated, retrieved + by a lookup of their FuncFixtureInfo. + """ + + _argprefix = "pytest_funcarg__" + FixtureLookupError = FixtureLookupError + FixtureLookupErrorRepr = FixtureLookupErrorRepr + + def __init__(self, session): + self.session = session + self.config = session.config + self._arg2fixturedefs = {} + self._holderobjseen = set() + self._arg2finish = {} + self._nodeid_and_autousenames = [("", self.config.getini("usefixtures"))] + session.config.pluginmanager.register(self, "funcmanage") + + def getfixtureinfo(self, node, func, cls, funcargs=True): + if funcargs and not getattr(node, "nofuncargs", False): + argnames = getfuncargnames(func, cls=cls) + else: + argnames = () + usefixtures = flatten( + mark.args for mark in node.iter_markers(name="usefixtures") + ) + initialnames = tuple(usefixtures) + argnames + fm = node.session._fixturemanager + initialnames, names_closure, arg2fixturedefs = fm.getfixtureclosure( + initialnames, node + ) + return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs) + + def pytest_plugin_registered(self, plugin): + nodeid = None + try: + p = py.path.local(plugin.__file__) + except AttributeError: + pass + else: + # construct the base nodeid which is later used to check + # what fixtures are visible for particular tests (as denoted + # by their test id) + if p.basename.startswith("conftest.py"): + nodeid = p.dirpath().relto(self.config.rootdir) + if p.sep != nodes.SEP: + nodeid = nodeid.replace(p.sep, nodes.SEP) + self.parsefactories(plugin, nodeid) + + def _getautousenames(self, nodeid): + """ return a tuple of fixture names to be used. """ + autousenames = [] + for baseid, basenames in self._nodeid_and_autousenames: + if nodeid.startswith(baseid): + if baseid: + i = len(baseid) + nextchar = nodeid[i : i + 1] + if nextchar and nextchar not in ":/": + continue + autousenames.extend(basenames) + return autousenames + + def getfixtureclosure(self, fixturenames, parentnode): + # collect the closure of all fixtures , starting with the given + # fixturenames as the initial set. As we have to visit all + # factory definitions anyway, we also return an arg2fixturedefs + # mapping so that the caller can reuse it and does not have + # to re-discover fixturedefs again for each fixturename + # (discovering matching fixtures for a given name/node is expensive) + + parentid = parentnode.nodeid + fixturenames_closure = self._getautousenames(parentid) + + def merge(otherlist): + for arg in otherlist: + if arg not in fixturenames_closure: + fixturenames_closure.append(arg) + + merge(fixturenames) + + # at this point, fixturenames_closure contains what we call "initialnames", + # which is a set of fixturenames the function immediately requests. We + # need to return it as well, so save this. + initialnames = tuple(fixturenames_closure) + + arg2fixturedefs = {} + lastlen = -1 + while lastlen != len(fixturenames_closure): + lastlen = len(fixturenames_closure) + for argname in fixturenames_closure: + if argname in arg2fixturedefs: + continue + fixturedefs = self.getfixturedefs(argname, parentid) + if fixturedefs: + arg2fixturedefs[argname] = fixturedefs + merge(fixturedefs[-1].argnames) + + def sort_by_scope(arg_name): + try: + fixturedefs = arg2fixturedefs[arg_name] + except KeyError: + return scopes.index("function") + else: + return fixturedefs[-1].scopenum + + fixturenames_closure.sort(key=sort_by_scope) + return initialnames, fixturenames_closure, arg2fixturedefs + + def pytest_generate_tests(self, metafunc): + for argname in metafunc.fixturenames: + faclist = metafunc._arg2fixturedefs.get(argname) + if faclist: + fixturedef = faclist[-1] + if fixturedef.params is not None: + parametrize_func = getattr(metafunc.function, "parametrize", None) + if parametrize_func is not None: + parametrize_func = parametrize_func.combined + func_params = getattr(parametrize_func, "args", [[None]]) + func_kwargs = getattr(parametrize_func, "kwargs", {}) + # skip directly parametrized arguments + if "argnames" in func_kwargs: + argnames = parametrize_func.kwargs["argnames"] + else: + argnames = func_params[0] + if not isinstance(argnames, (tuple, list)): + argnames = [x.strip() for x in argnames.split(",") if x.strip()] + if argname not in func_params and argname not in argnames: + metafunc.parametrize( + argname, + fixturedef.params, + indirect=True, + scope=fixturedef.scope, + ids=fixturedef.ids, + ) + else: + continue # will raise FixtureLookupError at setup time + + def pytest_collection_modifyitems(self, items): + # separate parametrized setups + items[:] = reorder_items(items) + + def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False): + if nodeid is not NOTSET: + holderobj = node_or_obj + else: + holderobj = node_or_obj.obj + nodeid = node_or_obj.nodeid + if holderobj in self._holderobjseen: + return + self._holderobjseen.add(holderobj) + autousenames = [] + for name in dir(holderobj): + # The attribute can be an arbitrary descriptor, so the attribute + # access below can raise. safe_getatt() ignores such exceptions. + obj = safe_getattr(holderobj, name, None) + marker = getfixturemarker(obj) + # fixture functions have a pytest_funcarg__ prefix (pre-2.3 style) + # or are "@pytest.fixture" marked + if marker is None: + if not name.startswith(self._argprefix): + continue + if not callable(obj): + continue + marker = defaultfuncargprefixmarker + from _pytest import deprecated + + self.config.warn( + "C1", deprecated.FUNCARG_PREFIX.format(name=name), nodeid=nodeid + ) + name = name[len(self._argprefix) :] + elif not isinstance(marker, FixtureFunctionMarker): + # magic globals with __getattr__ might have got us a wrong + # fixture attribute + continue + else: + if marker.name: + name = marker.name + assert not name.startswith(self._argprefix), FIXTURE_MSG.format(name) + + # during fixture definition we wrap the original fixture function + # to issue a warning if called directly, so here we unwrap it in order to not emit the warning + # when pytest itself calls the fixture function + if six.PY2 and unittest: + # hack on Python 2 because of the unbound methods + obj = get_real_func(obj) + else: + obj = get_real_method(obj, holderobj) + + fixture_def = FixtureDef( + self, + nodeid, + name, + obj, + marker.scope, + marker.params, + unittest=unittest, + ids=marker.ids, + ) + + faclist = self._arg2fixturedefs.setdefault(name, []) + if fixture_def.has_location: + faclist.append(fixture_def) + else: + # fixturedefs with no location are at the front + # so this inserts the current fixturedef after the + # existing fixturedefs from external plugins but + # before the fixturedefs provided in conftests. + i = len([f for f in faclist if not f.has_location]) + faclist.insert(i, fixture_def) + if marker.autouse: + autousenames.append(name) + + if autousenames: + self._nodeid_and_autousenames.append((nodeid or "", autousenames)) + + def getfixturedefs(self, argname, nodeid): + """ + Gets a list of fixtures which are applicable to the given node id. + + :param str argname: name of the fixture to search for + :param str nodeid: full node id of the requesting test. + :return: list[FixtureDef] + """ + try: + fixturedefs = self._arg2fixturedefs[argname] + except KeyError: + return None + else: + return tuple(self._matchfactories(fixturedefs, nodeid)) + + def _matchfactories(self, fixturedefs, nodeid): + for fixturedef in fixturedefs: + if nodes.ischildnode(fixturedef.baseid, nodeid): + yield fixturedef diff --git a/Lib/site-packages/_pytest/freeze_support.py b/Lib/site-packages/_pytest/freeze_support.py new file mode 100644 index 0000000..002e077 --- /dev/null +++ b/Lib/site-packages/_pytest/freeze_support.py @@ -0,0 +1,45 @@ +""" +Provides a function to report all internal modules for using freezing tools +pytest +""" +from __future__ import absolute_import, division, print_function + + +def freeze_includes(): + """ + Returns a list of module names used by pytest that should be + included by cx_freeze. + """ + import py + import _pytest + + result = list(_iter_all_modules(py)) + result += list(_iter_all_modules(_pytest)) + return result + + +def _iter_all_modules(package, prefix=""): + """ + Iterates over the names of all modules that can be found in the given + package, recursively. + Example: + _iter_all_modules(_pytest) -> + ['_pytest.assertion.newinterpret', + '_pytest.capture', + '_pytest.core', + ... + ] + """ + import os + import pkgutil + + if type(package) is not str: + path, prefix = package.__path__[0], package.__name__ + "." + else: + path = package + for _, name, is_package in pkgutil.iter_modules([path]): + if is_package: + for m in _iter_all_modules(os.path.join(path, name), prefix=name + "."): + yield prefix + m + else: + yield prefix + name diff --git a/Lib/site-packages/_pytest/helpconfig.py b/Lib/site-packages/_pytest/helpconfig.py new file mode 100644 index 0000000..12c3339 --- /dev/null +++ b/Lib/site-packages/_pytest/helpconfig.py @@ -0,0 +1,212 @@ +""" version info, help messages, tracing configuration. """ +from __future__ import absolute_import, division, print_function + +import py +import pytest +from _pytest.config import PrintHelp +import os +import sys +from argparse import Action + + +class HelpAction(Action): + """This is an argparse Action that will raise an exception in + order to skip the rest of the argument parsing when --help is passed. + This prevents argparse from quitting due to missing required arguments + when any are defined, for example by ``pytest_addoption``. + This is similar to the way that the builtin argparse --help option is + implemented by raising SystemExit. + """ + + def __init__(self, option_strings, dest=None, default=False, help=None): + super(HelpAction, self).__init__( + option_strings=option_strings, + dest=dest, + const=True, + default=default, + nargs=0, + help=help, + ) + + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, self.const) + + # We should only skip the rest of the parsing after preparse is done + if getattr(parser._parser, "after_preparse", False): + raise PrintHelp + + +def pytest_addoption(parser): + group = parser.getgroup("debugconfig") + group.addoption( + "--version", + action="store_true", + help="display pytest lib version and import information.", + ) + group._addoption( + "-h", + "--help", + action=HelpAction, + dest="help", + help="show help message and configuration info", + ) + group._addoption( + "-p", + action="append", + dest="plugins", + default=[], + metavar="name", + help="early-load given plugin (multi-allowed). " + "To avoid loading of plugins, use the `no:` prefix, e.g. " + "`no:doctest`.", + ) + group.addoption( + "--traceconfig", + "--trace-config", + action="store_true", + default=False, + help="trace considerations of conftest.py files.", + ), + group.addoption( + "--debug", + action="store_true", + dest="debug", + default=False, + help="store internal tracing debug information in 'pytestdebug.log'.", + ) + group._addoption( + "-o", + "--override-ini", + dest="override_ini", + action="append", + help='override ini option with "option=value" style, e.g. `-o xfail_strict=True -o cache_dir=cache`.', + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_cmdline_parse(): + outcome = yield + config = outcome.get_result() + if config.option.debug: + path = os.path.abspath("pytestdebug.log") + debugfile = open(path, "w") + debugfile.write( + "versions pytest-%s, py-%s, " + "python-%s\ncwd=%s\nargs=%s\n\n" + % ( + pytest.__version__, + py.__version__, + ".".join(map(str, sys.version_info)), + os.getcwd(), + config._origargs, + ) + ) + config.trace.root.setwriter(debugfile.write) + undo_tracing = config.pluginmanager.enable_tracing() + sys.stderr.write("writing pytestdebug information to %s\n" % path) + + def unset_tracing(): + debugfile.close() + sys.stderr.write("wrote pytestdebug information to %s\n" % debugfile.name) + config.trace.root.setwriter(None) + undo_tracing() + + config.add_cleanup(unset_tracing) + + +def pytest_cmdline_main(config): + if config.option.version: + p = py.path.local(pytest.__file__) + sys.stderr.write( + "This is pytest version %s, imported from %s\n" % (pytest.__version__, p) + ) + plugininfo = getpluginversioninfo(config) + if plugininfo: + for line in plugininfo: + sys.stderr.write(line + "\n") + return 0 + elif config.option.help: + config._do_configure() + showhelp(config) + config._ensure_unconfigure() + return 0 + + +def showhelp(config): + reporter = config.pluginmanager.get_plugin("terminalreporter") + tw = reporter._tw + tw.write(config._parser.optparser.format_help()) + tw.line() + tw.line() + tw.line( + "[pytest] ini-options in the first " "pytest.ini|tox.ini|setup.cfg file found:" + ) + tw.line() + + for name in config._parser._ininames: + help, type, default = config._parser._inidict[name] + if type is None: + type = "string" + spec = "%s (%s)" % (name, type) + line = " %-24s %s" % (spec, help) + tw.line(line[: tw.fullwidth]) + + tw.line() + tw.line("environment variables:") + vars = [ + ("PYTEST_ADDOPTS", "extra command line options"), + ("PYTEST_PLUGINS", "comma-separated plugins to load during startup"), + ("PYTEST_DEBUG", "set to enable debug tracing of pytest's internals"), + ] + for name, help in vars: + tw.line(" %-24s %s" % (name, help)) + tw.line() + tw.line() + + tw.line("to see available markers type: pytest --markers") + tw.line("to see available fixtures type: pytest --fixtures") + tw.line( + "(shown according to specified file_or_dir or current dir " + "if not specified; fixtures with leading '_' are only shown " + "with the '-v' option" + ) + + for warningreport in reporter.stats.get("warnings", []): + tw.line("warning : " + warningreport.message, red=True) + return + + +conftest_options = [("pytest_plugins", "list of plugin names to load")] + + +def getpluginversioninfo(config): + lines = [] + plugininfo = config.pluginmanager.list_plugin_distinfo() + if plugininfo: + lines.append("setuptools registered plugins:") + for plugin, dist in plugininfo: + loc = getattr(plugin, "__file__", repr(plugin)) + content = "%s-%s at %s" % (dist.project_name, dist.version, loc) + lines.append(" " + content) + return lines + + +def pytest_report_header(config): + lines = [] + if config.option.debug or config.option.traceconfig: + lines.append("using: pytest-%s pylib-%s" % (pytest.__version__, py.__version__)) + + verinfo = getpluginversioninfo(config) + if verinfo: + lines.extend(verinfo) + + if config.option.traceconfig: + lines.append("active plugins:") + items = config.pluginmanager.list_name_plugin() + for name, plugin in items: + if hasattr(plugin, "__file__"): + r = plugin.__file__ + else: + r = repr(plugin) + lines.append(" %-20s: %s" % (name, r)) + return lines diff --git a/Lib/site-packages/_pytest/hookspec.py b/Lib/site-packages/_pytest/hookspec.py new file mode 100644 index 0000000..e296911 --- /dev/null +++ b/Lib/site-packages/_pytest/hookspec.py @@ -0,0 +1,577 @@ +""" hook specifications for pytest plugins, invoked from main.py and builtin plugins. """ + +from pluggy import HookspecMarker +from .deprecated import PYTEST_NAMESPACE + + +hookspec = HookspecMarker("pytest") + +# ------------------------------------------------------------------------- +# Initialization hooks called for every plugin +# ------------------------------------------------------------------------- + + +@hookspec(historic=True) +def pytest_addhooks(pluginmanager): + """called at plugin registration time to allow adding new hooks via a call to + ``pluginmanager.add_hookspecs(module_or_class, prefix)``. + + + :param _pytest.config.PytestPluginManager pluginmanager: pytest plugin manager + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + """ + + +@hookspec(historic=True, warn_on_impl=PYTEST_NAMESPACE) +def pytest_namespace(): + """ + return dict of name->object to be made globally available in + the pytest namespace. + + This hook is called at plugin registration time. + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + + .. warning:: + This hook has been **deprecated** and will be removed in pytest 4.0. + + Plugins whose users depend on the current namespace functionality should prepare to migrate to a + namespace they actually own. + + To support the migration its suggested to trigger ``DeprecationWarnings`` for objects they put into the + pytest namespace. + + An stopgap measure to avoid the warning is to monkeypatch the ``pytest`` module, but just as the + ``pytest_namespace`` hook this should be seen as a temporary measure to be removed in future versions after + an appropriate transition period. + """ + + +@hookspec(historic=True) +def pytest_plugin_registered(plugin, manager): + """ a new pytest plugin got registered. + + :param plugin: the plugin module or instance + :param _pytest.config.PytestPluginManager manager: pytest plugin manager + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + """ + + +@hookspec(historic=True) +def pytest_addoption(parser): + """register argparse-style options and ini-style config values, + called once at the beginning of a test run. + + .. note:: + + This function should be implemented only in plugins or ``conftest.py`` + files situated at the tests root directory due to how pytest + :ref:`discovers plugins during startup `. + + :arg _pytest.config.Parser parser: To add command line options, call + :py:func:`parser.addoption(...) <_pytest.config.Parser.addoption>`. + To add ini-file values call :py:func:`parser.addini(...) + <_pytest.config.Parser.addini>`. + + Options can later be accessed through the + :py:class:`config <_pytest.config.Config>` object, respectively: + + - :py:func:`config.getoption(name) <_pytest.config.Config.getoption>` to + retrieve the value of a command line option. + + - :py:func:`config.getini(name) <_pytest.config.Config.getini>` to retrieve + a value read from an ini-style file. + + The config object is passed around on many internal objects via the ``.config`` + attribute or can be retrieved as the ``pytestconfig`` fixture. + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + """ + + +@hookspec(historic=True) +def pytest_configure(config): + """ + Allows plugins and conftest files to perform initial configuration. + + This hook is called for every plugin and initial conftest file + after command line options have been parsed. + + After that, the hook is called for other conftest files as they are + imported. + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + + :arg _pytest.config.Config config: pytest config object + """ + + +# ------------------------------------------------------------------------- +# Bootstrapping hooks called for plugins registered early enough: +# internal and 3rd party plugins. +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_cmdline_parse(pluginmanager, args): + """return initialized config object, parsing the specified args. + + Stops at first non-None result, see :ref:`firstresult` + + .. note:: + This hook will not be called for ``conftest.py`` files, only for setuptools plugins. + + :param _pytest.config.PytestPluginManager pluginmanager: pytest plugin manager + :param list[str] args: list of arguments passed on the command line + """ + + +def pytest_cmdline_preparse(config, args): + """(**Deprecated**) modify command line arguments before option parsing. + + This hook is considered deprecated and will be removed in a future pytest version. Consider + using :func:`pytest_load_initial_conftests` instead. + + .. note:: + This hook will not be called for ``conftest.py`` files, only for setuptools plugins. + + :param _pytest.config.Config config: pytest config object + :param list[str] args: list of arguments passed on the command line + """ + + +@hookspec(firstresult=True) +def pytest_cmdline_main(config): + """ called for performing the main command line action. The default + implementation will invoke the configure hooks and runtest_mainloop. + + .. note:: + This hook will not be called for ``conftest.py`` files, only for setuptools plugins. + + Stops at first non-None result, see :ref:`firstresult` + + :param _pytest.config.Config config: pytest config object + """ + + +def pytest_load_initial_conftests(early_config, parser, args): + """ implements the loading of initial conftest files ahead + of command line option parsing. + + .. note:: + This hook will not be called for ``conftest.py`` files, only for setuptools plugins. + + :param _pytest.config.Config early_config: pytest config object + :param list[str] args: list of arguments passed on the command line + :param _pytest.config.Parser parser: to add command line options + """ + + +# ------------------------------------------------------------------------- +# collection hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_collection(session): + """Perform the collection protocol for the given session. + + Stops at first non-None result, see :ref:`firstresult`. + + :param _pytest.main.Session session: the pytest session object + """ + + +def pytest_collection_modifyitems(session, config, items): + """ called after collection has been performed, may filter or re-order + the items in-place. + + :param _pytest.main.Session session: the pytest session object + :param _pytest.config.Config config: pytest config object + :param List[_pytest.nodes.Item] items: list of item objects + """ + + +def pytest_collection_finish(session): + """ called after collection has been performed and modified. + + :param _pytest.main.Session session: the pytest session object + """ + + +@hookspec(firstresult=True) +def pytest_ignore_collect(path, config): + """ return True to prevent considering this path for collection. + This hook is consulted for all files and directories prior to calling + more specific hooks. + + Stops at first non-None result, see :ref:`firstresult` + + :param str path: the path to analyze + :param _pytest.config.Config config: pytest config object + """ + + +@hookspec(firstresult=True) +def pytest_collect_directory(path, parent): + """ called before traversing a directory for collection files. + + Stops at first non-None result, see :ref:`firstresult` + + :param str path: the path to analyze + """ + + +def pytest_collect_file(path, parent): + """ return collection Node or None for the given path. Any new node + needs to have the specified ``parent`` as a parent. + + :param str path: the path to collect + """ + + +# logging hooks for collection + + +def pytest_collectstart(collector): + """ collector starts collecting. """ + + +def pytest_itemcollected(item): + """ we just collected a test item. """ + + +def pytest_collectreport(report): + """ collector finished collecting. """ + + +def pytest_deselected(items): + """ called for test items deselected by keyword. """ + + +@hookspec(firstresult=True) +def pytest_make_collect_report(collector): + """ perform ``collector.collect()`` and return a CollectReport. + + Stops at first non-None result, see :ref:`firstresult` """ + + +# ------------------------------------------------------------------------- +# Python test function related hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_pycollect_makemodule(path, parent): + """ return a Module collector or None for the given path. + This hook will be called for each matching test module path. + The pytest_collect_file hook needs to be used if you want to + create test modules for files that do not match as a test module. + + Stops at first non-None result, see :ref:`firstresult` """ + + +@hookspec(firstresult=True) +def pytest_pycollect_makeitem(collector, name, obj): + """ return custom item/collector for a python object in a module, or None. + + Stops at first non-None result, see :ref:`firstresult` """ + + +@hookspec(firstresult=True) +def pytest_pyfunc_call(pyfuncitem): + """ call underlying test function. + + Stops at first non-None result, see :ref:`firstresult` """ + + +def pytest_generate_tests(metafunc): + """ generate (multiple) parametrized calls to a test function.""" + + +@hookspec(firstresult=True) +def pytest_make_parametrize_id(config, val, argname): + """Return a user-friendly string representation of the given ``val`` that will be used + by @pytest.mark.parametrize calls. Return None if the hook doesn't know about ``val``. + The parameter name is available as ``argname``, if required. + + Stops at first non-None result, see :ref:`firstresult` + + :param _pytest.config.Config config: pytest config object + :param val: the parametrized value + :param str argname: the automatic parameter name produced by pytest + """ + + +# ------------------------------------------------------------------------- +# generic runtest related hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_runtestloop(session): + """ called for performing the main runtest loop + (after collection finished). + + Stops at first non-None result, see :ref:`firstresult` + + :param _pytest.main.Session session: the pytest session object + """ + + +def pytest_itemstart(item, node): + """(**Deprecated**) use pytest_runtest_logstart. """ + + +@hookspec(firstresult=True) +def pytest_runtest_protocol(item, nextitem): + """ implements the runtest_setup/call/teardown protocol for + the given test item, including capturing exceptions and calling + reporting hooks. + + :arg item: test item for which the runtest protocol is performed. + + :arg nextitem: the scheduled-to-be-next test item (or None if this + is the end my friend). This argument is passed on to + :py:func:`pytest_runtest_teardown`. + + :return boolean: True if no further hook implementations should be invoked. + + + Stops at first non-None result, see :ref:`firstresult` """ + + +def pytest_runtest_logstart(nodeid, location): + """ signal the start of running a single test item. + + This hook will be called **before** :func:`pytest_runtest_setup`, :func:`pytest_runtest_call` and + :func:`pytest_runtest_teardown` hooks. + + :param str nodeid: full id of the item + :param location: a triple of ``(filename, linenum, testname)`` + """ + + +def pytest_runtest_logfinish(nodeid, location): + """ signal the complete finish of running a single test item. + + This hook will be called **after** :func:`pytest_runtest_setup`, :func:`pytest_runtest_call` and + :func:`pytest_runtest_teardown` hooks. + + :param str nodeid: full id of the item + :param location: a triple of ``(filename, linenum, testname)`` + """ + + +def pytest_runtest_setup(item): + """ called before ``pytest_runtest_call(item)``. """ + + +def pytest_runtest_call(item): + """ called to execute the test ``item``. """ + + +def pytest_runtest_teardown(item, nextitem): + """ called after ``pytest_runtest_call``. + + :arg nextitem: the scheduled-to-be-next test item (None if no further + test item is scheduled). This argument can be used to + perform exact teardowns, i.e. calling just enough finalizers + so that nextitem only needs to call setup-functions. + """ + + +@hookspec(firstresult=True) +def pytest_runtest_makereport(item, call): + """ return a :py:class:`_pytest.runner.TestReport` object + for the given :py:class:`pytest.Item <_pytest.main.Item>` and + :py:class:`_pytest.runner.CallInfo`. + + Stops at first non-None result, see :ref:`firstresult` """ + + +def pytest_runtest_logreport(report): + """ process a test setup/call/teardown report relating to + the respective phase of executing a test. """ + + +# ------------------------------------------------------------------------- +# Fixture related hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_fixture_setup(fixturedef, request): + """ performs fixture setup execution. + + :return: The return value of the call to the fixture function + + Stops at first non-None result, see :ref:`firstresult` + + .. note:: + If the fixture function returns None, other implementations of + this hook function will continue to be called, according to the + behavior of the :ref:`firstresult` option. + """ + + +def pytest_fixture_post_finalizer(fixturedef, request): + """ called after fixture teardown, but before the cache is cleared so + the fixture result cache ``fixturedef.cached_result`` can + still be accessed.""" + + +# ------------------------------------------------------------------------- +# test session related hooks +# ------------------------------------------------------------------------- + + +def pytest_sessionstart(session): + """ called after the ``Session`` object has been created and before performing collection + and entering the run test loop. + + :param _pytest.main.Session session: the pytest session object + """ + + +def pytest_sessionfinish(session, exitstatus): + """ called after whole test run finished, right before returning the exit status to the system. + + :param _pytest.main.Session session: the pytest session object + :param int exitstatus: the status which pytest will return to the system + """ + + +def pytest_unconfigure(config): + """ called before test process is exited. + + :param _pytest.config.Config config: pytest config object + """ + + +# ------------------------------------------------------------------------- +# hooks for customizing the assert methods +# ------------------------------------------------------------------------- + + +def pytest_assertrepr_compare(config, op, left, right): + """return explanation for comparisons in failing assert expressions. + + Return None for no custom explanation, otherwise return a list + of strings. The strings will be joined by newlines but any newlines + *in* a string will be escaped. Note that all but the first line will + be indented slightly, the intention is for the first line to be a summary. + + :param _pytest.config.Config config: pytest config object + """ + + +# ------------------------------------------------------------------------- +# hooks for influencing reporting (invoked from _pytest_terminal) +# ------------------------------------------------------------------------- + + +def pytest_report_header(config, startdir): + """ return a string or list of strings to be displayed as header info for terminal reporting. + + :param _pytest.config.Config config: pytest config object + :param startdir: py.path object with the starting dir + + .. note:: + + This function should be implemented only in plugins or ``conftest.py`` + files situated at the tests root directory due to how pytest + :ref:`discovers plugins during startup `. + """ + + +def pytest_report_collectionfinish(config, startdir, items): + """ + .. versionadded:: 3.2 + + return a string or list of strings to be displayed after collection has finished successfully. + + This strings will be displayed after the standard "collected X items" message. + + :param _pytest.config.Config config: pytest config object + :param startdir: py.path object with the starting dir + :param items: list of pytest items that are going to be executed; this list should not be modified. + """ + + +@hookspec(firstresult=True) +def pytest_report_teststatus(report): + """ return result-category, shortletter and verbose word for reporting. + + Stops at first non-None result, see :ref:`firstresult` """ + + +def pytest_terminal_summary(terminalreporter, exitstatus): + """Add a section to terminal summary reporting. + + :param _pytest.terminal.TerminalReporter terminalreporter: the internal terminal reporter object + :param int exitstatus: the exit status that will be reported back to the OS + + .. versionadded:: 3.5 + The ``config`` parameter. + """ + + +@hookspec(historic=True) +def pytest_logwarning(message, code, nodeid, fslocation): + """ process a warning specified by a message, a code string, + a nodeid and fslocation (both of which may be None + if the warning is not tied to a particular node/location). + + .. note:: + This hook is incompatible with ``hookwrapper=True``. + """ + + +# ------------------------------------------------------------------------- +# doctest hooks +# ------------------------------------------------------------------------- + + +@hookspec(firstresult=True) +def pytest_doctest_prepare_content(content): + """ return processed content for a given doctest + + Stops at first non-None result, see :ref:`firstresult` """ + + +# ------------------------------------------------------------------------- +# error handling and internal debugging hooks +# ------------------------------------------------------------------------- + + +def pytest_internalerror(excrepr, excinfo): + """ called for internal errors. """ + + +def pytest_keyboard_interrupt(excinfo): + """ called for keyboard interrupt. """ + + +def pytest_exception_interact(node, call, report): + """called when an exception was raised which can potentially be + interactively handled. + + This hook is only called if an exception was raised + that is not an internal exception like ``skip.Exception``. + """ + + +def pytest_enter_pdb(config): + """ called upon pdb.set_trace(), can be used by plugins to take special + action just before the python debugger enters in interactive mode. + + :param _pytest.config.Config config: pytest config object + """ diff --git a/Lib/site-packages/_pytest/junitxml.py b/Lib/site-packages/_pytest/junitxml.py new file mode 100644 index 0000000..86aad69 --- /dev/null +++ b/Lib/site-packages/_pytest/junitxml.py @@ -0,0 +1,564 @@ +""" + report test results in JUnit-XML format, + for use with Jenkins and build integration servers. + + +Based on initial code from Ross Lawley. + +Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/ +src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd +""" +from __future__ import absolute_import, division, print_function + +import functools +import py +import os +import re +import sys +import time +import pytest +from _pytest import nodes +from _pytest.config import filename_arg + +# Python 2.X and 3.X compatibility +if sys.version_info[0] < 3: + from codecs import open +else: + unichr = chr + unicode = str + long = int + + +class Junit(py.xml.Namespace): + pass + + +# We need to get the subset of the invalid unicode ranges according to +# XML 1.0 which are valid in this python build. Hence we calculate +# this dynamically instead of hardcoding it. The spec range of valid +# chars is: Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] +# | [#x10000-#x10FFFF] +_legal_chars = (0x09, 0x0A, 0x0d) +_legal_ranges = ((0x20, 0x7E), (0x80, 0xD7FF), (0xE000, 0xFFFD), (0x10000, 0x10FFFF)) +_legal_xml_re = [ + unicode("%s-%s") % (unichr(low), unichr(high)) + for (low, high) in _legal_ranges + if low < sys.maxunicode +] +_legal_xml_re = [unichr(x) for x in _legal_chars] + _legal_xml_re +illegal_xml_re = re.compile(unicode("[^%s]") % unicode("").join(_legal_xml_re)) +del _legal_chars +del _legal_ranges +del _legal_xml_re + +_py_ext_re = re.compile(r"\.py$") + + +def bin_xml_escape(arg): + def repl(matchobj): + i = ord(matchobj.group()) + if i <= 0xFF: + return unicode("#x%02X") % i + else: + return unicode("#x%04X") % i + + return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg))) + + +class _NodeReporter(object): + def __init__(self, nodeid, xml): + + self.id = nodeid + self.xml = xml + self.add_stats = self.xml.add_stats + self.duration = 0 + self.properties = [] + self.nodes = [] + self.testcase = None + self.attrs = {} + + def append(self, node): + self.xml.add_stats(type(node).__name__) + self.nodes.append(node) + + def add_property(self, name, value): + self.properties.append((str(name), bin_xml_escape(value))) + + def add_attribute(self, name, value): + self.attrs[str(name)] = bin_xml_escape(value) + + def make_properties_node(self): + """Return a Junit node containing custom properties, if any. + """ + if self.properties: + return Junit.properties( + [ + Junit.property(name=name, value=value) + for name, value in self.properties + ] + ) + return "" + + def record_testreport(self, testreport): + assert not self.testcase + names = mangle_test_address(testreport.nodeid) + existing_attrs = self.attrs + classnames = names[:-1] + if self.xml.prefix: + classnames.insert(0, self.xml.prefix) + attrs = { + "classname": ".".join(classnames), + "name": bin_xml_escape(names[-1]), + "file": testreport.location[0], + } + if testreport.location[1] is not None: + attrs["line"] = testreport.location[1] + if hasattr(testreport, "url"): + attrs["url"] = testreport.url + self.attrs = attrs + self.attrs.update(existing_attrs) # restore any user-defined attributes + + def to_xml(self): + testcase = Junit.testcase(time=self.duration, **self.attrs) + testcase.append(self.make_properties_node()) + for node in self.nodes: + testcase.append(node) + return testcase + + def _add_simple(self, kind, message, data=None): + data = bin_xml_escape(data) + node = kind(data, message=message) + self.append(node) + + def write_captured_output(self, report): + content_out = report.capstdout + content_log = report.caplog + content_err = report.capstderr + + if content_log or content_out: + if content_log and self.xml.logging == "system-out": + if content_out: + # syncing stdout and the log-output is not done yet. It's + # probably not worth the effort. Therefore, first the captured + # stdout is shown and then the captured logs. + content = "\n".join( + [ + " Captured Stdout ".center(80, "-"), + content_out, + "", + " Captured Log ".center(80, "-"), + content_log, + ] + ) + else: + content = content_log + else: + content = content_out + + if content: + tag = getattr(Junit, "system-out") + self.append(tag(bin_xml_escape(content))) + + if content_log or content_err: + if content_log and self.xml.logging == "system-err": + if content_err: + content = "\n".join( + [ + " Captured Stderr ".center(80, "-"), + content_err, + "", + " Captured Log ".center(80, "-"), + content_log, + ] + ) + else: + content = content_log + else: + content = content_err + + if content: + tag = getattr(Junit, "system-err") + self.append(tag(bin_xml_escape(content))) + + def append_pass(self, report): + self.add_stats("passed") + + def append_failure(self, report): + # msg = str(report.longrepr.reprtraceback.extraline) + if hasattr(report, "wasxfail"): + self._add_simple(Junit.skipped, "xfail-marked test passes unexpectedly") + else: + if hasattr(report.longrepr, "reprcrash"): + message = report.longrepr.reprcrash.message + elif isinstance(report.longrepr, (unicode, str)): + message = report.longrepr + else: + message = str(report.longrepr) + message = bin_xml_escape(message) + fail = Junit.failure(message=message) + fail.append(bin_xml_escape(report.longrepr)) + self.append(fail) + + def append_collect_error(self, report): + # msg = str(report.longrepr.reprtraceback.extraline) + self.append( + Junit.error(bin_xml_escape(report.longrepr), message="collection failure") + ) + + def append_collect_skipped(self, report): + self._add_simple(Junit.skipped, "collection skipped", report.longrepr) + + def append_error(self, report): + if getattr(report, "when", None) == "teardown": + msg = "test teardown failure" + else: + msg = "test setup failure" + self._add_simple(Junit.error, msg, report.longrepr) + + def append_skipped(self, report): + if hasattr(report, "wasxfail"): + self._add_simple(Junit.skipped, "expected test failure", report.wasxfail) + else: + filename, lineno, skipreason = report.longrepr + if skipreason.startswith("Skipped: "): + skipreason = bin_xml_escape(skipreason[9:]) + self.append( + Junit.skipped( + "%s:%s: %s" % (filename, lineno, skipreason), + type="pytest.skip", + message=skipreason, + ) + ) + self.write_captured_output(report) + + def finalize(self): + data = self.to_xml().unicode(indent=0) + self.__dict__.clear() + self.to_xml = lambda: py.xml.raw(data) + + +@pytest.fixture +def record_property(request): + """Add an extra properties the calling test. + User properties become part of the test report and are available to the + configured reporters, like JUnit XML. + The fixture is callable with ``(name, value)``, with value being automatically + xml-encoded. + + Example:: + + def test_function(record_property): + record_property("example_key", 1) + """ + + def append_property(name, value): + request.node.user_properties.append((name, value)) + + return append_property + + +@pytest.fixture +def record_xml_property(record_property): + """(Deprecated) use record_property.""" + import warnings + from _pytest import deprecated + + warnings.warn(deprecated.RECORD_XML_PROPERTY, DeprecationWarning, stacklevel=2) + + return record_property + + +@pytest.fixture +def record_xml_attribute(request): + """Add extra xml attributes to the tag for the calling test. + The fixture is callable with ``(name, value)``, with value being + automatically xml-encoded + """ + request.node.warn( + code="C3", message="record_xml_attribute is an experimental feature" + ) + xml = getattr(request.config, "_xml", None) + if xml is not None: + node_reporter = xml.node_reporter(request.node.nodeid) + return node_reporter.add_attribute + else: + + def add_attr_noop(name, value): + pass + + return add_attr_noop + + +def pytest_addoption(parser): + group = parser.getgroup("terminal reporting") + group.addoption( + "--junitxml", + "--junit-xml", + action="store", + dest="xmlpath", + metavar="path", + type=functools.partial(filename_arg, optname="--junitxml"), + default=None, + help="create junit-xml style report file at given path.", + ) + group.addoption( + "--junitprefix", + "--junit-prefix", + action="store", + metavar="str", + default=None, + help="prepend prefix to classnames in junit-xml output", + ) + parser.addini( + "junit_suite_name", "Test suite name for JUnit report", default="pytest" + ) + parser.addini( + "junit_logging", + "Write captured log messages to JUnit report: " + "one of no|system-out|system-err", + default="no", + ) # choices=['no', 'stdout', 'stderr']) + + +def pytest_configure(config): + xmlpath = config.option.xmlpath + # prevent opening xmllog on slave nodes (xdist) + if xmlpath and not hasattr(config, "slaveinput"): + config._xml = LogXML( + xmlpath, + config.option.junitprefix, + config.getini("junit_suite_name"), + config.getini("junit_logging"), + ) + config.pluginmanager.register(config._xml) + + +def pytest_unconfigure(config): + xml = getattr(config, "_xml", None) + if xml: + del config._xml + config.pluginmanager.unregister(xml) + + +def mangle_test_address(address): + path, possible_open_bracket, params = address.partition("[") + names = path.split("::") + try: + names.remove("()") + except ValueError: + pass + # convert file path to dotted path + names[0] = names[0].replace(nodes.SEP, ".") + names[0] = _py_ext_re.sub("", names[0]) + # put any params back + names[-1] += possible_open_bracket + params + return names + + +class LogXML(object): + def __init__(self, logfile, prefix, suite_name="pytest", logging="no"): + logfile = os.path.expanduser(os.path.expandvars(logfile)) + self.logfile = os.path.normpath(os.path.abspath(logfile)) + self.prefix = prefix + self.suite_name = suite_name + self.logging = logging + self.stats = dict.fromkeys(["error", "passed", "failure", "skipped"], 0) + self.node_reporters = {} # nodeid -> _NodeReporter + self.node_reporters_ordered = [] + self.global_properties = [] + # List of reports that failed on call but teardown is pending. + self.open_reports = [] + self.cnt_double_fail_tests = 0 + + def finalize(self, report): + nodeid = getattr(report, "nodeid", report) + # local hack to handle xdist report order + slavenode = getattr(report, "node", None) + reporter = self.node_reporters.pop((nodeid, slavenode)) + if reporter is not None: + reporter.finalize() + + def node_reporter(self, report): + nodeid = getattr(report, "nodeid", report) + # local hack to handle xdist report order + slavenode = getattr(report, "node", None) + + key = nodeid, slavenode + + if key in self.node_reporters: + # TODO: breasks for --dist=each + return self.node_reporters[key] + + reporter = _NodeReporter(nodeid, self) + + self.node_reporters[key] = reporter + self.node_reporters_ordered.append(reporter) + + return reporter + + def add_stats(self, key): + if key in self.stats: + self.stats[key] += 1 + + def _opentestcase(self, report): + reporter = self.node_reporter(report) + reporter.record_testreport(report) + return reporter + + def pytest_runtest_logreport(self, report): + """handle a setup/call/teardown report, generating the appropriate + xml tags as necessary. + + note: due to plugins like xdist, this hook may be called in interlaced + order with reports from other nodes. for example: + + usual call order: + -> setup node1 + -> call node1 + -> teardown node1 + -> setup node2 + -> call node2 + -> teardown node2 + + possible call order in xdist: + -> setup node1 + -> call node1 + -> setup node2 + -> call node2 + -> teardown node2 + -> teardown node1 + """ + close_report = None + if report.passed: + if report.when == "call": # ignore setup/teardown + reporter = self._opentestcase(report) + reporter.append_pass(report) + elif report.failed: + if report.when == "teardown": + # The following vars are needed when xdist plugin is used + report_wid = getattr(report, "worker_id", None) + report_ii = getattr(report, "item_index", None) + close_report = next( + ( + rep + for rep in self.open_reports + if ( + rep.nodeid == report.nodeid + and getattr(rep, "item_index", None) == report_ii + and getattr(rep, "worker_id", None) == report_wid + ) + ), + None, + ) + if close_report: + # We need to open new testcase in case we have failure in + # call and error in teardown in order to follow junit + # schema + self.finalize(close_report) + self.cnt_double_fail_tests += 1 + reporter = self._opentestcase(report) + if report.when == "call": + reporter.append_failure(report) + self.open_reports.append(report) + else: + reporter.append_error(report) + elif report.skipped: + reporter = self._opentestcase(report) + reporter.append_skipped(report) + self.update_testcase_duration(report) + if report.when == "teardown": + reporter = self._opentestcase(report) + reporter.write_captured_output(report) + + for propname, propvalue in report.user_properties: + reporter.add_property(propname, propvalue) + + self.finalize(report) + report_wid = getattr(report, "worker_id", None) + report_ii = getattr(report, "item_index", None) + close_report = next( + ( + rep + for rep in self.open_reports + if ( + rep.nodeid == report.nodeid + and getattr(rep, "item_index", None) == report_ii + and getattr(rep, "worker_id", None) == report_wid + ) + ), + None, + ) + if close_report: + self.open_reports.remove(close_report) + + def update_testcase_duration(self, report): + """accumulates total duration for nodeid from given report and updates + the Junit.testcase with the new total if already created. + """ + reporter = self.node_reporter(report) + reporter.duration += getattr(report, "duration", 0.0) + + def pytest_collectreport(self, report): + if not report.passed: + reporter = self._opentestcase(report) + if report.failed: + reporter.append_collect_error(report) + else: + reporter.append_collect_skipped(report) + + def pytest_internalerror(self, excrepr): + reporter = self.node_reporter("internal") + reporter.attrs.update(classname="pytest", name="internal") + reporter._add_simple(Junit.error, "internal error", excrepr) + + def pytest_sessionstart(self): + self.suite_start_time = time.time() + + def pytest_sessionfinish(self): + dirname = os.path.dirname(os.path.abspath(self.logfile)) + if not os.path.isdir(dirname): + os.makedirs(dirname) + logfile = open(self.logfile, "w", encoding="utf-8") + suite_stop_time = time.time() + suite_time_delta = suite_stop_time - self.suite_start_time + + numtests = ( + self.stats["passed"] + + self.stats["failure"] + + self.stats["skipped"] + + self.stats["error"] + - self.cnt_double_fail_tests + ) + logfile.write('') + + logfile.write( + Junit.testsuite( + self._get_global_properties_node(), + [x.to_xml() for x in self.node_reporters_ordered], + name=self.suite_name, + errors=self.stats["error"], + failures=self.stats["failure"], + skips=self.stats["skipped"], + tests=numtests, + time="%.3f" % suite_time_delta, + ).unicode(indent=0) + ) + logfile.close() + + def pytest_terminal_summary(self, terminalreporter): + terminalreporter.write_sep("-", "generated xml file: %s" % (self.logfile)) + + def add_global_property(self, name, value): + self.global_properties.append((str(name), bin_xml_escape(value))) + + def _get_global_properties_node(self): + """Return a Junit node containing custom properties, if any. + """ + if self.global_properties: + return Junit.properties( + [ + Junit.property(name=name, value=value) + for name, value in self.global_properties + ] + ) + return "" diff --git a/Lib/site-packages/_pytest/logging.py b/Lib/site-packages/_pytest/logging.py new file mode 100644 index 0000000..1472b0d --- /dev/null +++ b/Lib/site-packages/_pytest/logging.py @@ -0,0 +1,591 @@ +""" Access and control log capturing. """ +from __future__ import absolute_import, division, print_function + +import logging +from contextlib import closing, contextmanager +import re +import six + +from _pytest.config import create_terminal_writer +import pytest +import py + + +DEFAULT_LOG_FORMAT = "%(filename)-25s %(lineno)4d %(levelname)-8s %(message)s" +DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S" + + +class ColoredLevelFormatter(logging.Formatter): + """ + Colorize the %(levelname)..s part of the log format passed to __init__. + """ + + LOGLEVEL_COLOROPTS = { + logging.CRITICAL: {"red"}, + logging.ERROR: {"red", "bold"}, + logging.WARNING: {"yellow"}, + logging.WARN: {"yellow"}, + logging.INFO: {"green"}, + logging.DEBUG: {"purple"}, + logging.NOTSET: set(), + } + LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-]?\d*s)") + + def __init__(self, terminalwriter, *args, **kwargs): + super(ColoredLevelFormatter, self).__init__(*args, **kwargs) + if six.PY2: + self._original_fmt = self._fmt + else: + self._original_fmt = self._style._fmt + self._level_to_fmt_mapping = {} + + levelname_fmt_match = self.LEVELNAME_FMT_REGEX.search(self._fmt) + if not levelname_fmt_match: + return + levelname_fmt = levelname_fmt_match.group() + + for level, color_opts in self.LOGLEVEL_COLOROPTS.items(): + formatted_levelname = levelname_fmt % { + "levelname": logging.getLevelName(level) + } + + # add ANSI escape sequences around the formatted levelname + color_kwargs = {name: True for name in color_opts} + colorized_formatted_levelname = terminalwriter.markup( + formatted_levelname, **color_kwargs + ) + self._level_to_fmt_mapping[level] = self.LEVELNAME_FMT_REGEX.sub( + colorized_formatted_levelname, self._fmt + ) + + def format(self, record): + fmt = self._level_to_fmt_mapping.get(record.levelno, self._original_fmt) + if six.PY2: + self._fmt = fmt + else: + self._style._fmt = fmt + return super(ColoredLevelFormatter, self).format(record) + + +def get_option_ini(config, *names): + for name in names: + ret = config.getoption(name) # 'default' arg won't work as expected + if ret is None: + ret = config.getini(name) + if ret: + return ret + + +def pytest_addoption(parser): + """Add options to control log capturing.""" + group = parser.getgroup("logging") + + def add_option_ini(option, dest, default=None, type=None, **kwargs): + parser.addini( + dest, default=default, type=type, help="default value for " + option + ) + group.addoption(option, dest=dest, **kwargs) + + add_option_ini( + "--no-print-logs", + dest="log_print", + action="store_const", + const=False, + default=True, + type="bool", + help="disable printing caught logs on failed tests.", + ) + add_option_ini( + "--log-level", + dest="log_level", + default=None, + help="logging level used by the logging module", + ) + add_option_ini( + "--log-format", + dest="log_format", + default=DEFAULT_LOG_FORMAT, + help="log format as used by the logging module.", + ) + add_option_ini( + "--log-date-format", + dest="log_date_format", + default=DEFAULT_LOG_DATE_FORMAT, + help="log date format as used by the logging module.", + ) + parser.addini( + "log_cli", + default=False, + type="bool", + help='enable log display during test run (also known as "live logging").', + ) + add_option_ini( + "--log-cli-level", dest="log_cli_level", default=None, help="cli logging level." + ) + add_option_ini( + "--log-cli-format", + dest="log_cli_format", + default=None, + help="log format as used by the logging module.", + ) + add_option_ini( + "--log-cli-date-format", + dest="log_cli_date_format", + default=None, + help="log date format as used by the logging module.", + ) + add_option_ini( + "--log-file", + dest="log_file", + default=None, + help="path to a file when logging will be written to.", + ) + add_option_ini( + "--log-file-level", + dest="log_file_level", + default=None, + help="log file logging level.", + ) + add_option_ini( + "--log-file-format", + dest="log_file_format", + default=DEFAULT_LOG_FORMAT, + help="log format as used by the logging module.", + ) + add_option_ini( + "--log-file-date-format", + dest="log_file_date_format", + default=DEFAULT_LOG_DATE_FORMAT, + help="log date format as used by the logging module.", + ) + + +@contextmanager +def catching_logs(handler, formatter=None, level=None): + """Context manager that prepares the whole logging machinery properly.""" + root_logger = logging.getLogger() + + if formatter is not None: + handler.setFormatter(formatter) + if level is not None: + handler.setLevel(level) + + # Adding the same handler twice would confuse logging system. + # Just don't do that. + add_new_handler = handler not in root_logger.handlers + + if add_new_handler: + root_logger.addHandler(handler) + if level is not None: + orig_level = root_logger.level + root_logger.setLevel(min(orig_level, level)) + try: + yield handler + finally: + if level is not None: + root_logger.setLevel(orig_level) + if add_new_handler: + root_logger.removeHandler(handler) + + +class LogCaptureHandler(logging.StreamHandler): + """A logging handler that stores log records and the log text.""" + + def __init__(self): + """Creates a new log handler.""" + logging.StreamHandler.__init__(self, py.io.TextIO()) + self.records = [] + + def emit(self, record): + """Keep the log records in a list in addition to the log text.""" + self.records.append(record) + logging.StreamHandler.emit(self, record) + + def reset(self): + self.records = [] + self.stream = py.io.TextIO() + + +class LogCaptureFixture(object): + """Provides access and control of log capturing.""" + + def __init__(self, item): + """Creates a new funcarg.""" + self._item = item + self._initial_log_levels = {} # type: Dict[str, int] # dict of log name -> log level + + def _finalize(self): + """Finalizes the fixture. + + This restores the log levels changed by :meth:`set_level`. + """ + # restore log levels + for logger_name, level in self._initial_log_levels.items(): + logger = logging.getLogger(logger_name) + logger.setLevel(level) + + @property + def handler(self): + """ + :rtype: LogCaptureHandler + """ + return self._item.catch_log_handler + + def get_records(self, when): + """ + Get the logging records for one of the possible test phases. + + :param str when: + Which test phase to obtain the records from. Valid values are: "setup", "call" and "teardown". + + :rtype: List[logging.LogRecord] + :return: the list of captured records at the given stage + + .. versionadded:: 3.4 + """ + handler = self._item.catch_log_handlers.get(when) + if handler: + return handler.records + else: + return [] + + @property + def text(self): + """Returns the log text.""" + return self.handler.stream.getvalue() + + @property + def records(self): + """Returns the list of log records.""" + return self.handler.records + + @property + def record_tuples(self): + """Returns a list of a striped down version of log records intended + for use in assertion comparison. + + The format of the tuple is: + + (logger_name, log_level, message) + """ + return [(r.name, r.levelno, r.getMessage()) for r in self.records] + + @property + def messages(self): + """Returns a list of format-interpolated log messages. + + Unlike 'records', which contains the format string and parameters for interpolation, log messages in this list + are all interpolated. + Unlike 'text', which contains the output from the handler, log messages in this list are unadorned with + levels, timestamps, etc, making exact comparisions more reliable. + + Note that traceback or stack info (from :func:`logging.exception` or the `exc_info` or `stack_info` arguments + to the logging functions) is not included, as this is added by the formatter in the handler. + + .. versionadded:: 3.7 + """ + return [r.getMessage() for r in self.records] + + def clear(self): + """Reset the list of log records and the captured log text.""" + self.handler.reset() + + def set_level(self, level, logger=None): + """Sets the level for capturing of logs. The level will be restored to its previous value at the end of + the test. + + :param int level: the logger to level. + :param str logger: the logger to update the level. If not given, the root logger level is updated. + + .. versionchanged:: 3.4 + The levels of the loggers changed by this function will be restored to their initial values at the + end of the test. + """ + logger_name = logger + logger = logging.getLogger(logger_name) + # save the original log-level to restore it during teardown + self._initial_log_levels.setdefault(logger_name, logger.level) + logger.setLevel(level) + + @contextmanager + def at_level(self, level, logger=None): + """Context manager that sets the level for capturing of logs. After the end of the 'with' statement the + level is restored to its original value. + + :param int level: the logger to level. + :param str logger: the logger to update the level. If not given, the root logger level is updated. + """ + logger = logging.getLogger(logger) + orig_level = logger.level + logger.setLevel(level) + try: + yield + finally: + logger.setLevel(orig_level) + + +@pytest.fixture +def caplog(request): + """Access and control log capturing. + + Captured logs are available through the following methods:: + + * caplog.text -> string containing formatted log output + * caplog.records -> list of logging.LogRecord instances + * caplog.record_tuples -> list of (logger_name, level, message) tuples + * caplog.clear() -> clear captured records and formatted log output string + """ + result = LogCaptureFixture(request.node) + yield result + result._finalize() + + +def get_actual_log_level(config, *setting_names): + """Return the actual logging level.""" + + for setting_name in setting_names: + log_level = config.getoption(setting_name) + if log_level is None: + log_level = config.getini(setting_name) + if log_level: + break + else: + return + + if isinstance(log_level, six.string_types): + log_level = log_level.upper() + try: + return int(getattr(logging, log_level, log_level)) + except ValueError: + # Python logging does not recognise this as a logging level + raise pytest.UsageError( + "'{}' is not recognized as a logging level name for " + "'{}'. Please consider passing the " + "logging level num instead.".format(log_level, setting_name) + ) + + +def pytest_configure(config): + config.pluginmanager.register(LoggingPlugin(config), "logging-plugin") + + +@contextmanager +def _dummy_context_manager(): + yield + + +class LoggingPlugin(object): + """Attaches to the logging module and captures log messages for each test. + """ + + def __init__(self, config): + """Creates a new plugin to capture log messages. + + The formatter can be safely shared across all handlers so + create a single one for the entire test session here. + """ + self._config = config + + # enable verbose output automatically if live logging is enabled + if self._log_cli_enabled() and not config.getoption("verbose"): + # sanity check: terminal reporter should not have been loaded at this point + assert self._config.pluginmanager.get_plugin("terminalreporter") is None + config.option.verbose = 1 + + self.print_logs = get_option_ini(config, "log_print") + self.formatter = logging.Formatter( + get_option_ini(config, "log_format"), + get_option_ini(config, "log_date_format"), + ) + self.log_level = get_actual_log_level(config, "log_level") + + log_file = get_option_ini(config, "log_file") + if log_file: + self.log_file_level = get_actual_log_level(config, "log_file_level") + + log_file_format = get_option_ini(config, "log_file_format", "log_format") + log_file_date_format = get_option_ini( + config, "log_file_date_format", "log_date_format" + ) + # Each pytest runtests session will write to a clean logfile + self.log_file_handler = logging.FileHandler( + log_file, mode="w", encoding="UTF-8" + ) + log_file_formatter = logging.Formatter( + log_file_format, datefmt=log_file_date_format + ) + self.log_file_handler.setFormatter(log_file_formatter) + else: + self.log_file_handler = None + + # initialized during pytest_runtestloop + self.log_cli_handler = None + + def _log_cli_enabled(self): + """Return True if log_cli should be considered enabled, either explicitly + or because --log-cli-level was given in the command-line. + """ + return self._config.getoption( + "--log-cli-level" + ) is not None or self._config.getini("log_cli") + + @contextmanager + def _runtest_for(self, item, when): + """Implements the internals of pytest_runtest_xxx() hook.""" + with catching_logs( + LogCaptureHandler(), formatter=self.formatter, level=self.log_level + ) as log_handler: + if self.log_cli_handler: + self.log_cli_handler.set_when(when) + + if item is None: + yield # run the test + return + + if not hasattr(item, "catch_log_handlers"): + item.catch_log_handlers = {} + item.catch_log_handlers[when] = log_handler + item.catch_log_handler = log_handler + try: + yield # run test + finally: + del item.catch_log_handler + if when == "teardown": + del item.catch_log_handlers + + if self.print_logs: + # Add a captured log section to the report. + log = log_handler.stream.getvalue().strip() + item.add_report_section(when, "log", log) + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_setup(self, item): + with self._runtest_for(item, "setup"): + yield + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_call(self, item): + with self._runtest_for(item, "call"): + yield + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_teardown(self, item): + with self._runtest_for(item, "teardown"): + yield + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_logstart(self): + if self.log_cli_handler: + self.log_cli_handler.reset() + with self._runtest_for(None, "start"): + yield + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_logfinish(self): + with self._runtest_for(None, "finish"): + yield + + @pytest.hookimpl(hookwrapper=True) + def pytest_runtestloop(self, session): + """Runs all collected test items.""" + self._setup_cli_logging() + with self.live_logs_context: + if self.log_file_handler is not None: + with closing(self.log_file_handler): + with catching_logs( + self.log_file_handler, level=self.log_file_level + ): + yield # run all the tests + else: + yield # run all the tests + + def _setup_cli_logging(self): + """Sets up the handler and logger for the Live Logs feature, if enabled. + + This must be done right before starting the loop so we can access the terminal reporter plugin. + """ + terminal_reporter = self._config.pluginmanager.get_plugin("terminalreporter") + if self._log_cli_enabled() and terminal_reporter is not None: + capture_manager = self._config.pluginmanager.get_plugin("capturemanager") + log_cli_handler = _LiveLoggingStreamHandler( + terminal_reporter, capture_manager + ) + log_cli_format = get_option_ini( + self._config, "log_cli_format", "log_format" + ) + log_cli_date_format = get_option_ini( + self._config, "log_cli_date_format", "log_date_format" + ) + if ( + self._config.option.color != "no" + and ColoredLevelFormatter.LEVELNAME_FMT_REGEX.search(log_cli_format) + ): + log_cli_formatter = ColoredLevelFormatter( + create_terminal_writer(self._config), + log_cli_format, + datefmt=log_cli_date_format, + ) + else: + log_cli_formatter = logging.Formatter( + log_cli_format, datefmt=log_cli_date_format + ) + log_cli_level = get_actual_log_level( + self._config, "log_cli_level", "log_level" + ) + self.log_cli_handler = log_cli_handler + self.live_logs_context = catching_logs( + log_cli_handler, formatter=log_cli_formatter, level=log_cli_level + ) + else: + self.live_logs_context = _dummy_context_manager() + + +class _LiveLoggingStreamHandler(logging.StreamHandler): + """ + Custom StreamHandler used by the live logging feature: it will write a newline before the first log message + in each test. + + During live logging we must also explicitly disable stdout/stderr capturing otherwise it will get captured + and won't appear in the terminal. + """ + + def __init__(self, terminal_reporter, capture_manager): + """ + :param _pytest.terminal.TerminalReporter terminal_reporter: + :param _pytest.capture.CaptureManager capture_manager: + """ + logging.StreamHandler.__init__(self, stream=terminal_reporter) + self.capture_manager = capture_manager + self.reset() + self.set_when(None) + self._test_outcome_written = False + + def reset(self): + """Reset the handler; should be called before the start of each test""" + self._first_record_emitted = False + + def set_when(self, when): + """Prepares for the given test phase (setup/call/teardown)""" + self._when = when + self._section_name_shown = False + if when == "start": + self._test_outcome_written = False + + def emit(self, record): + if self.capture_manager is not None: + self.capture_manager.suspend_global_capture() + try: + if not self._first_record_emitted: + self.stream.write("\n") + self._first_record_emitted = True + elif self._when in ("teardown", "finish"): + if not self._test_outcome_written: + self._test_outcome_written = True + self.stream.write("\n") + if not self._section_name_shown and self._when: + self.stream.section("live log " + self._when, sep="-", bold=True) + self._section_name_shown = True + logging.StreamHandler.emit(self, record) + finally: + if self.capture_manager is not None: + self.capture_manager.resume_global_capture() diff --git a/Lib/site-packages/_pytest/main.py b/Lib/site-packages/_pytest/main.py new file mode 100644 index 0000000..105891e --- /dev/null +++ b/Lib/site-packages/_pytest/main.py @@ -0,0 +1,662 @@ +""" core implementation of testing process: init, session, runtest loop. """ +from __future__ import absolute_import, division, print_function + +import contextlib +import functools +import os +import pkgutil +import six +import sys + +import _pytest +from _pytest import nodes +import _pytest._code +import py + +from _pytest.config import directory_arg, UsageError, hookimpl +from _pytest.outcomes import exit +from _pytest.runner import collect_one_node + + +# exitcodes for the command line +EXIT_OK = 0 +EXIT_TESTSFAILED = 1 +EXIT_INTERRUPTED = 2 +EXIT_INTERNALERROR = 3 +EXIT_USAGEERROR = 4 +EXIT_NOTESTSCOLLECTED = 5 + + +def pytest_addoption(parser): + parser.addini( + "norecursedirs", + "directory patterns to avoid for recursion", + type="args", + default=[".*", "build", "dist", "CVS", "_darcs", "{arch}", "*.egg", "venv"], + ) + parser.addini( + "testpaths", + "directories to search for tests when no files or directories are given in the " + "command line.", + type="args", + default=[], + ) + # parser.addini("dirpatterns", + # "patterns specifying possible locations of test files", + # type="linelist", default=["**/test_*.txt", + # "**/test_*.py", "**/*_test.py"] + # ) + group = parser.getgroup("general", "running and selection options") + group._addoption( + "-x", + "--exitfirst", + action="store_const", + dest="maxfail", + const=1, + help="exit instantly on first error or failed test.", + ), + group._addoption( + "--maxfail", + metavar="num", + action="store", + type=int, + dest="maxfail", + default=0, + help="exit after first num failures or errors.", + ) + group._addoption( + "--strict", + action="store_true", + help="marks not registered in configuration file raise errors.", + ) + group._addoption( + "-c", + metavar="file", + type=str, + dest="inifilename", + help="load configuration from `file` instead of trying to locate one of the implicit " + "configuration files.", + ) + group._addoption( + "--continue-on-collection-errors", + action="store_true", + default=False, + dest="continue_on_collection_errors", + help="Force test execution even if collection errors occur.", + ) + group._addoption( + "--rootdir", + action="store", + dest="rootdir", + help="Define root directory for tests. Can be relative path: 'root_dir', './root_dir', " + "'root_dir/another_dir/'; absolute path: '/home/user/root_dir'; path with variables: " + "'$HOME/root_dir'.", + ) + + group = parser.getgroup("collect", "collection") + group.addoption( + "--collectonly", + "--collect-only", + action="store_true", + help="only collect tests, don't execute them.", + ), + group.addoption( + "--pyargs", + action="store_true", + help="try to interpret all arguments as python packages.", + ) + group.addoption( + "--ignore", + action="append", + metavar="path", + help="ignore path during collection (multi-allowed).", + ) + group.addoption( + "--deselect", + action="append", + metavar="nodeid_prefix", + help="deselect item during collection (multi-allowed).", + ) + # when changing this to --conf-cut-dir, config.py Conftest.setinitial + # needs upgrading as well + group.addoption( + "--confcutdir", + dest="confcutdir", + default=None, + metavar="dir", + type=functools.partial(directory_arg, optname="--confcutdir"), + help="only load conftest.py's relative to specified dir.", + ) + group.addoption( + "--noconftest", + action="store_true", + dest="noconftest", + default=False, + help="Don't load any conftest.py files.", + ) + group.addoption( + "--keepduplicates", + "--keep-duplicates", + action="store_true", + dest="keepduplicates", + default=False, + help="Keep duplicate tests.", + ) + group.addoption( + "--collect-in-virtualenv", + action="store_true", + dest="collect_in_virtualenv", + default=False, + help="Don't ignore tests in a local virtualenv directory", + ) + + group = parser.getgroup("debugconfig", "test session debugging and configuration") + group.addoption( + "--basetemp", + dest="basetemp", + default=None, + metavar="dir", + help="base temporary directory for this test run.", + ) + + +def pytest_configure(config): + __import__("pytest").config = config # compatibility + + +def wrap_session(config, doit): + """Skeleton command line program""" + session = Session(config) + session.exitstatus = EXIT_OK + initstate = 0 + try: + try: + config._do_configure() + initstate = 1 + config.hook.pytest_sessionstart(session=session) + initstate = 2 + session.exitstatus = doit(config, session) or 0 + except UsageError: + raise + except Failed: + session.exitstatus = EXIT_TESTSFAILED + except KeyboardInterrupt: + excinfo = _pytest._code.ExceptionInfo() + if initstate < 2 and isinstance(excinfo.value, exit.Exception): + sys.stderr.write("{}: {}\n".format(excinfo.typename, excinfo.value.msg)) + config.hook.pytest_keyboard_interrupt(excinfo=excinfo) + session.exitstatus = EXIT_INTERRUPTED + except: # noqa + excinfo = _pytest._code.ExceptionInfo() + config.notify_exception(excinfo, config.option) + session.exitstatus = EXIT_INTERNALERROR + if excinfo.errisinstance(SystemExit): + sys.stderr.write("mainloop: caught Spurious SystemExit!\n") + + finally: + excinfo = None # Explicitly break reference cycle. + session.startdir.chdir() + if initstate >= 2: + config.hook.pytest_sessionfinish( + session=session, exitstatus=session.exitstatus + ) + config._ensure_unconfigure() + return session.exitstatus + + +def pytest_cmdline_main(config): + return wrap_session(config, _main) + + +def _main(config, session): + """ default command line protocol for initialization, session, + running tests and reporting. """ + config.hook.pytest_collection(session=session) + config.hook.pytest_runtestloop(session=session) + + if session.testsfailed: + return EXIT_TESTSFAILED + elif session.testscollected == 0: + return EXIT_NOTESTSCOLLECTED + + +def pytest_collection(session): + return session.perform_collect() + + +def pytest_runtestloop(session): + if session.testsfailed and not session.config.option.continue_on_collection_errors: + raise session.Interrupted("%d errors during collection" % session.testsfailed) + + if session.config.option.collectonly: + return True + + for i, item in enumerate(session.items): + nextitem = session.items[i + 1] if i + 1 < len(session.items) else None + item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem) + if session.shouldfail: + raise session.Failed(session.shouldfail) + if session.shouldstop: + raise session.Interrupted(session.shouldstop) + return True + + +def _in_venv(path): + """Attempts to detect if ``path`` is the root of a Virtual Environment by + checking for the existence of the appropriate activate script""" + bindir = path.join("Scripts" if sys.platform.startswith("win") else "bin") + if not bindir.isdir(): + return False + activates = ( + "activate", + "activate.csh", + "activate.fish", + "Activate", + "Activate.bat", + "Activate.ps1", + ) + return any([fname.basename in activates for fname in bindir.listdir()]) + + +def pytest_ignore_collect(path, config): + ignore_paths = config._getconftest_pathlist("collect_ignore", path=path.dirpath()) + ignore_paths = ignore_paths or [] + excludeopt = config.getoption("ignore") + if excludeopt: + ignore_paths.extend([py.path.local(x) for x in excludeopt]) + + if py.path.local(path) in ignore_paths: + return True + + allow_in_venv = config.getoption("collect_in_virtualenv") + if _in_venv(path) and not allow_in_venv: + return True + + # Skip duplicate paths. + keepduplicates = config.getoption("keepduplicates") + duplicate_paths = config.pluginmanager._duplicatepaths + if not keepduplicates: + if path in duplicate_paths: + return True + else: + duplicate_paths.add(path) + + return False + + +def pytest_collection_modifyitems(items, config): + deselect_prefixes = tuple(config.getoption("deselect") or []) + if not deselect_prefixes: + return + + remaining = [] + deselected = [] + for colitem in items: + if colitem.nodeid.startswith(deselect_prefixes): + deselected.append(colitem) + else: + remaining.append(colitem) + + if deselected: + config.hook.pytest_deselected(items=deselected) + items[:] = remaining + + +@contextlib.contextmanager +def _patched_find_module(): + """Patch bug in pkgutil.ImpImporter.find_module + + When using pkgutil.find_loader on python<3.4 it removes symlinks + from the path due to a call to os.path.realpath. This is not consistent + with actually doing the import (in these versions, pkgutil and __import__ + did not share the same underlying code). This can break conftest + discovery for pytest where symlinks are involved. + + The only supported python<3.4 by pytest is python 2.7. + """ + if six.PY2: # python 3.4+ uses importlib instead + + def find_module_patched(self, fullname, path=None): + # Note: we ignore 'path' argument since it is only used via meta_path + subname = fullname.split(".")[-1] + if subname != fullname and self.path is None: + return None + if self.path is None: + path = None + else: + # original: path = [os.path.realpath(self.path)] + path = [self.path] + try: + file, filename, etc = pkgutil.imp.find_module(subname, path) + except ImportError: + return None + return pkgutil.ImpLoader(fullname, file, filename, etc) + + old_find_module = pkgutil.ImpImporter.find_module + pkgutil.ImpImporter.find_module = find_module_patched + try: + yield + finally: + pkgutil.ImpImporter.find_module = old_find_module + else: + yield + + +class FSHookProxy(object): + def __init__(self, fspath, pm, remove_mods): + self.fspath = fspath + self.pm = pm + self.remove_mods = remove_mods + + def __getattr__(self, name): + x = self.pm.subset_hook_caller(name, remove_plugins=self.remove_mods) + self.__dict__[name] = x + return x + + +class NoMatch(Exception): + """ raised if matching cannot locate a matching names. """ + + +class Interrupted(KeyboardInterrupt): + """ signals an interrupted test run. """ + + __module__ = "builtins" # for py3 + + +class Failed(Exception): + """ signals a stop as failed test run. """ + + +class Session(nodes.FSCollector): + Interrupted = Interrupted + Failed = Failed + + def __init__(self, config): + nodes.FSCollector.__init__( + self, config.rootdir, parent=None, config=config, session=self, nodeid="" + ) + self.testsfailed = 0 + self.testscollected = 0 + self.shouldstop = False + self.shouldfail = False + self.trace = config.trace.root.get("collection") + self._norecursepatterns = config.getini("norecursedirs") + self.startdir = py.path.local() + # Keep track of any collected nodes in here, so we don't duplicate fixtures + self._node_cache = {} + + self.config.pluginmanager.register(self, name="session") + + @hookimpl(tryfirst=True) + def pytest_collectstart(self): + if self.shouldfail: + raise self.Failed(self.shouldfail) + if self.shouldstop: + raise self.Interrupted(self.shouldstop) + + @hookimpl(tryfirst=True) + def pytest_runtest_logreport(self, report): + if report.failed and not hasattr(report, "wasxfail"): + self.testsfailed += 1 + maxfail = self.config.getvalue("maxfail") + if maxfail and self.testsfailed >= maxfail: + self.shouldfail = "stopping after %d failures" % (self.testsfailed) + + pytest_collectreport = pytest_runtest_logreport + + def isinitpath(self, path): + return path in self._initialpaths + + def gethookproxy(self, fspath): + # check if we have the common case of running + # hooks with all conftest.py files + pm = self.config.pluginmanager + my_conftestmodules = pm._getconftestmodules(fspath) + remove_mods = pm._conftest_plugins.difference(my_conftestmodules) + if remove_mods: + # one or more conftests are not in use at this fspath + proxy = FSHookProxy(fspath, pm, remove_mods) + else: + # all plugis are active for this fspath + proxy = self.config.hook + return proxy + + def perform_collect(self, args=None, genitems=True): + hook = self.config.hook + try: + items = self._perform_collect(args, genitems) + self.config.pluginmanager.check_pending() + hook.pytest_collection_modifyitems( + session=self, config=self.config, items=items + ) + finally: + hook.pytest_collection_finish(session=self) + self.testscollected = len(items) + return items + + def _perform_collect(self, args, genitems): + if args is None: + args = self.config.args + self.trace("perform_collect", self, args) + self.trace.root.indent += 1 + self._notfound = [] + self._initialpaths = set() + self._initialparts = [] + self.items = items = [] + for arg in args: + parts = self._parsearg(arg) + self._initialparts.append(parts) + self._initialpaths.add(parts[0]) + rep = collect_one_node(self) + self.ihook.pytest_collectreport(report=rep) + self.trace.root.indent -= 1 + if self._notfound: + errors = [] + for arg, exc in self._notfound: + line = "(no name %r in any of %r)" % (arg, exc.args[0]) + errors.append("not found: %s\n%s" % (arg, line)) + # XXX: test this + raise UsageError(*errors) + if not genitems: + return rep.result + else: + if rep.passed: + for node in rep.result: + self.items.extend(self.genitems(node)) + return items + + def collect(self): + for parts in self._initialparts: + arg = "::".join(map(str, parts)) + self.trace("processing argument", arg) + self.trace.root.indent += 1 + try: + for x in self._collect(arg): + yield x + except NoMatch: + # we are inside a make_report hook so + # we cannot directly pass through the exception + self._notfound.append((arg, sys.exc_info()[1])) + + self.trace.root.indent -= 1 + + def _collect(self, arg): + from _pytest.python import Package + + names = self._parsearg(arg) + argpath = names.pop(0) + paths = [] + + root = self + # Start with a Session root, and delve to argpath item (dir or file) + # and stack all Packages found on the way. + # No point in finding packages when collecting doctests + if not self.config.option.doctestmodules: + for parent in argpath.parts(): + pm = self.config.pluginmanager + if pm._confcutdir and pm._confcutdir.relto(parent): + continue + + if parent.isdir(): + pkginit = parent.join("__init__.py") + if pkginit.isfile(): + if pkginit in self._node_cache: + root = self._node_cache[pkginit] + else: + col = root._collectfile(pkginit) + if col and isinstance(col, Package): + root = col[0] + self._node_cache[root.fspath] = root + + # If it's a directory argument, recurse and look for any Subpackages. + # Let the Package collector deal with subnodes, don't collect here. + if argpath.check(dir=1): + assert not names, "invalid arg %r" % (arg,) + for path in argpath.visit( + fil=lambda x: x.check(file=1), rec=self._recurse, bf=True, sort=True + ): + pkginit = path.dirpath().join("__init__.py") + if pkginit.exists() and not any(x in pkginit.parts() for x in paths): + for x in root._collectfile(pkginit): + yield x + paths.append(x.fspath.dirpath()) + + if not any(x in path.parts() for x in paths): + for x in root._collectfile(path): + if (type(x), x.fspath) in self._node_cache: + yield self._node_cache[(type(x), x.fspath)] + else: + yield x + self._node_cache[(type(x), x.fspath)] = x + else: + assert argpath.check(file=1) + + if argpath in self._node_cache: + col = self._node_cache[argpath] + else: + col = root._collectfile(argpath) + if col: + self._node_cache[argpath] = col + for y in self.matchnodes(col, names): + yield y + + def _collectfile(self, path): + ihook = self.gethookproxy(path) + if not self.isinitpath(path): + if ihook.pytest_ignore_collect(path=path, config=self.config): + return () + return ihook.pytest_collect_file(path=path, parent=self) + + def _recurse(self, path): + ihook = self.gethookproxy(path.dirpath()) + if ihook.pytest_ignore_collect(path=path, config=self.config): + return + for pat in self._norecursepatterns: + if path.check(fnmatch=pat): + return False + ihook = self.gethookproxy(path) + ihook.pytest_collect_directory(path=path, parent=self) + return True + + def _tryconvertpyarg(self, x): + """Convert a dotted module name to path. + + """ + + try: + with _patched_find_module(): + loader = pkgutil.find_loader(x) + except ImportError: + return x + if loader is None: + return x + # This method is sometimes invoked when AssertionRewritingHook, which + # does not define a get_filename method, is already in place: + try: + with _patched_find_module(): + path = loader.get_filename(x) + except AttributeError: + # Retrieve path from AssertionRewritingHook: + path = loader.modules[x][0].co_filename + if loader.is_package(x): + path = os.path.dirname(path) + return path + + def _parsearg(self, arg): + """ return (fspath, names) tuple after checking the file exists. """ + parts = str(arg).split("::") + if self.config.option.pyargs: + parts[0] = self._tryconvertpyarg(parts[0]) + relpath = parts[0].replace("/", os.sep) + path = self.config.invocation_dir.join(relpath, abs=True) + if not path.check(): + if self.config.option.pyargs: + raise UsageError( + "file or package not found: " + arg + " (missing __init__.py?)" + ) + else: + raise UsageError("file not found: " + arg) + parts[0] = path + return parts + + def matchnodes(self, matching, names): + self.trace("matchnodes", matching, names) + self.trace.root.indent += 1 + nodes = self._matchnodes(matching, names) + num = len(nodes) + self.trace("matchnodes finished -> ", num, "nodes") + self.trace.root.indent -= 1 + if num == 0: + raise NoMatch(matching, names[:1]) + return nodes + + def _matchnodes(self, matching, names): + if not matching or not names: + return matching + name = names[0] + assert name + nextnames = names[1:] + resultnodes = [] + for node in matching: + if isinstance(node, nodes.Item): + if not names: + resultnodes.append(node) + continue + assert isinstance(node, nodes.Collector) + if node.nodeid in self._node_cache: + rep = self._node_cache[node.nodeid] + else: + rep = collect_one_node(node) + self._node_cache[node.nodeid] = rep + if rep.passed: + has_matched = False + for x in rep.result: + # TODO: remove parametrized workaround once collection structure contains parametrization + if x.name == name or x.name.split("[")[0] == name: + resultnodes.extend(self.matchnodes([x], nextnames)) + has_matched = True + # XXX accept IDs that don't have "()" for class instances + if not has_matched and len(rep.result) == 1 and x.name == "()": + nextnames.insert(0, name) + resultnodes.extend(self.matchnodes([x], nextnames)) + else: + # report collection failures here to avoid failing to run some test + # specified in the command line because the module could not be + # imported (#134) + node.ihook.pytest_collectreport(report=rep) + return resultnodes + + def genitems(self, node): + self.trace("genitems", node) + if isinstance(node, nodes.Item): + node.ihook.pytest_itemcollected(item=node) + yield node + else: + assert isinstance(node, nodes.Collector) + rep = collect_one_node(node) + if rep.passed: + for subnode in rep.result: + for x in self.genitems(subnode): + yield x + node.ihook.pytest_collectreport(report=rep) diff --git a/Lib/site-packages/_pytest/mark/__init__.py b/Lib/site-packages/_pytest/mark/__init__.py new file mode 100644 index 0000000..e3918ca --- /dev/null +++ b/Lib/site-packages/_pytest/mark/__init__.py @@ -0,0 +1,174 @@ +""" generic mechanism for marking and selecting python functions. """ +from __future__ import absolute_import, division, print_function +from _pytest.config import UsageError +from .structures import ( + ParameterSet, + EMPTY_PARAMETERSET_OPTION, + MARK_GEN, + Mark, + MarkInfo, + MarkDecorator, + MarkGenerator, + transfer_markers, + get_empty_parameterset_mark, +) +from .legacy import matchkeyword, matchmark + +__all__ = [ + "Mark", + "MarkInfo", + "MarkDecorator", + "MarkGenerator", + "transfer_markers", + "get_empty_parameterset_mark", +] + + +class MarkerError(Exception): + + """Error in use of a pytest marker/attribute.""" + + +def param(*values, **kw): + """Specify a parameter in `pytest.mark.parametrize`_ calls or + :ref:`parametrized fixtures `. + + .. code-block:: python + + @pytest.mark.parametrize("test_input,expected", [ + ("3+5", 8), + pytest.param("6*9", 42, marks=pytest.mark.xfail), + ]) + def test_eval(test_input, expected): + assert eval(test_input) == expected + + :param values: variable args of the values of the parameter set, in order. + :keyword marks: a single mark or a list of marks to be applied to this parameter set. + :keyword str id: the id to attribute to this parameter set. + """ + return ParameterSet.param(*values, **kw) + + +def pytest_addoption(parser): + group = parser.getgroup("general") + group._addoption( + "-k", + action="store", + dest="keyword", + default="", + metavar="EXPRESSION", + help="only run tests which match the given substring expression. " + "An expression is a python evaluatable expression " + "where all names are substring-matched against test names " + "and their parent classes. Example: -k 'test_method or test_" + "other' matches all test functions and classes whose name " + "contains 'test_method' or 'test_other', while -k 'not test_method' " + "matches those that don't contain 'test_method' in their names. " + "Additionally keywords are matched to classes and functions " + "containing extra names in their 'extra_keyword_matches' set, " + "as well as functions which have names assigned directly to them.", + ) + + group._addoption( + "-m", + action="store", + dest="markexpr", + default="", + metavar="MARKEXPR", + help="only run tests matching given mark expression. " + "example: -m 'mark1 and not mark2'.", + ) + + group.addoption( + "--markers", + action="store_true", + help="show markers (builtin, plugin and per-project ones).", + ) + + parser.addini("markers", "markers for test functions", "linelist") + parser.addini(EMPTY_PARAMETERSET_OPTION, "default marker for empty parametersets") + + +def pytest_cmdline_main(config): + import _pytest.config + + if config.option.markers: + config._do_configure() + tw = _pytest.config.create_terminal_writer(config) + for line in config.getini("markers"): + parts = line.split(":", 1) + name = parts[0] + rest = parts[1] if len(parts) == 2 else "" + tw.write("@pytest.mark.%s:" % name, bold=True) + tw.line(rest) + tw.line() + config._ensure_unconfigure() + return 0 + + +pytest_cmdline_main.tryfirst = True + + +def deselect_by_keyword(items, config): + keywordexpr = config.option.keyword.lstrip() + if keywordexpr.startswith("-"): + keywordexpr = "not " + keywordexpr[1:] + selectuntil = False + if keywordexpr[-1:] == ":": + selectuntil = True + keywordexpr = keywordexpr[:-1] + + remaining = [] + deselected = [] + for colitem in items: + if keywordexpr and not matchkeyword(colitem, keywordexpr): + deselected.append(colitem) + else: + if selectuntil: + keywordexpr = None + remaining.append(colitem) + + if deselected: + config.hook.pytest_deselected(items=deselected) + items[:] = remaining + + +def deselect_by_mark(items, config): + matchexpr = config.option.markexpr + if not matchexpr: + return + + remaining = [] + deselected = [] + for item in items: + if matchmark(item, matchexpr): + remaining.append(item) + else: + deselected.append(item) + + if deselected: + config.hook.pytest_deselected(items=deselected) + items[:] = remaining + + +def pytest_collection_modifyitems(items, config): + deselect_by_keyword(items, config) + deselect_by_mark(items, config) + + +def pytest_configure(config): + config._old_mark_config = MARK_GEN._config + if config.option.strict: + MARK_GEN._config = config + + empty_parameterset = config.getini(EMPTY_PARAMETERSET_OPTION) + + if empty_parameterset not in ("skip", "xfail", None, ""): + raise UsageError( + "{!s} must be one of skip and xfail," + " but it is {!r}".format(EMPTY_PARAMETERSET_OPTION, empty_parameterset) + ) + + +def pytest_unconfigure(config): + MARK_GEN._config = getattr(config, "_old_mark_config", None) diff --git a/Lib/site-packages/_pytest/mark/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/_pytest/mark/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb6e1aaf1354397eb66a247e65c500369e7f0a9c GIT binary patch literal 4953 zcmaJ_OLyDG6$U^M1gVE<*|9A#8hGuCrun4JFye9Zkk&0v6MDJlmkPYAqfc& zdN8yep}MG&bGk`aUG#KQY1y9B{*e9zY`gMb$fo`70HkE44I~WaJ$LSR?{{bT;mk}; z!_z*HUoM~5w0~1!{8-4`!JGaI3DaDS>C6cA$Z(CQ{P_8hWRauQqvFV=W zp1-fL88-Wk#%B2o2PO9cJHzVVXzoRJmd)XNiJfET@ttQc@OketyTC4@bcJ1F^Z35V zF0(86US%(`tN31H*Vs$=zQmkWt?}~S2TqU2Tm&5_;+?)92WjMV6X8U@*b3sF&M_h8T%4Ig+e(-SZ3-96GM|U5z*V>O(+iTvZ57$2a zbS1MN+Iif_J)y7N51UzxA^XMB3M>cC2A66CSr<`X-Z}&nWf|mk`CU3H7XG;t9UsO0<4KWeRimO=sR?Umnr z;k^0o`rX0co-h6NUndKW^64 z@MhELB#bX_gh^+s)hdiVZ=>n&{2wtEuM+ihw9{Rj}V@ZLY-afhHPS+2@6QjRsOeSKy>nI`kQ$JihA&xVa zr_q{pCTaW>79gEd-5bvB+mjLb##>4-2h$FD+QL@^{zk|hU-Y1NtlH;Az-og*7;r`<*$>ha=7BX% z&74Z%1gxbb3)GN_``CNLCG-*VNF2P%(6zIw+#zSD zM;Sl9AK^_Il96_Z*l?up>mz*=af6j8IxvfP{yW49Ra-@E4YlC>Nv%P=Pi+5P3B9z# z5-~nIcT|+5$<7}ch!+|h=!F%xqL|zd_l)JOtek=ac~%+om*&>mpFe!mUR?!=`l}E! ziNjq-3}acfedO0 zE+G>+9)ZcZ0E%Jg5Hq1aN|UMKhFBEn`aPdGM+r3Ui0}gw3j{&VW9f84GF=3o_KqJ7 zLf&$gx10rK@rWM%gpm=cVuEpEA>R=#iN&e@IC!bpR?G(p6R<8x2NH-S3G&>u3p8)O zPCoGxX$-rh<>Mq5+RH^aUK9dhR@wKZ!;*Lb;^%Xpni@WmZ&GOo`eiJj_zIbKodUsJ zX=7Ev5yp~JgdWG%bi6>07(!m5$H@u{dN6kh#vwU?j$V>)ZXB7~WKMaw9W_*xGX7+hFfQ3exO%6^r z;;N8N*17lSlu;`2XfL@nDv~%htEK}R8(Tr-EKu{C3RMDxN;ejod(~yd^Az!G$|*c4 zhJ5esw4ZFNPH1r!H-ELhVxBgdAc>dY(c&jauqWDp zNcS!m8Fg@a-o{)z3}Q}{w)bkGi(*aHS)D$P*$iZsHp;GzgGo;$!+~4#e8!Ri*@9a= z&RWPK>Y{<( z6NV$6EaO!S_h)2q^3_5O{DzReX^1}&R~>1J+04W8NCWp7I~%CAm~o`v)4p2UFO5ov z6=K38W8WN^OrO{G%hDd12RbWn8DbrE=DZdg%-Xj`#%7gOM&%0{os7Q&=Z%cR+Q>T6 z^Bk@91?(*=QQE7-Jq9QISy(rcLoP5FK@u{BD38H8C?aDoDqmer02yOmA? zyWr6eU>x`HHg?CHJ-{;QD@ZgzRs)2ldZ!H&xtcz!=eb#w;kX~7-vm!G{|TOb6mmQX z%d}1o14K%M%+8WRp>3iWviK5SW$83bf=ovG0jNf*TMFeArRXaN0;E+z6Cghk_cVA{$3B>Z z>i(R>bWg+mMw#7TFghhLh=oNP-wD5xFcW^gg+hK+@(l26Y10%JMyT;1)?rz~9q3%i z^sS1xDJ#r4w52uDkBkHT_h4nZX3}lZOt*r8TUJ+ym7M%;eEo8|??gi!iEzS3e4|4* zbyKlV^;~jr-E;!{r_R?ei~UAbR3T1QDX1^2d*DiSVJ>PExS2&x)RE$KbXGx1&~`El zKP(`kLublM=6-nhKCQxW?3!@mUonrmO%trPZW%Q&nE`;sCuo^ykVv0&tKg(-DZxom z>YyZb&ro_XR>UvSf@?Sq&XVp3YIEW~Rq9H_)8fn(h@K$nf1r1M4ba5{+f}^Zw^&;A$wCR4)z literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/mark/__pycache__/evaluate.cpython-37.pyc b/Lib/site-packages/_pytest/mark/__pycache__/evaluate.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e0921fbef2ae56314f499b6a9648802b2146b7fc GIT binary patch literal 3524 zcmaJ@&vP6{74Gi&soj+<$+BcQAuJFVY^bOpKoX1-9BjoH z?P>m-e=afh1$E9I8;v{o^ezg?Bu`kUs(FW-zUT;3TOG^PcE^@NT8T4sJMPfyc$`UF zI!{=~zt5yAy(dh1(ZbZ~)Fj_wE&myIX6{ymDE6%c7E^m2?=z{jg)`I8{VbTkG4MRDMaUSV>E9hZi=~R{1%Z8&ki4-Z*a!a?DrTusxyB>{H z$z{iz{nqhm#Qe&S{=w8T)<1u6_g4249Vy-2ZvXnT=6B!eelQx{3-hr1i>wzW-Q8$7 z>W<>kn{lf1FiGBg^sda*TW|lcTglR$ZQdP*>Yz)C9EN$cH5!+7qoFj)5*_p^3dU>P zrJrofmR)7&)3LtKgnNi!3-EpKNU9`af>7(}Kf~=wT zWnDH9 ziblb~3E)V~Fr_F2+Mp@6;q8`P+HoEYOE(~EXdpy20H-QQ!(r62N?S)sU#(%g(xxGU zLshKMpdSQr8s|Z99X(C#WH1@Mll2R7Zk;Xc5sT=dnuIn2H_#wDpYT&QCBJ}x@P@rC zOCZsHlvhHwxT1qzA_c7sg4Zyq$qG!ocz(6y|DR9p)F1Lk%Ee z`TG3a7xX?`a^YNxD@Jd!Ea^Sq1AsHIB!9|{{-TXDH|c2Ll*BqWAaojlOc`6i3)BY9 zztkj(81PMel{NU}`Xw~xChZw>VI^TP$Ab(BG!R}+`7wy2SBW+`LIj12GYh#YjCG`e zl!g7uTC9!Zr9Dum0*dxgU!#H?_#AN>acV4Qc6bAGGxF59jdyb6qPXW5&kad}ldl>> z{uPa}Pa>Z}P((kD==YZ@`sL!pIwe1_a|cGYB_d?*PKA0P$>^p(@T9fD))1^W*gijo zq9?v|PB~}kTD~x#$Z8|NyMGj$?9c3&=XL2}tbuP)`X@^T4Ar;R8M*aS!P#dl6|*Q> zZ$BfhKj+P7g!^;;yU8m%<1`PCOr*TkoN3q8W>Aq{lW&>1<}60V>3;L3YEnpyw2rg1 z*2HsD*KX>P*FJ3Vj)w@RLKyx^=>gQxA-K^i& zfY1#`qbQZ-g4t{@>>ZTX@YgWR18fnEa-1DxX);zs6+=L^NW0mCEKXa(pk7)-y?+^S zw-V|*Sggs183L=1z*^(W{047`HS`6_$=W68jV>2Jr<=xr{uUZJpw5l&5RiYf0S$p{ zN$^x{0Y;a418?9Hm<7cai-MoXwE8ywFa1#x=A@&dAXHk}-k`Ohet@=_S8r2`{M5{w za8SC3BZ-?sy+eQ0gJ3_&_QFI5!OQ{*iNp((uTvbGt^5G%+@a7d`h_92JGY>YUOAtoCxhu*d~q&p+XW`YA)=V2D3h!U}t89Xsi3(l&c~>hIDy zcJnKRJB7XT<-(eBN-9)W0*L?;44jh{ zqqKR5n6=-eyCDiw-3)bezL(zGZCy2hs~^GICZ?)u)LKVTx(AO#wXaK?O5+8}IF_a3 zqp|_oV&fnmk0PyZ(NB~+oFkHPpjT+@>r}jlqUBZoV-Il!s~^)aIakFdBf|Hndoh$M zik|oJX*#9KS!#l=;08YAF2WU*$28z>tD+`s)IMUY3)W#CeQMSC~kYUU( zuIhpqAip^9)lvaK03iT65p+eI5jnT$*3O!zsm}dJraDH z$W993LRh&d96V|678Eb%a@|I!atq0()@U7sd?iaG>5+z)ehXn!Bq5vuQVM6Uj5Ii~zlWIoYz_#iu zC@3_g@P$ZaL7=`$!;}}O*QxkE6^58Zpo)Y)rPlxGWm=TysjDa`+t9>(@W=ISTlf}U z*I&VRv*wsJt$GzX?_k-v@JUg><7bCC(to&vp*}%od;*ux-XQAbW`mcVUi!ByP2Z<` QR8wpv3Y%9fTmIsI0rs&SS^xk5 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/mark/__pycache__/legacy.cpython-37.pyc b/Lib/site-packages/_pytest/mark/__pycache__/legacy.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f56bd1b5c9f5d737939f4668a56de04bd8047c7a GIT binary patch literal 3316 zcmai0(Qezw6`dg|iJ}xGo3^`&n*sxDTSq|RZd;)320@TbHrW>Kx(1wGcUdnOhBLNk zQ=~jY*_Kv%S*JhHFR)(<6zCW6wLpRWg*^4#p`;{ku%$gCa^`Y)@45G!nMYTy1Ps@c zv+}S1=`i+hdRSf!+&n}x5}jlrlUzC(54rtyLI=NY<_^8k<4o~`#%D}=vhkA1hH9R< zXFP0Sq$yh%Y0*gNOJBBSuAQ{YCldUA|9nCfaRbVDN&R{t6_1hg74ry+wAiy z_`<~d>WS8cPH1d-xwv_VX6~R<3;{9Mrpo3-P_W|aVp_iEV3erGcl}Z#9pCsuMd?ri-^)v4Mm(J%9udlLOexwj91G- zJkw(((mhcQ)Z#5dWCRnHmm4B+;3r+=IJL)UW(^%><|Ui)b9TW#g}ZZS#%9hLhpX;p z!eK!dy-u%fqnYdI25iQ@4(5Eu57^(GBX67ilL0R;kB6%7RL;gnl}Fxd55~58_2uJx zyI&ZDv-@Q8%df;Qf4lq1X!I%4v->9seD|3ej&?`s=x&;uGS0HQN57MW{?%_j-W^R! zWy;-X@k{IO)(PAgOYJjiL`QZ=+{?`oWt%ykWE14=O*h z3rA5EMA5L2<4obc8%0OsIHO4M)QTcmB)IY7vecE6zR*{&eAP*^*qEUz2ZhvKa_H*Y zUfFaLJetY{`oIi5`L5^qPPbu46AY{_GJA;jKTN9m6MCvq^9M|7*3uBRqz|y#Rqu~# za#CoyB-6?FlIgHEHXD{apQXnt7a(0~N>S_yo8mjfJ`v{=Va6|@8ek~R6*%Kqeu`gR4bIxw`1K{+N{1!ck7~Pq4uaQ-svaN?PD~{Dh3aI z{7u&`dG;3LeSHlt==Z22rP4p3ju>Xg~q$&jOYZ|-V_ce`HPN9*XTvl#glq(FV zUYlqZ1NvSGg-cn9>YK3(e&!MvrjMTKwBEUfF$w?_v$U%#qozFq2cq%TWm+kTK{t%sIgj=l{?S0NCMNVTlNzibHS z5a|nSjuJcGVN0*gkj|T+HIYg>7hFH38R<&zZ_Z5yi>G9rl zlful!n_DxtY~qcrvLzemK8>C6Z~4*I4x4n#Hh~8^0XC17!C|2P!5RI*x(RDuTYtrJ z=Px)+0o+zR1L-c|TSK>Cj!?h_rw9;|pk2Y5siefI!=f8lmE1`)I*}|gL^+_!Br#mz zd`F~tl8q%P<#O84d|Kl85o?@27J~cdJe$-@A@5fAYBM#Y^G%8xfVEI5R?#9B_v}t{ z@A+feaGnde6s z1tba1*!4;L34l8yhF=QdrP7j^! zNnXaM_Bh=4^g71E&SEigu4*j~uc3Q*A}0eMs)V3?V i;SlAeKE?U>>m$$u8nQ=Qk2KZkLizox*M1hbe&fFy^;ydR literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/mark/__pycache__/structures.cpython-37.pyc b/Lib/site-packages/_pytest/mark/__pycache__/structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e5c3b5ff0a7796b8acaf97f6db20bc12f6a9ef2 GIT binary patch literal 15056 zcmb7LTW}m#TJFnSS|eGOWyN-`+i_yYCJ=HgVNV)&1@d39zuJfI;&n(B{liLt{zrX>c9i5I;W=9L0lhu!%{Qq&;v^y3S4za z&F(t8ZuLmutshl~)!aiH?;le~@cu|}Y}ehjtB>;?o*q@l@bp;n^a=I2dIIA;sh(6% z;rf(%T0Mj7)9NeA$MqTYtU8YCSJZRrd0hQuloRSCMmd>`@+`)EL7l>rQ+!fA9vt7b zs?XtRS)Iny)4@SJeO{pZs`{!r^U%S&v#Nr3m1K+)%D!!t&wWO`FO==L)UIy^D%$F{ z0^AjJpte@nD%GP%uLe;R=+7MVEj#g(H!k0Lv-bAoTbFNKUA%hh_SMDOI}2}Le*Mks z3va}S<>mE-Yd33`7Z-0`f9;*ct7SJXEZkf~$9NJ$HNsZ29ke^~)Qx(#+ib7iXx?wO zF_*hp?^cfmo84%;)~#y*gjs805Y;y8dSivt^XKBoCD-sg8j;nvcJ1$5-?P4FHymXv z=YhB5MD{0Om<>-q|B2Oh`i^q@)=^949y(ZfeqjatB|ly{++iHy5u74xou6WuhmLK1 zB7@@-cR}azmN*Hc`pQNt_$X)r9p1gVZetZ;oMQ{`b79bG;7!5cEiNWK{>J*e`uhBx zcfvr2cdjmc^L_uNSMFTycCXZ<`kl8rEA`f$MXdf#x7j`0Y-5sE>+IdHtByYZ@;B~u zx1%78?$nYiF>)u2^wvtWrGv22-Hr>KCQx%+2Nz`7({}H%daGFvD;HWEKD<~leR?H% z>^C~vC*oCSrR->a6nkCW=>|I52Gw$83VjHVHAmI6IHBJR+wzn+i}NxT??XzjWqZza zP9H<-3pjqAou0snBvbaT(>WH|Xn{Dpu5veA;5oMtd$k&%ZPjXQ5r$f==Ur&kH>ao7Dtn`#pNO1wcPH0=2KUZ}qtD?!r(7_Tji+9e??dK4wxdGd*|qODJNcc0 z%J=QQvtI1y`-MjCh_zGf=lVrecu2V`E&#jM0yt%(*^Tq}8}(-E8VRAd+P!nDoyZp{ z@G~j!AqD;kea7cfqGqSWGWy2V1?^+8`dOUf$+tS4jjirgtvgyz@G;56@m4zRMsqdx>Ux!=2=&u=QJvPo z-7TOtP$Hahjtm()jW8}4>DJG25OT~AJ)Q);YGVSP%J*?}72dGylI_XAX~(mtYzO~x zI6Oz6MV}QM*^dOhgd?OL2rQb2ssj~G9RQtB&7nP^aw`A8#$6tF1yz(c1?7PdrFiP? zRMXrJqKsk5$YhC|9QzhdeP<60tDHy9jtiD`BWKsqV21{nq&+83+$b028}64%7sDtqjF;BS|yWLJVhU|zEYOe(G zfg6DHO0d$=^{Aucyx562*MfM(E(jP;Uk;(w$e6-GTeTepLYt@2ygF5#wphu29^m^aj19c-%Y(0;oK#G6Ic^vQ8i!|$x zY@6+Z!n2*+-E;49^jzfO+g>#BF$7*e0JTYTSN}m&+MA4~Sfv^Li^Vv)Gsr#*9wZ5|LhtYN`80qLoYfuB5^=%)joR>C~$8vyAghppZ$7!p5 zy57?;!-4Xf?WlwAAmX9lX`rLt@H@-v!AcaCvSAWf4Lmj2kCmV%GmSzVwB?ln!j~Cf zBK@%AgQ-@r256J5&7d76Jq({@vvAR>(|#fHp)h;}#@p<6LcmzZ3YMYkHhk*!A-EPk z`#F9vPQqsAzy;+4`fIr8U*YKjPH}RHqPu*siZb^XH(eL$H>-!67<}( zU2<}`PT}yKY24@R0-ltd-s2-uFg(TzWq?1*K@o?GBm8@u4EIM)1NtgFXY^v<-h;7y zWM6@X+#$C^H>%u*^L?ugO-VnhVM9;Ci|RYlC;yvHKd*oL{-a|kG z$+G+T2EDV1fpyf1~IIq9&+|Aui927gw!!c@h;V3wj zbFqDY4E>*%E>Llir!KBxL{XFltM}3fddb_V7pj}RV4yPxUw>|&`HZUiTBf`SE}4aD zS&W&0I}0qssqEXIAZ&T)7+}kG+14aJm{xf1s%gK0i~e=C?RauXz|1N*u)dDdCJqC+ z-CMlg_KzoQNm!3VD+GRfYjZi!6lEh_{;6;8l>N=EP!t5rcfI99;zzrRiI<*bSI={@ zfj~_efufSuFXIF}cUw(ZfL73!zH#ZB)c0Zn;sRjbtVd$A^+kRot0ae(JrN~cM!Py; zWCUhHJPUn_BbNq3CbFwfa{yXAAnh%-iHLY+oJs+nhR1QTAUbpQw3CCk=Q)mCXX!{d zvjvLQQ%>*cUr28RMc2wj@q*$~t+v@wTP^sZ@l>rw%o(pVo?L0w!w`YWT1Oc`NkvVM zVTkK8OD!m%LJElnI5*RdJ@u?S?Hw{yIwOiVJmWXjA{{%Zh+fcMLHF!O;l6|;q?#Kz zJ?pt3uk43*wGg;_xkpyDm|Q*j*N7(J2tl~=`q%IohR#LX-5`sqQqCnuhUanWTkDX> zb!)>3XCgYcjy$o}VKvv?qZV|4wVrQ)tJm|N+TzjJy`N<&JTVj1qrLVtPNH)@^srA`elMgnomDxZ+M5mqwH z46~2R1$`7NG+Lh6(3f$FbE>%#>DSPNNFL;qyZ|&rN#VK!$>gfWCHx*bn!v}K0fY5s z320@c%R;#%jHGX)uU_QHIf-AK<}&=JNE>hngiNoiYzfy4P9pgP_PaO?|F~0*hkruQ z5e}ioyu@y6IHeq-?5Z2UvB6Q;D+b;pI5*&yiJ*k&%dSr1n!|MpSE%;tfnYjwmJcdV zO@M=DBtK$R4<-4L*(5)5Sj~X54vDR;{}+sre_5=yxQh~H(p+c3iy@Ib68S;=>ih4m z1#ObD)eMwSsu_VrS}lJC_C5;ydFeX8MD$*Vd$E){C;q*)=E|BlHp_v0Ij@7p{E`k} z1rVgeW7ziB5Z++g&~HY;roRzv-|J`<`WJ%xh;Jg@X)zMJxKxqvIYs8}!Y@K74lfv= zYp`e|0-OdW<+qv}0eGw#&d(2gq)mMOlK-l2LiGx7D+@@L(5o5zo`Wm2iFAuFb~ana zqx|apK7*X1=6UH=Q5I$Yxzrh?+E-&k$yoH5R_bjELR%a|gJGhAew9!t6gx0Nq2cvh z5?C_GRL~IbtCq&1r^=(wUl%ITV8hUK6s!!NelrAQtrlHRIC&i)n9|zlv|62ekk@q3 zmn#1CM%t4S=hss&Qdq)J6+Uabwe7=AY%&aiZG$c_E+$dX?qu-$b*0ii2_s~Esdpm; z)=2QI0iI^WR8DFo&1~>to6%q}IH+KZ6scQL2R5(CWo`2_Tm@GEKg4*A&K6*4k{a;Z zWjw=izJLD9SDE7Zms#ilur_A@r59Qk8d0ngsY=#77%m0k4D@$9sw2ffeaq#6W+|$H zi58?)F;eLuhsc;B&>#k|(QFR}<2N^kg)GIw*D6L2qJgj0s%o@OPekf=}xTe{7U;GU1pK43{iPJ2b)nQn$;JmBilOyfdhJY)~W6kfu! zf5u_*98T}Z2(m=$a{dtq$3=gcC&@udVn83kj7SQsBeQoKNgmAYEL?;8`!)17;Um4z z#3#`2^XaHrjtjL~aJN?b7raW-E_0*cm<}V0rpG0~OrfEWu~x@{P{OESC`giAsm{fl@H%nG|ic#bQ#tAuD14#42r3PRR3q6Y3Vy5O#)> z1n5{7si`lwf)|CU2V=t8Q?iYRn1Pc`nK-<{O7R3T%kvxYS3D0cj*Rvi1-lBio#V zi_K7+8Rn%3x#wLwJm1fucTQh{yA66E=tfPVeGHlA>~8o?AL%9ZDk79d!V#?G_I^N= zCYq?88BP#@xXdUupLzoUb){&6O^7fwW22KQXXCqwGQQUg@vTz+X=3EX)2EG4qx;!z zs}4m2otJ&jFc6x#;%myeeiJ7omW%MK5Pw8yghCU&z_-lIv%&)NA(>^NQ~a2DkR)3; zG6B=e94bFfK1on}&Crl~Ojh;d_~zengmXAqE;G#~`xrvPY2+Lk8jfp{v>35ao*Vb# zi?td`Ct#)zFqFQ7Q?-;S!LT}+x{kF@L!5NObS#aGd;Bas=}SD-cv|9#s}pdCmLOay z`j27cPjSdPyk~RBl}gs!naX)C{!NPN%Gi+FhT<+7=Xo?J>dIcVAm~to$dNKb^iV`c`48y5q_VnpQ05CXXNc$Rg96cG6^{7*cWsL0AObzHDD zWi4AiIWJSV%;_bmFpCK;k(1vQXftp^Ss&bv#7m~FT?<<9J;YlU<{rt8&PxQ#=K}J) z{}z_=!8>hm{s%Yk^o&^Z%;)~_Lz!W+fvYpdT4F(98^n4*<48PZvdW2r zN$Ryw;GzBrU(AqC?@encpVqceVF5}+ti2=yB>7A3(F~t~%5}E)LuG&$KgVIrL2lO7 ze3C7kYCn^?W!z*7M?p~`ivkiN1eekwvMJ1@un@W<)oN6(eMFP_7-GU3u~R03iLRyHPB%K@*K{fVWB)UgCseX_zVuswGA(1nK^pt?j(h)kpb=IUcgJ9T;ez#ZP=d#p>SD{b?jC#Bx?6fT@d|tYBbX7k zOL66+=GG43UxTOUSpenO7mz3qgJ_dG9DN}JNyQ}_Xz(FzTk7o_KPTmM(sYxW*wlNG z`q)nNu&Ce;iX)wkz(iW?i>(2j))u+nIIy^!$G8Jk~u+jnYZJ|9PKYU9$3a{X_ zeGCMH6d{j}T>7rNj;h^`gF3@p&WfCkl0IW2mVhL{k$=yMT&ZNR3Y%0iMAhfv!rn@P z!9~3Vho|Asa~1Q?^8`^WgQbQRrA*U%4#?@wMhrpb&7=qdNNg>49o}w!R2>q?zp%h8rceCFJRhViiLYgVW zRy5hym1CeC7m)|8Z?&RcRt}JS2d3gysG+Bl`Z$`yztYP|1s z(}!cqWg;)5VX5xmi?;~9jOPr&pIX_>l^nsJ$vNy{wsjNOBj<2Xat`7rkp9?dWe6_1 zV_ytPobq-yy*)I2mTMSZD5)b0Wt4}h8TpFqg0=(RMH}89_!#7Ldgmm<97;_}SW4}= z+GMJLh!s!9ptRzX0e%}Jn{p$;mP!iNA=KXwe|OR8HWxq4)KbLTX&*L<# z@|9DSJ$O*WQ1GgND+~ZQr)c&oy#Z?`<&FAT%nai#tCDKem+0Y?SZApr&3+S;wXOS0 zOGDM1rKKc~62Y%ZV|AsD>=f7Do{ zMg~XPM>aei=!FqWLq<%iWikbzrW7qLanh`egH;&>K#(#QjM&dSXa+_mYb7}<1R<;( zV%rmx2)5cz=u_$TDjUuh>=3qYZVMZU-Gv(OrLp#`Y}Y2%Ix!FIpQ-KBeZ*5)5MD#s0F{oG#Rk-3ti)8~1Fc-TC{ z5by45?}7p{b5Z{&!Zw}0&7?7@Aa=gE5Ep6kfWFV|dC9d2+CR5X^`1BZlq06ALlLba zIf0sh$>IbW`8Y3i$_3Z@6|7Q!!V~3A-@pmGOl4zD>_Ri5hAv7~Fh0+>*bdkZ;)0o7 zcCd_5LVuqlkpfJ=TabQk^rWLVWzQmd^CXf3MI?7VL=ho&vKeDgLpQoiK>Ps*meKc9 zKHtUL4>>JK=#_F%KVDJu>Hdo5ExZ{h8tj9@mPO-FLg5%igFhxvo+z9NRl>EXCe;+K zo;skWah)(eW3{9XK_Sh?QwtpxyqQ#;Gq$2|@esBWlSuPN51v=C0e~Lj;5%>|>V~A&Q00q0KR{Ji|KyJ2xbr0Lahv5S2n_eRTW_(ZS z-!75&`p8?~246?y_w$C|@f_g>k`^aFre()|Y18XH<9~{CMlfR!XfPRqKa|_F7N5W$ zyLd1TzY$@2mbKdNa0zr@3wp?cxg_g6wHD`g9$!mJ1n#wiZOX zhO>WyK6;0z0aK+41^U(u|3gAU8d_h3A?q}P&y3()12m|le^MX)I7;;tQ5CeX!;t$F zU|$B?6}UkKF2PNFnUY(e{33uDzySE;UjSg%Df4hfIFk7lZiRqk5-@iaiVw8SO+Azplk zlakF)xyXB-)Gcye!E-g=USlC(WwRUSkgZxU4wCULhzZ+nbV1 z05r1E+@(ZwPpS#9O(~uv&Wt}2_SVHcN;fUQBf;O-Y(+@OAehQ3?lf@NcNVld?N$6Y z&O8xqQgs#i8yh(G!*1Xf_Yg_Ft=lx+K#E#ip=Y;vIlW9Z)?_h`~LXJHE^A8yhxQ6``yj0A*8LWhp#|jQ{ z%kMu!RSKtOj=5{@bVUghIXB5dd0G1Oy$sSu6L~P>DPWfka$Q&rQHWhU*kvG=&D>{S zw1WWqwd%k-{}#=cDr5GN0{1fjBi0aEr-5g(Pt1ou6~gTQ$hC?k%uhk!dox3PP+^Dt z<&M51bC6U?M(sHI&p0!u{}S<{MEp~RTDUjEQw?IZsd4EVi`BlvXq7JskNmeEH z_;+F4-64M{CP8FeQb>gaE8GAho8&bkMgGmuW*1w3sZY%x6A^&wMA*Dv*~I>q(1f}t z`1%-6^nJ`m;R;%@jh*u*6fvnBmO3T-EOjNRu}Jz^vc-}lG+{GcI!&V?>O+<}#O9gm zLEgut-;lE2kz5^_&@O9G-G>ZmHxIz1btT=4|f>3Jf>AlKea19rUJf|J9ij L1$XAe5&QoDCNWt* literal 0 HcmV?d00001 diff --git a/Lib/site-packages/_pytest/mark/evaluate.py b/Lib/site-packages/_pytest/mark/evaluate.py new file mode 100644 index 0000000..d4bfdaf --- /dev/null +++ b/Lib/site-packages/_pytest/mark/evaluate.py @@ -0,0 +1,120 @@ +import os +import six +import sys +import platform +import traceback + +from ..outcomes import fail, TEST_OUTCOME + + +def cached_eval(config, expr, d): + if not hasattr(config, "_evalcache"): + config._evalcache = {} + try: + return config._evalcache[expr] + except KeyError: + import _pytest._code + + exprcode = _pytest._code.compile(expr, mode="eval") + config._evalcache[expr] = x = eval(exprcode, d) + return x + + +class MarkEvaluator(object): + def __init__(self, item, name): + self.item = item + self._marks = None + self._mark = None + self._mark_name = name + + def __bool__(self): + # dont cache here to prevent staleness + return bool(self._get_marks()) + + __nonzero__ = __bool__ + + def wasvalid(self): + return not hasattr(self, "exc") + + def _get_marks(self): + return list(self.item.iter_markers(name=self._mark_name)) + + def invalidraise(self, exc): + raises = self.get("raises") + if not raises: + return + return not isinstance(exc, raises) + + def istrue(self): + try: + return self._istrue() + except TEST_OUTCOME: + self.exc = sys.exc_info() + if isinstance(self.exc[1], SyntaxError): + msg = [" " * (self.exc[1].offset + 4) + "^"] + msg.append("SyntaxError: invalid syntax") + else: + msg = traceback.format_exception_only(*self.exc[:2]) + fail( + "Error evaluating %r expression\n" + " %s\n" + "%s" % (self._mark_name, self.expr, "\n".join(msg)), + pytrace=False, + ) + + def _getglobals(self): + d = {"os": os, "sys": sys, "platform": platform, "config": self.item.config} + if hasattr(self.item, "obj"): + d.update(self.item.obj.__globals__) + return d + + def _istrue(self): + if hasattr(self, "result"): + return self.result + self._marks = self._get_marks() + + if self._marks: + self.result = False + for mark in self._marks: + self._mark = mark + if "condition" in mark.kwargs: + args = (mark.kwargs["condition"],) + else: + args = mark.args + + for expr in args: + self.expr = expr + if isinstance(expr, six.string_types): + d = self._getglobals() + result = cached_eval(self.item.config, expr, d) + else: + if "reason" not in mark.kwargs: + # XXX better be checked at collection time + msg = "you need to specify reason=STRING " "when using booleans as conditions." + fail(msg) + result = bool(expr) + if result: + self.result = True + self.reason = mark.kwargs.get("reason", None) + self.expr = expr + return self.result + + if not args: + self.result = True + self.reason = mark.kwargs.get("reason", None) + return self.result + return False + + def get(self, attr, default=None): + if self._mark is None: + return default + return self._mark.kwargs.get(attr, default) + + def getexplanation(self): + expl = getattr(self, "reason", None) or self.get("reason", None) + if not expl: + if not hasattr(self, "expr"): + return "" + else: + return "condition: " + str(self.expr) + return expl diff --git a/Lib/site-packages/_pytest/mark/legacy.py b/Lib/site-packages/_pytest/mark/legacy.py new file mode 100644 index 0000000..ab016a0 --- /dev/null +++ b/Lib/site-packages/_pytest/mark/legacy.py @@ -0,0 +1,97 @@ +""" +this is a place where we put datastructures used by legacy apis +we hope ot remove +""" +import attr +import keyword + +from _pytest.config import UsageError + + +@attr.s +class MarkMapping(object): + """Provides a local mapping for markers where item access + resolves to True if the marker is present. """ + + own_mark_names = attr.ib() + + @classmethod + def from_item(cls, item): + mark_names = {mark.name for mark in item.iter_markers()} + return cls(mark_names) + + def __getitem__(self, name): + return name in self.own_mark_names + + +class KeywordMapping(object): + """Provides a local mapping for keywords. + Given a list of names, map any substring of one of these names to True. + """ + + def __init__(self, names): + self._names = names + + @classmethod + def from_item(cls, item): + mapped_names = set() + + # Add the names of the current item and any parent items + import pytest + + for item in item.listchain(): + if not isinstance(item, pytest.Instance): + mapped_names.add(item.name) + + # Add the names added as extra keywords to current or parent items + for name in item.listextrakeywords(): + mapped_names.add(name) + + # Add the names attached to the current function through direct assignment + if hasattr(item, "function"): + for name in item.function.__dict__: + mapped_names.add(name) + + return cls(mapped_names) + + def __getitem__(self, subname): + for name in self._names: + if subname in name: + return True + return False + + +python_keywords_allowed_list = ["or", "and", "not"] + + +def matchmark(colitem, markexpr): + """Tries to match on any marker names, attached to the given colitem.""" + return eval(markexpr, {}, MarkMapping.from_item(colitem)) + + +def matchkeyword(colitem, keywordexpr): + """Tries to match given keyword expression to given collector item. + + Will match on the name of colitem, including the names of its parents. + Only matches names of items which are either a :class:`Class` or a + :class:`Function`. + Additionally, matches on names in the 'extra_keyword_matches' set of + any item, as well as names directly assigned to test functions. + """ + mapping = KeywordMapping.from_item(colitem) + if " " not in keywordexpr: + # special case to allow for simple "-k pass" and "-k 1.3" + return mapping[keywordexpr] + elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]: + return not mapping[keywordexpr[4:]] + for kwd in keywordexpr.split(): + if keyword.iskeyword(kwd) and kwd not in python_keywords_allowed_list: + raise UsageError( + "Python keyword '{}' not accepted in expressions passed to '-k'".format( + kwd + ) + ) + try: + return eval(keywordexpr, {}, mapping) + except SyntaxError: + raise UsageError("Wrong expression passed to '-k': {}".format(keywordexpr)) diff --git a/Lib/site-packages/_pytest/mark/structures.py b/Lib/site-packages/_pytest/mark/structures.py new file mode 100644 index 0000000..9bd89c3 --- /dev/null +++ b/Lib/site-packages/_pytest/mark/structures.py @@ -0,0 +1,454 @@ +import inspect +import warnings +from collections import namedtuple +from functools import reduce +from operator import attrgetter + +import attr + +from ..deprecated import MARK_PARAMETERSET_UNPACKING, MARK_INFO_ATTRIBUTE +from ..compat import NOTSET, getfslineno, MappingMixin +from six.moves import map + + +EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark" + + +def alias(name, warning=None): + getter = attrgetter(name) + + def warned(self): + warnings.warn(warning, stacklevel=2) + return getter(self) + + return property(getter if warning is None else warned, doc="alias for " + name) + + +def istestfunc(func): + return ( + hasattr(func, "__call__") + and getattr(func, "__name__", "") != "" + ) + + +def get_empty_parameterset_mark(config, argnames, func): + requested_mark = config.getini(EMPTY_PARAMETERSET_OPTION) + if requested_mark in ("", None, "skip"): + mark = MARK_GEN.skip + elif requested_mark == "xfail": + mark = MARK_GEN.xfail(run=False) + else: + raise LookupError(requested_mark) + fs, lineno = getfslineno(func) + reason = "got empty parameter set %r, function %s at %s:%d" % ( + argnames, + func.__name__, + fs, + lineno, + ) + return mark(reason=reason) + + +class ParameterSet(namedtuple("ParameterSet", "values, marks, id")): + @classmethod + def param(cls, *values, **kw): + marks = kw.pop("marks", ()) + if isinstance(marks, MarkDecorator): + marks = (marks,) + else: + assert isinstance(marks, (tuple, list, set)) + + def param_extract_id(id=None): + return id + + id_ = param_extract_id(**kw) + return cls(values, marks, id_) + + @classmethod + def extract_from(cls, parameterset, legacy_force_tuple=False): + """ + :param parameterset: + a legacy style parameterset that may or may not be a tuple, + and may or may not be wrapped into a mess of mark objects + + :param legacy_force_tuple: + enforce tuple wrapping so single argument tuple values + don't get decomposed and break tests + + """ + + if isinstance(parameterset, cls): + return parameterset + if not isinstance(parameterset, MarkDecorator) and legacy_force_tuple: + return cls.param(parameterset) + + newmarks = [] + argval = parameterset + while isinstance(argval, MarkDecorator): + newmarks.append( + MarkDecorator(Mark(argval.markname, argval.args[:-1], argval.kwargs)) + ) + argval = argval.args[-1] + assert not isinstance(argval, ParameterSet) + if legacy_force_tuple: + argval = (argval,) + + if newmarks: + warnings.warn(MARK_PARAMETERSET_UNPACKING) + + return cls(argval, marks=newmarks, id=None) + + @classmethod + def _for_parametrize(cls, argnames, argvalues, func, config): + if not isinstance(argnames, (tuple, list)): + argnames = [x.strip() for x in argnames.split(",") if x.strip()] + force_tuple = len(argnames) == 1 + else: + force_tuple = False + parameters = [ + ParameterSet.extract_from(x, legacy_force_tuple=force_tuple) + for x in argvalues + ] + del argvalues + + if parameters: + # check all parameter sets have the correct number of values + for param in parameters: + if len(param.values) != len(argnames): + raise ValueError( + 'In "parametrize" the number of values ({}) must be ' + "equal to the number of names ({})".format( + param.values, argnames + ) + ) + else: + # empty parameter set (likely computed at runtime): create a single + # parameter set with NOSET values, with the "empty parameter set" mark applied to it + mark = get_empty_parameterset_mark(config, argnames, func) + parameters.append( + ParameterSet(values=(NOTSET,) * len(argnames), marks=[mark], id=None) + ) + return argnames, parameters + + +@attr.s(frozen=True) +class Mark(object): + #: name of the mark + name = attr.ib(type=str) + #: positional arguments of the mark decorator + args = attr.ib() # type: List[object] + #: keyword arguments of the mark decorator + kwargs = attr.ib() # type: Dict[str, object] + + def combined_with(self, other): + """ + :param other: the mark to combine with + :type other: Mark + :rtype: Mark + + combines by appending aargs and merging the mappings + """ + assert self.name == other.name + return Mark( + self.name, self.args + other.args, dict(self.kwargs, **other.kwargs) + ) + + +@attr.s +class MarkDecorator(object): + """ A decorator for test functions and test classes. When applied + it will create :class:`MarkInfo` objects which may be + :ref:`retrieved by hooks as item keywords `. + MarkDecorator instances are often created like this:: + + mark1 = pytest.mark.NAME # simple MarkDecorator + mark2 = pytest.mark.NAME(name1=value) # parametrized MarkDecorator + + and can then be applied as decorators to test functions:: + + @mark2 + def test_function(): + pass + + When a MarkDecorator instance is called it does the following: + 1. If called with a single class as its only positional argument and no + additional keyword arguments, it attaches itself to the class so it + gets applied automatically to all test cases found in that class. + 2. If called with a single function as its only positional argument and + no additional keyword arguments, it attaches a MarkInfo object to the + function, containing all the arguments already stored internally in + the MarkDecorator. + 3. When called in any other case, it performs a 'fake construction' call, + i.e. it returns a new MarkDecorator instance with the original + MarkDecorator's content updated with the arguments passed to this + call. + + Note: The rules above prevent MarkDecorator objects from storing only a + single function or class reference as their positional argument with no + additional keyword or positional arguments. + + """ + + mark = attr.ib(validator=attr.validators.instance_of(Mark)) + + name = alias("mark.name") + args = alias("mark.args") + kwargs = alias("mark.kwargs") + + @property + def markname(self): + return self.name # for backward-compat (2.4.1 had this attr) + + def __eq__(self, other): + return self.mark == other.mark if isinstance(other, MarkDecorator) else False + + def __repr__(self): + return "" % (self.mark,) + + def with_args(self, *args, **kwargs): + """ return a MarkDecorator with extra arguments added + + unlike call this can be used even if the sole argument is a callable/class + + :return: MarkDecorator + """ + + mark = Mark(self.name, args, kwargs) + return self.__class__(self.mark.combined_with(mark)) + + def __call__(self, *args, **kwargs): + """ if passed a single callable argument: decorate it with mark info. + otherwise add *args/**kwargs in-place to mark information. """ + if args and not kwargs: + func = args[0] + is_class = inspect.isclass(func) + if len(args) == 1 and (istestfunc(func) or is_class): + if is_class: + store_mark(func, self.mark) + else: + store_legacy_markinfo(func, self.mark) + store_mark(func, self.mark) + return func + return self.with_args(*args, **kwargs) + + +def get_unpacked_marks(obj): + """ + obtain the unpacked marks that are stored on an object + """ + mark_list = getattr(obj, "pytestmark", []) + if not isinstance(mark_list, list): + mark_list = [mark_list] + return normalize_mark_list(mark_list) + + +def normalize_mark_list(mark_list): + """ + normalizes marker decorating helpers to mark objects + + :type mark_list: List[Union[Mark, Markdecorator]] + :rtype: List[Mark] + """ + return [getattr(mark, "mark", mark) for mark in mark_list] # unpack MarkDecorator + + +def store_mark(obj, mark): + """store a Mark on an object + this is used to implement the Mark declarations/decorators correctly + """ + assert isinstance(mark, Mark), mark + # always reassign name to avoid updating pytestmark + # in a reference that was only borrowed + obj.pytestmark = get_unpacked_marks(obj) + [mark] + + +def store_legacy_markinfo(func, mark): + """create the legacy MarkInfo objects and put them onto the function + """ + if not isinstance(mark, Mark): + raise TypeError("got {mark!r} instead of a Mark".format(mark=mark)) + holder = getattr(func, mark.name, None) + if holder is None: + holder = MarkInfo.for_mark(mark) + setattr(func, mark.name, holder) + elif isinstance(holder, MarkInfo): + holder.add_mark(mark) + + +def transfer_markers(funcobj, cls, mod): + """ + this function transfers class level markers and module level markers + into function level markinfo objects + + this is the main reason why marks are so broken + the resolution will involve phasing out function level MarkInfo objects + + """ + for obj in (cls, mod): + for mark in get_unpacked_marks(obj): + if not _marked(funcobj, mark): + store_legacy_markinfo(funcobj, mark) + + +def _marked(func, mark): + """ Returns True if :func: is already marked with :mark:, False otherwise. + This can happen if marker is applied to class and the test file is + invoked more than once. + """ + try: + func_mark = getattr(func, getattr(mark, "combined", mark).name) + except AttributeError: + return False + return any(mark == info.combined for info in func_mark) + + +@attr.s +class MarkInfo(object): + """ Marking object created by :class:`MarkDecorator` instances. """ + + _marks = attr.ib(converter=list) + + @_marks.validator + def validate_marks(self, attribute, value): + for item in value: + if not isinstance(item, Mark): + raise ValueError( + "MarkInfo expects Mark instances, got {!r} ({!r})".format( + item, type(item) + ) + ) + + combined = attr.ib( + repr=False, + default=attr.Factory( + lambda self: reduce(Mark.combined_with, self._marks), takes_self=True + ), + ) + + name = alias("combined.name", warning=MARK_INFO_ATTRIBUTE) + args = alias("combined.args", warning=MARK_INFO_ATTRIBUTE) + kwargs = alias("combined.kwargs", warning=MARK_INFO_ATTRIBUTE) + + @classmethod + def for_mark(cls, mark): + return cls([mark]) + + def __repr__(self): + return "".format(self.combined) + + def add_mark(self, mark): + """ add a MarkInfo with the given args and kwargs. """ + self._marks.append(mark) + self.combined = self.combined.combined_with(mark) + + def __iter__(self): + """ yield MarkInfo objects each relating to a marking-call. """ + return map(MarkInfo.for_mark, self._marks) + + +class MarkGenerator(object): + """ Factory for :class:`MarkDecorator` objects - exposed as + a ``pytest.mark`` singleton instance. Example:: + + import pytest + @pytest.mark.slowtest + def test_function(): + pass + + will set a 'slowtest' :class:`MarkInfo` object + on the ``test_function`` object. """ + + _config = None + + def __getattr__(self, name): + if name[0] == "_": + raise AttributeError("Marker name must NOT start with underscore") + if self._config is not None: + self._check(name) + return MarkDecorator(Mark(name, (), {})) + + def _check(self, name): + try: + if name in self._markers: + return + except AttributeError: + pass + self._markers = values = set() + for line in self._config.getini("markers"): + marker = line.split(":", 1)[0] + marker = marker.rstrip() + x = marker.split("(", 1)[0] + values.add(x) + if name not in self._markers: + raise AttributeError("%r not a registered marker" % (name,)) + + +MARK_GEN = MarkGenerator() + + +class NodeKeywords(MappingMixin): + def __init__(self, node): + self.node = node + self.parent = node.parent + self._markers = {node.name: True} + + def __getitem__(self, key): + try: + return self._markers[key] + except KeyError: + if self.parent is None: + raise + return self.parent.keywords[key] + + def __setitem__(self, key, value): + self._markers[key] = value + + def __delitem__(self, key): + raise ValueError("cannot delete key in keywords dict") + + def __iter__(self): + seen = self._seen() + return iter(seen) + + def _seen(self): + seen = set(self._markers) + if self.parent is not None: + seen.update(self.parent.keywords) + return seen + + def __len__(self): + return len(self._seen()) + + def __repr__(self): + return "" % (self.node,) + + +@attr.s(cmp=False, hash=False) +class NodeMarkers(object): + """ + internal strucutre for storing marks belongong to a node + + ..warning:: + + unstable api + + """ + + own_markers = attr.ib(default=attr.Factory(list)) + + def update(self, add_markers): + """update the own markers + """ + self.own_markers.extend(add_markers) + + def find(self, name): + """ + find markers in own nodes or parent nodes + needs a better place + """ + for mark in self.own_markers: + if mark.name == name: + yield mark + + def __iter__(self): + return iter(self.own_markers) diff --git a/Lib/site-packages/_pytest/monkeypatch.py b/Lib/site-packages/_pytest/monkeypatch.py new file mode 100644 index 0000000..22ffffd --- /dev/null +++ b/Lib/site-packages/_pytest/monkeypatch.py @@ -0,0 +1,282 @@ +""" monkeypatching and mocking functionality. """ +from __future__ import absolute_import, division, print_function + +import os +import sys +import re +from contextlib import contextmanager + +import six +from _pytest.fixtures import fixture + +RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$") + + +@fixture +def monkeypatch(): + """The returned ``monkeypatch`` fixture provides these + helper methods to modify objects, dictionaries or os.environ:: + + monkeypatch.setattr(obj, name, value, raising=True) + monkeypatch.delattr(obj, name, raising=True) + monkeypatch.setitem(mapping, name, value) + monkeypatch.delitem(obj, name, raising=True) + monkeypatch.setenv(name, value, prepend=False) + monkeypatch.delenv(name, raising=True) + monkeypatch.syspath_prepend(path) + monkeypatch.chdir(path) + + All modifications will be undone after the requesting + test function or fixture has finished. The ``raising`` + parameter determines if a KeyError or AttributeError + will be raised if the set/deletion operation has no target. + """ + mpatch = MonkeyPatch() + yield mpatch + mpatch.undo() + + +def resolve(name): + # simplified from zope.dottedname + parts = name.split(".") + + used = parts.pop(0) + found = __import__(used) + for part in parts: + used += "." + part + try: + found = getattr(found, part) + except AttributeError: + pass + else: + continue + # we use explicit un-nesting of the handling block in order + # to avoid nested exceptions on python 3 + try: + __import__(used) + except ImportError as ex: + # str is used for py2 vs py3 + expected = str(ex).split()[-1] + if expected == used: + raise + else: + raise ImportError("import error in %s: %s" % (used, ex)) + found = annotated_getattr(found, part, used) + return found + + +def annotated_getattr(obj, name, ann): + try: + obj = getattr(obj, name) + except AttributeError: + raise AttributeError( + "%r object at %s has no attribute %r" % (type(obj).__name__, ann, name) + ) + return obj + + +def derive_importpath(import_path, raising): + if not isinstance(import_path, six.string_types) or "." not in import_path: + raise TypeError("must be absolute import path string, not %r" % (import_path,)) + module, attr = import_path.rsplit(".", 1) + target = resolve(module) + if raising: + annotated_getattr(target, attr, ann=module) + return attr, target + + +class Notset(object): + def __repr__(self): + return "" + + +notset = Notset() + + +class MonkeyPatch(object): + """ Object returned by the ``monkeypatch`` fixture keeping a record of setattr/item/env/syspath changes. + """ + + def __init__(self): + self._setattr = [] + self._setitem = [] + self._cwd = None + self._savesyspath = None + + @contextmanager + def context(self): + """ + Context manager that returns a new :class:`MonkeyPatch` object which + undoes any patching done inside the ``with`` block upon exit: + + .. code-block:: python + + import functools + def test_partial(monkeypatch): + with monkeypatch.context() as m: + m.setattr(functools, "partial", 3) + + Useful in situations where it is desired to undo some patches before the test ends, + such as mocking ``stdlib`` functions that might break pytest itself if mocked (for examples + of this see `#3290 `_. + """ + m = MonkeyPatch() + try: + yield m + finally: + m.undo() + + def setattr(self, target, name, value=notset, raising=True): + """ Set attribute value on target, memorizing the old value. + By default raise AttributeError if the attribute did not exist. + + For convenience you can specify a string as ``target`` which + will be interpreted as a dotted import path, with the last part + being the attribute name. Example: + ``monkeypatch.setattr("os.getcwd", lambda: "/")`` + would set the ``getcwd`` function of the ``os`` module. + + The ``raising`` value determines if the setattr should fail + if the attribute is not already present (defaults to True + which means it will raise). + """ + __tracebackhide__ = True + import inspect + + if value is notset: + if not isinstance(target, six.string_types): + raise TypeError( + "use setattr(target, name, value) or " + "setattr(target, value) with target being a dotted " + "import string" + ) + value = name + name, target = derive_importpath(target, raising) + + oldval = getattr(target, name, notset) + if raising and oldval is notset: + raise AttributeError("%r has no attribute %r" % (target, name)) + + # avoid class descriptors like staticmethod/classmethod + if inspect.isclass(target): + oldval = target.__dict__.get(name, notset) + self._setattr.append((target, name, oldval)) + setattr(target, name, value) + + def delattr(self, target, name=notset, raising=True): + """ Delete attribute ``name`` from ``target``, by default raise + AttributeError it the attribute did not previously exist. + + If no ``name`` is specified and ``target`` is a string + it will be interpreted as a dotted import path with the + last part being the attribute name. + + If ``raising`` is set to False, no exception will be raised if the + attribute is missing. + """ + __tracebackhide__ = True + if name is notset: + if not isinstance(target, six.string_types): + raise TypeError( + "use delattr(target, name) or " + "delattr(target) with target being a dotted " + "import string" + ) + name, target = derive_importpath(target, raising) + + if not hasattr(target, name): + if raising: + raise AttributeError(name) + else: + self._setattr.append((target, name, getattr(target, name, notset))) + delattr(target, name) + + def setitem(self, dic, name, value): + """ Set dictionary entry ``name`` to value. """ + self._setitem.append((dic, name, dic.get(name, notset))) + dic[name] = value + + def delitem(self, dic, name, raising=True): + """ Delete ``name`` from dict. Raise KeyError if it doesn't exist. + + If ``raising`` is set to False, no exception will be raised if the + key is missing. + """ + if name not in dic: + if raising: + raise KeyError(name) + else: + self._setitem.append((dic, name, dic.get(name, notset))) + del dic[name] + + def setenv(self, name, value, prepend=None): + """ Set environment variable ``name`` to ``value``. If ``prepend`` + is a character, read the current environment variable value + and prepend the ``value`` adjoined with the ``prepend`` character.""" + value = str(value) + if prepend and name in os.environ: + value = value + prepend + os.environ[name] + self.setitem(os.environ, name, value) + + def delenv(self, name, raising=True): + """ Delete ``name`` from the environment. Raise KeyError it does not + exist. + + If ``raising`` is set to False, no exception will be raised if the + environment variable is missing. + """ + self.delitem(os.environ, name, raising=raising) + + def syspath_prepend(self, path): + """ Prepend ``path`` to ``sys.path`` list of import locations. """ + if self._savesyspath is None: + self._savesyspath = sys.path[:] + sys.path.insert(0, str(path)) + + def chdir(self, path): + """ Change the current working directory to the specified path. + Path can be a string or a py.path.local object. + """ + if self._cwd is None: + self._cwd = os.getcwd() + if hasattr(path, "chdir"): + path.chdir() + else: + os.chdir(path) + + def undo(self): + """ Undo previous changes. This call consumes the + undo stack. Calling it a second time has no effect unless + you do more monkeypatching after the undo call. + + There is generally no need to call `undo()`, since it is + called automatically during tear-down. + + Note that the same `monkeypatch` fixture is used across a + single test function invocation. If `monkeypatch` is used both by + the test function itself and one of the test fixtures, + calling `undo()` will undo all of the changes made in + both functions. + """ + for obj, name, value in reversed(self._setattr): + if value is not notset: + setattr(obj, name, value) + else: + delattr(obj, name) + self._setattr[:] = [] + for dictionary, name, value in reversed(self._setitem): + if value is notset: + try: + del dictionary[name] + except KeyError: + pass # was already deleted, so we have the desired state + else: + dictionary[name] = value + self._setitem[:] = [] + if self._savesyspath is not None: + sys.path[:] = self._savesyspath + self._savesyspath = None + + if self._cwd is not None: + os.chdir(self._cwd) + self._cwd = None diff --git a/Lib/site-packages/_pytest/nodes.py b/Lib/site-packages/_pytest/nodes.py new file mode 100644 index 0000000..49c30e9 --- /dev/null +++ b/Lib/site-packages/_pytest/nodes.py @@ -0,0 +1,431 @@ +from __future__ import absolute_import, division, print_function +import os + +import six +import py +import attr + +import _pytest +import _pytest._code + +from _pytest.mark.structures import NodeKeywords, MarkInfo + +SEP = "/" + +tracebackcutdir = py.path.local(_pytest.__file__).dirpath() + + +def _splitnode(nodeid): + """Split a nodeid into constituent 'parts'. + + Node IDs are strings, and can be things like: + '' + 'testing/code' + 'testing/code/test_excinfo.py' + 'testing/code/test_excinfo.py::TestFormattedExcinfo::()' + + Return values are lists e.g. + [] + ['testing', 'code'] + ['testing', 'code', 'test_excinfo.py'] + ['testing', 'code', 'test_excinfo.py', 'TestFormattedExcinfo', '()'] + """ + if nodeid == "": + # If there is no root node at all, return an empty list so the caller's logic can remain sane + return [] + parts = nodeid.split(SEP) + # Replace single last element 'test_foo.py::Bar::()' with multiple elements 'test_foo.py', 'Bar', '()' + parts[-1:] = parts[-1].split("::") + return parts + + +def ischildnode(baseid, nodeid): + """Return True if the nodeid is a child node of the baseid. + + E.g. 'foo/bar::Baz::()' is a child of 'foo', 'foo/bar' and 'foo/bar::Baz', but not of 'foo/blorp' + """ + base_parts = _splitnode(baseid) + node_parts = _splitnode(nodeid) + if len(node_parts) < len(base_parts): + return False + return node_parts[: len(base_parts)] == base_parts + + +@attr.s +class _CompatProperty(object): + name = attr.ib() + + def __get__(self, obj, owner): + if obj is None: + return self + + # TODO: reenable in the features branch + # warnings.warn( + # "usage of {owner!r}.{name} is deprecated, please use pytest.{name} instead".format( + # name=self.name, owner=type(owner).__name__), + # PendingDeprecationWarning, stacklevel=2) + return getattr(__import__("pytest"), self.name) + + +class Node(object): + """ base class for Collector and Item the test collection tree. + Collector subclasses have children, Items are terminal nodes.""" + + def __init__( + self, name, parent=None, config=None, session=None, fspath=None, nodeid=None + ): + #: a unique name within the scope of the parent node + self.name = name + + #: the parent collector node. + self.parent = parent + + #: the pytest config object + self.config = config or parent.config + + #: the session this node is part of + self.session = session or parent.session + + #: filesystem path where this node was collected from (can be None) + self.fspath = fspath or getattr(parent, "fspath", None) + + #: keywords/markers collected from all scopes + self.keywords = NodeKeywords(self) + + #: the marker objects belonging to this node + self.own_markers = [] + + #: allow adding of extra keywords to use for matching + self.extra_keyword_matches = set() + + # used for storing artificial fixturedefs for direct parametrization + self._name2pseudofixturedef = {} + + if nodeid is not None: + self._nodeid = nodeid + else: + assert parent is not None + self._nodeid = self.parent.nodeid + "::" + self.name + + @property + def ihook(self): + """ fspath sensitive hook proxy used to call pytest hooks""" + return self.session.gethookproxy(self.fspath) + + Module = _CompatProperty("Module") + Class = _CompatProperty("Class") + Instance = _CompatProperty("Instance") + Function = _CompatProperty("Function") + File = _CompatProperty("File") + Item = _CompatProperty("Item") + + def _getcustomclass(self, name): + maybe_compatprop = getattr(type(self), name) + if isinstance(maybe_compatprop, _CompatProperty): + return getattr(__import__("pytest"), name) + else: + cls = getattr(self, name) + # TODO: reenable in the features branch + # warnings.warn("use of node.%s is deprecated, " + # "use pytest_pycollect_makeitem(...) to create custom " + # "collection nodes" % name, category=DeprecationWarning) + return cls + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, getattr(self, "name", None)) + + def warn(self, code, message): + """ generate a warning with the given code and message for this + item. """ + assert isinstance(code, str) + fslocation = getattr(self, "location", None) + if fslocation is None: + fslocation = getattr(self, "fspath", None) + self.ihook.pytest_logwarning.call_historic( + kwargs=dict( + code=code, message=message, nodeid=self.nodeid, fslocation=fslocation + ) + ) + + # methods for ordering nodes + @property + def nodeid(self): + """ a ::-separated string denoting its collection tree address. """ + return self._nodeid + + def __hash__(self): + return hash(self.nodeid) + + def setup(self): + pass + + def teardown(self): + pass + + def listchain(self): + """ return list of all parent collectors up to self, + starting from root of collection tree. """ + chain = [] + item = self + while item is not None: + chain.append(item) + item = item.parent + chain.reverse() + return chain + + def add_marker(self, marker, append=True): + """dynamically add a marker object to the node. + + :type marker: ``str`` or ``pytest.mark.*`` object + :param marker: + ``append=True`` whether to append the marker, + if ``False`` insert at position ``0``. + """ + from _pytest.mark import MarkDecorator, MARK_GEN + + if isinstance(marker, six.string_types): + marker = getattr(MARK_GEN, marker) + elif not isinstance(marker, MarkDecorator): + raise ValueError("is not a string or pytest.mark.* Marker") + self.keywords[marker.name] = marker + if append: + self.own_markers.append(marker.mark) + else: + self.own_markers.insert(0, marker.mark) + + def iter_markers(self, name=None): + """ + :param name: if given, filter the results by the name attribute + + iterate over all markers of the node + """ + return (x[1] for x in self.iter_markers_with_node(name=name)) + + def iter_markers_with_node(self, name=None): + """ + :param name: if given, filter the results by the name attribute + + iterate over all markers of the node + returns sequence of tuples (node, mark) + """ + for node in reversed(self.listchain()): + for mark in node.own_markers: + if name is None or getattr(mark, "name", None) == name: + yield node, mark + + def get_closest_marker(self, name, default=None): + """return the first marker matching the name, from closest (for example function) to farther level (for example + module level). + + :param default: fallback return value of no marker was found + :param name: name to filter by + """ + return next(self.iter_markers(name=name), default) + + def get_marker(self, name): + """ get a marker object from this node or None if + the node doesn't have a marker with that name. + + .. deprecated:: 3.6 + This function has been deprecated in favor of + :meth:`Node.get_closest_marker <_pytest.nodes.Node.get_closest_marker>` and + :meth:`Node.iter_markers <_pytest.nodes.Node.iter_markers>`, see :ref:`update marker code` + for more details. + """ + markers = list(self.iter_markers(name=name)) + if markers: + return MarkInfo(markers) + + def listextrakeywords(self): + """ Return a set of all extra keywords in self and any parents.""" + extra_keywords = set() + for item in self.listchain(): + extra_keywords.update(item.extra_keyword_matches) + return extra_keywords + + def listnames(self): + return [x.name for x in self.listchain()] + + def addfinalizer(self, fin): + """ register a function to be called when this node is finalized. + + This method can only be called when this node is active + in a setup chain, for example during self.setup(). + """ + self.session._setupstate.addfinalizer(fin, self) + + def getparent(self, cls): + """ get the next parent node (including ourself) + which is an instance of the given class""" + current = self + while current and not isinstance(current, cls): + current = current.parent + return current + + def _prunetraceback(self, excinfo): + pass + + def _repr_failure_py(self, excinfo, style=None): + fm = self.session._fixturemanager + if excinfo.errisinstance(fm.FixtureLookupError): + return excinfo.value.formatrepr() + tbfilter = True + if self.config.option.fulltrace: + style = "long" + else: + tb = _pytest._code.Traceback([excinfo.traceback[-1]]) + self._prunetraceback(excinfo) + if len(excinfo.traceback) == 0: + excinfo.traceback = tb + tbfilter = False # prunetraceback already does it + if style == "auto": + style = "long" + # XXX should excinfo.getrepr record all data and toterminal() process it? + if style is None: + if self.config.option.tbstyle == "short": + style = "short" + else: + style = "long" + + if self.config.option.verbose > 1: + truncate_locals = False + else: + truncate_locals = True + + try: + os.getcwd() + abspath = False + except OSError: + abspath = True + + return excinfo.getrepr( + funcargs=True, + abspath=abspath, + showlocals=self.config.option.showlocals, + style=style, + tbfilter=tbfilter, + truncate_locals=truncate_locals, + ) + + repr_failure = _repr_failure_py + + +class Collector(Node): + """ Collector instances create children through collect() + and thus iteratively build a tree. + """ + + class CollectError(Exception): + """ an error during collection, contains a custom message. """ + + def collect(self): + """ returns a list of children (items and collectors) + for this collection node. + """ + raise NotImplementedError("abstract") + + def repr_failure(self, excinfo): + """ represent a collection failure. """ + if excinfo.errisinstance(self.CollectError): + exc = excinfo.value + return str(exc.args[0]) + return self._repr_failure_py(excinfo, style="short") + + def _prunetraceback(self, excinfo): + if hasattr(self, "fspath"): + traceback = excinfo.traceback + ntraceback = traceback.cut(path=self.fspath) + if ntraceback == traceback: + ntraceback = ntraceback.cut(excludepath=tracebackcutdir) + excinfo.traceback = ntraceback.filter() + + +def _check_initialpaths_for_relpath(session, fspath): + for initial_path in session._initialpaths: + if fspath.common(initial_path) == initial_path: + return fspath.relto(initial_path.dirname) + + +class FSCollector(Collector): + def __init__(self, fspath, parent=None, config=None, session=None, nodeid=None): + fspath = py.path.local(fspath) # xxx only for test_resultlog.py? + name = fspath.basename + if parent is not None: + rel = fspath.relto(parent.fspath) + if rel: + name = rel + name = name.replace(os.sep, SEP) + self.fspath = fspath + + session = session or parent.session + + if nodeid is None: + nodeid = self.fspath.relto(session.config.rootdir) + + if not nodeid: + nodeid = _check_initialpaths_for_relpath(session, fspath) + if nodeid and os.sep != SEP: + nodeid = nodeid.replace(os.sep, SEP) + + super(FSCollector, self).__init__( + name, parent, config, session, nodeid=nodeid, fspath=fspath + ) + + +class File(FSCollector): + """ base class for collecting tests from a file. """ + + +class Item(Node): + """ a basic test invocation item. Note that for a single function + there might be multiple test invocation items. + """ + + nextitem = None + + def __init__(self, name, parent=None, config=None, session=None, nodeid=None): + super(Item, self).__init__(name, parent, config, session, nodeid=nodeid) + self._report_sections = [] + + #: user properties is a list of tuples (name, value) that holds user + #: defined properties for this test. + self.user_properties = [] + + def add_report_section(self, when, key, content): + """ + Adds a new report section, similar to what's done internally to add stdout and + stderr captured output:: + + item.add_report_section("call", "stdout", "report section contents") + + :param str when: + One of the possible capture states, ``"setup"``, ``"call"``, ``"teardown"``. + :param str key: + Name of the section, can be customized at will. Pytest uses ``"stdout"`` and + ``"stderr"`` internally. + + :param str content: + The full contents as a string. + """ + if content: + self._report_sections.append((when, key, content)) + + def reportinfo(self): + return self.fspath, None, "" + + @property + def location(self): + try: + return self._location + except AttributeError: + location = self.reportinfo() + # bestrelpath is a quite slow function + cache = self.config.__dict__.setdefault("_bestrelpathcache", {}) + try: + fspath = cache[location[0]] + except KeyError: + fspath = self.session.fspath.bestrelpath(location[0]) + cache[location[0]] = fspath + location = (fspath, location[1], str(location[2])) + self._location = location + return location diff --git a/Lib/site-packages/_pytest/nose.py b/Lib/site-packages/_pytest/nose.py new file mode 100644 index 0000000..bb2e427 --- /dev/null +++ b/Lib/site-packages/_pytest/nose.py @@ -0,0 +1,72 @@ +""" run test suites written for nose. """ +from __future__ import absolute_import, division, print_function + +import sys + +from _pytest import unittest, runner, python +from _pytest.config import hookimpl + + +def get_skip_exceptions(): + skip_classes = set() + for module_name in ("unittest", "unittest2", "nose"): + mod = sys.modules.get(module_name) + if hasattr(mod, "SkipTest"): + skip_classes.add(mod.SkipTest) + return tuple(skip_classes) + + +def pytest_runtest_makereport(item, call): + if call.excinfo and call.excinfo.errisinstance(get_skip_exceptions()): + # let's substitute the excinfo with a pytest.skip one + call2 = call.__class__(lambda: runner.skip(str(call.excinfo.value)), call.when) + call.excinfo = call2.excinfo + + +@hookimpl(trylast=True) +def pytest_runtest_setup(item): + if is_potential_nosetest(item): + if isinstance(item.parent, python.Generator): + gen = item.parent + if not hasattr(gen, "_nosegensetup"): + call_optional(gen.obj, "setup") + if isinstance(gen.parent, python.Instance): + call_optional(gen.parent.obj, "setup") + gen._nosegensetup = True + if not call_optional(item.obj, "setup"): + # call module level setup if there is no object level one + call_optional(item.parent.obj, "setup") + # XXX this implies we only call teardown when setup worked + item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item) + + +def teardown_nose(item): + if is_potential_nosetest(item): + if not call_optional(item.obj, "teardown"): + call_optional(item.parent.obj, "teardown") + # if hasattr(item.parent, '_nosegensetup'): + # #call_optional(item._nosegensetup, 'teardown') + # del item.parent._nosegensetup + + +def pytest_make_collect_report(collector): + if isinstance(collector, python.Generator): + call_optional(collector.obj, "setup") + + +def is_potential_nosetest(item): + # extra check needed since we do not do nose style setup/teardown + # on direct unittest style classes + return isinstance(item, python.Function) and not isinstance( + item, unittest.TestCaseFunction + ) + + +def call_optional(obj, name): + method = getattr(obj, name, None) + isfixture = hasattr(method, "_pytestfixturefunction") + if method is not None and not isfixture and callable(method): + # If there's any problems allow the exception to raise rather than + # silently ignoring them + method() + return True diff --git a/Lib/site-packages/_pytest/outcomes.py b/Lib/site-packages/_pytest/outcomes.py new file mode 100644 index 0000000..63b8453 --- /dev/null +++ b/Lib/site-packages/_pytest/outcomes.py @@ -0,0 +1,158 @@ +""" +exception classes and constants handling test outcomes +as well as functions creating them +""" +from __future__ import absolute_import, division, print_function +import py +import sys + + +class OutcomeException(BaseException): + """ OutcomeException and its subclass instances indicate and + contain info about test and collection outcomes. + """ + + def __init__(self, msg=None, pytrace=True): + BaseException.__init__(self, msg) + self.msg = msg + self.pytrace = pytrace + + def __repr__(self): + if self.msg: + val = self.msg + if isinstance(val, bytes): + val = py._builtin._totext(val, errors="replace") + return val + return "<%s instance>" % (self.__class__.__name__,) + + __str__ = __repr__ + + +TEST_OUTCOME = (OutcomeException, Exception) + + +class Skipped(OutcomeException): + # XXX hackish: on 3k we fake to live in the builtins + # in order to have Skipped exception printing shorter/nicer + __module__ = "builtins" + + def __init__(self, msg=None, pytrace=True, allow_module_level=False): + OutcomeException.__init__(self, msg=msg, pytrace=pytrace) + self.allow_module_level = allow_module_level + + +class Failed(OutcomeException): + """ raised from an explicit call to pytest.fail() """ + + __module__ = "builtins" + + +class Exit(KeyboardInterrupt): + """ raised for immediate program exits (no tracebacks/summaries)""" + + def __init__(self, msg="unknown reason"): + self.msg = msg + KeyboardInterrupt.__init__(self, msg) + + +# exposed helper methods + + +def exit(msg): + """ exit testing process as if KeyboardInterrupt was triggered. """ + __tracebackhide__ = True + raise Exit(msg) + + +exit.Exception = Exit + + +def skip(msg="", **kwargs): + """ skip an executing test with the given message. Note: it's usually + better to use the pytest.mark.skipif marker to declare a test to be + skipped under certain conditions like mismatching platforms or + dependencies. See the pytest_skipping plugin for details. + + :kwarg bool allow_module_level: allows this function to be called at + module level, skipping the rest of the module. Default to False. + """ + __tracebackhide__ = True + allow_module_level = kwargs.pop("allow_module_level", False) + if kwargs: + keys = [k for k in kwargs.keys()] + raise TypeError("unexpected keyword arguments: {}".format(keys)) + raise Skipped(msg=msg, allow_module_level=allow_module_level) + + +skip.Exception = Skipped + + +def fail(msg="", pytrace=True): + """ explicitly fail a currently-executing test with the given Message. + + :arg pytrace: if false the msg represents the full failure information + and no python traceback will be reported. + """ + __tracebackhide__ = True + raise Failed(msg=msg, pytrace=pytrace) + + +fail.Exception = Failed + + +class XFailed(fail.Exception): + """ raised from an explicit call to pytest.xfail() """ + + +def xfail(reason=""): + """ xfail an executing test or setup functions with the given reason.""" + __tracebackhide__ = True + raise XFailed(reason) + + +xfail.Exception = XFailed + + +def importorskip(modname, minversion=None): + """ return imported module if it has at least "minversion" as its + __version__ attribute. If no minversion is specified the a skip + is only triggered if the module can not be imported. + """ + import warnings + + __tracebackhide__ = True + compile(modname, "", "eval") # to catch syntaxerrors + should_skip = False + + with warnings.catch_warnings(): + # make sure to ignore ImportWarnings that might happen because + # of existing directories with the same name we're trying to + # import but without a __init__.py file + warnings.simplefilter("ignore") + try: + __import__(modname) + except ImportError: + # Do not raise chained exception here(#1485) + should_skip = True + if should_skip: + raise Skipped("could not import %r" % (modname,), allow_module_level=True) + mod = sys.modules[modname] + if minversion is None: + return mod + verattr = getattr(mod, "__version__", None) + if minversion is not None: + try: + from pkg_resources import parse_version as pv + except ImportError: + raise Skipped( + "we have a required version for %r but can not import " + "pkg_resources to parse version strings." % (modname,), + allow_module_level=True, + ) + if verattr is None or pv(verattr) < pv(minversion): + raise Skipped( + "module %r has __version__ %r, required is: %r" + % (modname, verattr, minversion), + allow_module_level=True, + ) + return mod diff --git a/Lib/site-packages/_pytest/pastebin.py b/Lib/site-packages/_pytest/pastebin.py new file mode 100644 index 0000000..6af202d --- /dev/null +++ b/Lib/site-packages/_pytest/pastebin.py @@ -0,0 +1,109 @@ +""" submit failure or test session information to a pastebin service. """ +from __future__ import absolute_import, division, print_function + +import pytest +import six +import sys +import tempfile + + +def pytest_addoption(parser): + group = parser.getgroup("terminal reporting") + group._addoption( + "--pastebin", + metavar="mode", + action="store", + dest="pastebin", + default=None, + choices=["failed", "all"], + help="send failed|all info to bpaste.net pastebin service.", + ) + + +@pytest.hookimpl(trylast=True) +def pytest_configure(config): + if config.option.pastebin == "all": + tr = config.pluginmanager.getplugin("terminalreporter") + # if no terminal reporter plugin is present, nothing we can do here; + # this can happen when this function executes in a slave node + # when using pytest-xdist, for example + if tr is not None: + # pastebin file will be utf-8 encoded binary file + config._pastebinfile = tempfile.TemporaryFile("w+b") + oldwrite = tr._tw.write + + def tee_write(s, **kwargs): + oldwrite(s, **kwargs) + if isinstance(s, six.text_type): + s = s.encode("utf-8") + config._pastebinfile.write(s) + + tr._tw.write = tee_write + + +def pytest_unconfigure(config): + if hasattr(config, "_pastebinfile"): + # get terminal contents and delete file + config._pastebinfile.seek(0) + sessionlog = config._pastebinfile.read() + config._pastebinfile.close() + del config._pastebinfile + # undo our patching in the terminal reporter + tr = config.pluginmanager.getplugin("terminalreporter") + del tr._tw.__dict__["write"] + # write summary + tr.write_sep("=", "Sending information to Paste Service") + pastebinurl = create_new_paste(sessionlog) + tr.write_line("pastebin session-log: %s\n" % pastebinurl) + + +def create_new_paste(contents): + """ + Creates a new paste using bpaste.net service. + + :contents: paste contents as utf-8 encoded bytes + :returns: url to the pasted contents + """ + import re + + if sys.version_info < (3, 0): + from urllib import urlopen, urlencode + else: + from urllib.request import urlopen + from urllib.parse import urlencode + + params = { + "code": contents, + "lexer": "python3" if sys.version_info[0] == 3 else "python", + "expiry": "1week", + } + url = "https://bpaste.net" + response = urlopen(url, data=urlencode(params).encode("ascii")).read() + m = re.search(r'href="/raw/(\w+)"', response.decode("utf-8")) + if m: + return "%s/show/%s" % (url, m.group(1)) + else: + return "bad response: " + response + + +def pytest_terminal_summary(terminalreporter): + import _pytest.config + + if terminalreporter.config.option.pastebin != "failed": + return + tr = terminalreporter + if "failed" in tr.stats: + terminalreporter.write_sep("=", "Sending information to Paste Service") + for rep in terminalreporter.stats.get("failed"): + try: + msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc + except AttributeError: + msg = tr._getfailureheadline(rep) + tw = _pytest.config.create_terminal_writer( + terminalreporter.config, stringio=True + ) + rep.toterminal(tw) + s = tw.stringio.getvalue() + assert len(s) + pastebinurl = create_new_paste(s) + tr.write_line("%s --> %s" % (msg, pastebinurl)) diff --git a/Lib/site-packages/_pytest/paths.py b/Lib/site-packages/_pytest/paths.py new file mode 100644 index 0000000..7c0dc1e --- /dev/null +++ b/Lib/site-packages/_pytest/paths.py @@ -0,0 +1,13 @@ +from .compat import Path +from os.path import expanduser, expandvars, isabs + + +def resolve_from_str(input, root): + assert not isinstance(input, Path), "would break on py2" + root = Path(root) + input = expanduser(input) + input = expandvars(input) + if isabs(input): + return Path(input) + else: + return root.joinpath(input) diff --git a/Lib/site-packages/_pytest/pytester.py b/Lib/site-packages/_pytest/pytester.py new file mode 100644 index 0000000..5b42b81 --- /dev/null +++ b/Lib/site-packages/_pytest/pytester.py @@ -0,0 +1,1306 @@ +"""(disabled by default) support for testing pytest and pytest plugins.""" +from __future__ import absolute_import, division, print_function + +import codecs +import gc +import os +import platform +import re +import subprocess +import six +import sys +import time +import traceback +from fnmatch import fnmatch + +from weakref import WeakKeyDictionary + +from _pytest.capture import MultiCapture, SysCapture +from _pytest._code import Source +import py +import pytest +from _pytest.main import Session, EXIT_OK +from _pytest.assertion.rewrite import AssertionRewritingHook +from _pytest.compat import Path + +IGNORE_PAM = [ # filenames added when obtaining details about the current user + u"/var/lib/sss/mc/passwd" +] + + +def pytest_addoption(parser): + parser.addoption( + "--lsof", + action="store_true", + dest="lsof", + default=False, + help=("run FD checks if lsof is available"), + ) + + parser.addoption( + "--runpytest", + default="inprocess", + dest="runpytest", + choices=("inprocess", "subprocess"), + help=( + "run pytest sub runs in tests using an 'inprocess' " + "or 'subprocess' (python -m main) method" + ), + ) + + parser.addini( + "pytester_example_dir", help="directory to take the pytester example files from" + ) + + +def pytest_configure(config): + if config.getvalue("lsof"): + checker = LsofFdLeakChecker() + if checker.matching_platform(): + config.pluginmanager.register(checker) + + +class LsofFdLeakChecker(object): + def get_open_files(self): + out = self._exec_lsof() + open_files = self._parse_lsof_output(out) + return open_files + + def _exec_lsof(self): + pid = os.getpid() + return py.process.cmdexec("lsof -Ffn0 -p %d" % pid) + + def _parse_lsof_output(self, out): + def isopen(line): + return line.startswith("f") and ( + "deleted" not in line + and "mem" not in line + and "txt" not in line + and "cwd" not in line + ) + + open_files = [] + + for line in out.split("\n"): + if isopen(line): + fields = line.split("\0") + fd = fields[0][1:] + filename = fields[1][1:] + if filename in IGNORE_PAM: + continue + if filename.startswith("/"): + open_files.append((fd, filename)) + + return open_files + + def matching_platform(self): + try: + py.process.cmdexec("lsof -v") + except (py.process.cmdexec.Error, UnicodeDecodeError): + # cmdexec may raise UnicodeDecodeError on Windows systems with + # locale other than English: + # https://bitbucket.org/pytest-dev/py/issues/66 + return False + else: + return True + + @pytest.hookimpl(hookwrapper=True, tryfirst=True) + def pytest_runtest_protocol(self, item): + lines1 = self.get_open_files() + yield + if hasattr(sys, "pypy_version_info"): + gc.collect() + lines2 = self.get_open_files() + + new_fds = {t[0] for t in lines2} - {t[0] for t in lines1} + leaked_files = [t for t in lines2 if t[0] in new_fds] + if leaked_files: + error = [] + error.append("***** %s FD leakage detected" % len(leaked_files)) + error.extend([str(f) for f in leaked_files]) + error.append("*** Before:") + error.extend([str(f) for f in lines1]) + error.append("*** After:") + error.extend([str(f) for f in lines2]) + error.append(error[0]) + error.append("*** function %s:%s: %s " % item.location) + error.append("See issue #2366") + item.warn("", "\n".join(error)) + + +# XXX copied from execnet's conftest.py - needs to be merged +winpymap = { + "python2.7": r"C:\Python27\python.exe", + "python3.4": r"C:\Python34\python.exe", + "python3.5": r"C:\Python35\python.exe", + "python3.6": r"C:\Python36\python.exe", +} + + +def getexecutable(name, cache={}): + try: + return cache[name] + except KeyError: + executable = py.path.local.sysfind(name) + if executable: + import subprocess + + popen = subprocess.Popen( + [str(executable), "--version"], + universal_newlines=True, + stderr=subprocess.PIPE, + ) + out, err = popen.communicate() + if name == "jython": + if not err or "2.5" not in err: + executable = None + if "2.5.2" in err: + executable = None # http://bugs.jython.org/issue1790 + elif popen.returncode != 0: + # handle pyenv's 127 + executable = None + cache[name] = executable + return executable + + +@pytest.fixture(params=["python2.7", "python3.4", "pypy", "pypy3"]) +def anypython(request): + name = request.param + executable = getexecutable(name) + if executable is None: + if sys.platform == "win32": + executable = winpymap.get(name, None) + if executable: + executable = py.path.local(executable) + if executable.check(): + return executable + pytest.skip("no suitable %s found" % (name,)) + return executable + + +# used at least by pytest-xdist plugin + + +@pytest.fixture +def _pytest(request): + """Return a helper which offers a gethookrecorder(hook) method which + returns a HookRecorder instance which helps to make assertions about called + hooks. + + """ + return PytestArg(request) + + +class PytestArg(object): + def __init__(self, request): + self.request = request + + def gethookrecorder(self, hook): + hookrecorder = HookRecorder(hook._pm) + self.request.addfinalizer(hookrecorder.finish_recording) + return hookrecorder + + +def get_public_names(values): + """Only return names from iterator values without a leading underscore.""" + return [x for x in values if x[0] != "_"] + + +class ParsedCall(object): + def __init__(self, name, kwargs): + self.__dict__.update(kwargs) + self._name = name + + def __repr__(self): + d = self.__dict__.copy() + del d["_name"] + return "" % (self._name, d) + + +class HookRecorder(object): + """Record all hooks called in a plugin manager. + + This wraps all the hook calls in the plugin manager, recording each call + before propagating the normal calls. + + """ + + def __init__(self, pluginmanager): + self._pluginmanager = pluginmanager + self.calls = [] + + def before(hook_name, hook_impls, kwargs): + self.calls.append(ParsedCall(hook_name, kwargs)) + + def after(outcome, hook_name, hook_impls, kwargs): + pass + + self._undo_wrapping = pluginmanager.add_hookcall_monitoring(before, after) + + def finish_recording(self): + self._undo_wrapping() + + def getcalls(self, names): + if isinstance(names, str): + names = names.split() + return [call for call in self.calls if call._name in names] + + def assert_contains(self, entries): + __tracebackhide__ = True + i = 0 + entries = list(entries) + backlocals = sys._getframe(1).f_locals + while entries: + name, check = entries.pop(0) + for ind, call in enumerate(self.calls[i:]): + if call._name == name: + print("NAMEMATCH", name, call) + if eval(check, backlocals, call.__dict__): + print("CHECKERMATCH", repr(check), "->", call) + else: + print("NOCHECKERMATCH", repr(check), "-", call) + continue + i += ind + 1 + break + print("NONAMEMATCH", name, "with", call) + else: + pytest.fail("could not find %r check %r" % (name, check)) + + def popcall(self, name): + __tracebackhide__ = True + for i, call in enumerate(self.calls): + if call._name == name: + del self.calls[i] + return call + lines = ["could not find call %r, in:" % (name,)] + lines.extend([" %s" % str(x) for x in self.calls]) + pytest.fail("\n".join(lines)) + + def getcall(self, name): + values = self.getcalls(name) + assert len(values) == 1, (name, values) + return values[0] + + # functionality for test reports + + def getreports(self, names="pytest_runtest_logreport pytest_collectreport"): + return [x.report for x in self.getcalls(names)] + + def matchreport( + self, + inamepart="", + names="pytest_runtest_logreport pytest_collectreport", + when=None, + ): + """return a testreport whose dotted import path matches""" + values = [] + for rep in self.getreports(names=names): + try: + if not when and rep.when != "call" and rep.passed: + # setup/teardown passing reports - let's ignore those + continue + except AttributeError: + pass + if when and getattr(rep, "when", None) != when: + continue + if not inamepart or inamepart in rep.nodeid.split("::"): + values.append(rep) + if not values: + raise ValueError( + "could not find test report matching %r: " + "no test reports at all!" % (inamepart,) + ) + if len(values) > 1: + raise ValueError( + "found 2 or more testreports matching %r: %s" % (inamepart, values) + ) + return values[0] + + def getfailures(self, names="pytest_runtest_logreport pytest_collectreport"): + return [rep for rep in self.getreports(names) if rep.failed] + + def getfailedcollections(self): + return self.getfailures("pytest_collectreport") + + def listoutcomes(self): + passed = [] + skipped = [] + failed = [] + for rep in self.getreports("pytest_collectreport pytest_runtest_logreport"): + if rep.passed: + if getattr(rep, "when", None) == "call": + passed.append(rep) + elif rep.skipped: + skipped.append(rep) + elif rep.failed: + failed.append(rep) + return passed, skipped, failed + + def countoutcomes(self): + return [len(x) for x in self.listoutcomes()] + + def assertoutcome(self, passed=0, skipped=0, failed=0): + realpassed, realskipped, realfailed = self.listoutcomes() + assert passed == len(realpassed) + assert skipped == len(realskipped) + assert failed == len(realfailed) + + def clear(self): + self.calls[:] = [] + + +@pytest.fixture +def linecomp(request): + return LineComp() + + +@pytest.fixture(name="LineMatcher") +def LineMatcher_fixture(request): + return LineMatcher + + +@pytest.fixture +def testdir(request, tmpdir_factory): + return Testdir(request, tmpdir_factory) + + +rex_outcome = re.compile(r"(\d+) ([\w-]+)") + + +class RunResult(object): + """The result of running a command. + + Attributes: + + :ret: the return value + :outlines: list of lines captured from stdout + :errlines: list of lines captures from stderr + :stdout: :py:class:`LineMatcher` of stdout, use ``stdout.str()`` to + reconstruct stdout or the commonly used ``stdout.fnmatch_lines()`` + method + :stderr: :py:class:`LineMatcher` of stderr + :duration: duration in seconds + + """ + + def __init__(self, ret, outlines, errlines, duration): + self.ret = ret + self.outlines = outlines + self.errlines = errlines + self.stdout = LineMatcher(outlines) + self.stderr = LineMatcher(errlines) + self.duration = duration + + def parseoutcomes(self): + """Return a dictionary of outcomestring->num from parsing the terminal + output that the test process produced. + + """ + for line in reversed(self.outlines): + if "seconds" in line: + outcomes = rex_outcome.findall(line) + if outcomes: + d = {} + for num, cat in outcomes: + d[cat] = int(num) + return d + raise ValueError("Pytest terminal report not found") + + def assert_outcomes(self, passed=0, skipped=0, failed=0, error=0): + """Assert that the specified outcomes appear with the respective + numbers (0 means it didn't occur) in the text output from a test run. + + """ + d = self.parseoutcomes() + obtained = { + "passed": d.get("passed", 0), + "skipped": d.get("skipped", 0), + "failed": d.get("failed", 0), + "error": d.get("error", 0), + } + assert obtained == dict( + passed=passed, skipped=skipped, failed=failed, error=error + ) + + +class CwdSnapshot(object): + def __init__(self): + self.__saved = os.getcwd() + + def restore(self): + os.chdir(self.__saved) + + +class SysModulesSnapshot(object): + def __init__(self, preserve=None): + self.__preserve = preserve + self.__saved = dict(sys.modules) + + def restore(self): + if self.__preserve: + self.__saved.update( + (k, m) for k, m in sys.modules.items() if self.__preserve(k) + ) + sys.modules.clear() + sys.modules.update(self.__saved) + + +class SysPathsSnapshot(object): + def __init__(self): + self.__saved = list(sys.path), list(sys.meta_path) + + def restore(self): + sys.path[:], sys.meta_path[:] = self.__saved + + +class Testdir(object): + """Temporary test directory with tools to test/run pytest itself. + + This is based on the ``tmpdir`` fixture but provides a number of methods + which aid with testing pytest itself. Unless :py:meth:`chdir` is used all + methods will use :py:attr:`tmpdir` as their current working directory. + + Attributes: + + :tmpdir: The :py:class:`py.path.local` instance of the temporary directory. + + :plugins: A list of plugins to use with :py:meth:`parseconfig` and + :py:meth:`runpytest`. Initially this is an empty list but plugins can + be added to the list. The type of items to add to the list depends on + the method using them so refer to them for details. + + """ + + def __init__(self, request, tmpdir_factory): + self.request = request + self._mod_collections = WeakKeyDictionary() + name = request.function.__name__ + self.tmpdir = tmpdir_factory.mktemp(name, numbered=True) + self.plugins = [] + self._cwd_snapshot = CwdSnapshot() + self._sys_path_snapshot = SysPathsSnapshot() + self._sys_modules_snapshot = self.__take_sys_modules_snapshot() + self.chdir() + self.request.addfinalizer(self.finalize) + method = self.request.config.getoption("--runpytest") + if method == "inprocess": + self._runpytest_method = self.runpytest_inprocess + elif method == "subprocess": + self._runpytest_method = self.runpytest_subprocess + + def __repr__(self): + return "" % (self.tmpdir,) + + def finalize(self): + """Clean up global state artifacts. + + Some methods modify the global interpreter state and this tries to + clean this up. It does not remove the temporary directory however so + it can be looked at after the test run has finished. + + """ + self._sys_modules_snapshot.restore() + self._sys_path_snapshot.restore() + self._cwd_snapshot.restore() + + def __take_sys_modules_snapshot(self): + # some zope modules used by twisted-related tests keep internal state + # and can't be deleted; we had some trouble in the past with + # `zope.interface` for example + def preserve_module(name): + return name.startswith("zope") + + return SysModulesSnapshot(preserve=preserve_module) + + def make_hook_recorder(self, pluginmanager): + """Create a new :py:class:`HookRecorder` for a PluginManager.""" + assert not hasattr(pluginmanager, "reprec") + pluginmanager.reprec = reprec = HookRecorder(pluginmanager) + self.request.addfinalizer(reprec.finish_recording) + return reprec + + def chdir(self): + """Cd into the temporary directory. + + This is done automatically upon instantiation. + + """ + self.tmpdir.chdir() + + def _makefile(self, ext, args, kwargs, encoding="utf-8"): + items = list(kwargs.items()) + + def to_text(s): + return s.decode(encoding) if isinstance(s, bytes) else six.text_type(s) + + if args: + source = u"\n".join(to_text(x) for x in args) + basename = self.request.function.__name__ + items.insert(0, (basename, source)) + + ret = None + for basename, value in items: + p = self.tmpdir.join(basename).new(ext=ext) + p.dirpath().ensure_dir() + source = Source(value) + source = u"\n".join(to_text(line) for line in source.lines) + p.write(source.strip().encode(encoding), "wb") + if ret is None: + ret = p + return ret + + def makefile(self, ext, *args, **kwargs): + """Create a new file in the testdir. + + ext: The extension the file should use, including the dot, e.g. `.py`. + + args: All args will be treated as strings and joined using newlines. + The result will be written as contents to the file. The name of the + file will be based on the test function requesting this fixture. + E.g. "testdir.makefile('.txt', 'line1', 'line2')" + + kwargs: Each keyword is the name of a file, while the value of it will + be written as contents of the file. + E.g. "testdir.makefile('.ini', pytest='[pytest]\naddopts=-rs\n')" + + """ + return self._makefile(ext, args, kwargs) + + def makeconftest(self, source): + """Write a contest.py file with 'source' as contents.""" + return self.makepyfile(conftest=source) + + def makeini(self, source): + """Write a tox.ini file with 'source' as contents.""" + return self.makefile(".ini", tox=source) + + def getinicfg(self, source): + """Return the pytest section from the tox.ini config file.""" + p = self.makeini(source) + return py.iniconfig.IniConfig(p)["pytest"] + + def makepyfile(self, *args, **kwargs): + """Shortcut for .makefile() with a .py extension.""" + return self._makefile(".py", args, kwargs) + + def maketxtfile(self, *args, **kwargs): + """Shortcut for .makefile() with a .txt extension.""" + return self._makefile(".txt", args, kwargs) + + def syspathinsert(self, path=None): + """Prepend a directory to sys.path, defaults to :py:attr:`tmpdir`. + + This is undone automatically when this object dies at the end of each + test. + + """ + if path is None: + path = self.tmpdir + sys.path.insert(0, str(path)) + # a call to syspathinsert() usually means that the caller wants to + # import some dynamically created files, thus with python3 we + # invalidate its import caches + self._possibly_invalidate_import_caches() + + def _possibly_invalidate_import_caches(self): + # invalidate caches if we can (py33 and above) + try: + import importlib + except ImportError: + pass + else: + if hasattr(importlib, "invalidate_caches"): + importlib.invalidate_caches() + + def mkdir(self, name): + """Create a new (sub)directory.""" + return self.tmpdir.mkdir(name) + + def mkpydir(self, name): + """Create a new python package. + + This creates a (sub)directory with an empty ``__init__.py`` file so it + gets recognised as a python package. + + """ + p = self.mkdir(name) + p.ensure("__init__.py") + return p + + def copy_example(self, name=None): + from . import experiments + import warnings + + warnings.warn(experiments.PYTESTER_COPY_EXAMPLE, stacklevel=2) + example_dir = self.request.config.getini("pytester_example_dir") + if example_dir is None: + raise ValueError("pytester_example_dir is unset, can't copy examples") + example_dir = self.request.config.rootdir.join(example_dir) + + for extra_element in self.request.node.iter_markers("pytester_example_path"): + assert extra_element.args + example_dir = example_dir.join(*extra_element.args) + + if name is None: + func_name = self.request.function.__name__ + maybe_dir = example_dir / func_name + maybe_file = example_dir / (func_name + ".py") + + if maybe_dir.isdir(): + example_path = maybe_dir + elif maybe_file.isfile(): + example_path = maybe_file + else: + raise LookupError( + "{} cant be found as module or package in {}".format( + func_name, example_dir.bestrelpath(self.request.confg.rootdir) + ) + ) + else: + example_path = example_dir.join(name) + + if example_path.isdir() and not example_path.join("__init__.py").isfile(): + example_path.copy(self.tmpdir) + return self.tmpdir + elif example_path.isfile(): + result = self.tmpdir.join(example_path.basename) + example_path.copy(result) + return result + else: + raise LookupError("example is not found as a file or directory") + + Session = Session + + def getnode(self, config, arg): + """Return the collection node of a file. + + :param config: :py:class:`_pytest.config.Config` instance, see + :py:meth:`parseconfig` and :py:meth:`parseconfigure` to create the + configuration + + :param arg: a :py:class:`py.path.local` instance of the file + + """ + session = Session(config) + assert "::" not in str(arg) + p = py.path.local(arg) + config.hook.pytest_sessionstart(session=session) + res = session.perform_collect([str(p)], genitems=False)[0] + config.hook.pytest_sessionfinish(session=session, exitstatus=EXIT_OK) + return res + + def getpathnode(self, path): + """Return the collection node of a file. + + This is like :py:meth:`getnode` but uses :py:meth:`parseconfigure` to + create the (configured) pytest Config instance. + + :param path: a :py:class:`py.path.local` instance of the file + + """ + config = self.parseconfigure(path) + session = Session(config) + x = session.fspath.bestrelpath(path) + config.hook.pytest_sessionstart(session=session) + res = session.perform_collect([x], genitems=False)[0] + config.hook.pytest_sessionfinish(session=session, exitstatus=EXIT_OK) + return res + + def genitems(self, colitems): + """Generate all test items from a collection node. + + This recurses into the collection node and returns a list of all the + test items contained within. + + """ + session = colitems[0].session + result = [] + for colitem in colitems: + result.extend(session.genitems(colitem)) + return result + + def runitem(self, source): + """Run the "test_func" Item. + + The calling test instance (class containing the test method) must + provide a ``.getrunner()`` method which should return a runner which + can run the test protocol for a single item, e.g. + :py:func:`_pytest.runner.runtestprotocol`. + + """ + # used from runner functional tests + item = self.getitem(source) + # the test class where we are called from wants to provide the runner + testclassinstance = self.request.instance + runner = testclassinstance.getrunner() + return runner(item) + + def inline_runsource(self, source, *cmdlineargs): + """Run a test module in process using ``pytest.main()``. + + This run writes "source" into a temporary file and runs + ``pytest.main()`` on it, returning a :py:class:`HookRecorder` instance + for the result. + + :param source: the source code of the test module + + :param cmdlineargs: any extra command line arguments to use + + :return: :py:class:`HookRecorder` instance of the result + + """ + p = self.makepyfile(source) + values = list(cmdlineargs) + [p] + return self.inline_run(*values) + + def inline_genitems(self, *args): + """Run ``pytest.main(['--collectonly'])`` in-process. + + Runs the :py:func:`pytest.main` function to run all of pytest inside + the test process itself like :py:meth:`inline_run`, but returns a + tuple of the collected items and a :py:class:`HookRecorder` instance. + + """ + rec = self.inline_run("--collect-only", *args) + items = [x.item for x in rec.getcalls("pytest_itemcollected")] + return items, rec + + def inline_run(self, *args, **kwargs): + """Run ``pytest.main()`` in-process, returning a HookRecorder. + + Runs the :py:func:`pytest.main` function to run all of pytest inside + the test process itself. This means it can return a + :py:class:`HookRecorder` instance which gives more detailed results + from that run than can be done by matching stdout/stderr from + :py:meth:`runpytest`. + + :param args: command line arguments to pass to :py:func:`pytest.main` + + :param plugin: (keyword-only) extra plugin instances the + ``pytest.main()`` instance should use + + :return: a :py:class:`HookRecorder` instance + + """ + finalizers = [] + try: + # When running pytest inline any plugins active in the main test + # process are already imported. So this disables the warning which + # will trigger to say they can no longer be rewritten, which is + # fine as they have already been rewritten. + orig_warn = AssertionRewritingHook._warn_already_imported + + def revert_warn_already_imported(): + AssertionRewritingHook._warn_already_imported = orig_warn + + finalizers.append(revert_warn_already_imported) + AssertionRewritingHook._warn_already_imported = lambda *a: None + + # Any sys.module or sys.path changes done while running pytest + # inline should be reverted after the test run completes to avoid + # clashing with later inline tests run within the same pytest test, + # e.g. just because they use matching test module names. + finalizers.append(self.__take_sys_modules_snapshot().restore) + finalizers.append(SysPathsSnapshot().restore) + + # Important note: + # - our tests should not leave any other references/registrations + # laying around other than possibly loaded test modules + # referenced from sys.modules, as nothing will clean those up + # automatically + + rec = [] + + class Collect(object): + def pytest_configure(x, config): + rec.append(self.make_hook_recorder(config.pluginmanager)) + + plugins = kwargs.get("plugins") or [] + plugins.append(Collect()) + ret = pytest.main(list(args), plugins=plugins) + if len(rec) == 1: + reprec = rec.pop() + else: + + class reprec(object): + pass + + reprec.ret = ret + + # typically we reraise keyboard interrupts from the child run + # because it's our user requesting interruption of the testing + if ret == 2 and not kwargs.get("no_reraise_ctrlc"): + calls = reprec.getcalls("pytest_keyboard_interrupt") + if calls and calls[-1].excinfo.type == KeyboardInterrupt: + raise KeyboardInterrupt() + return reprec + finally: + for finalizer in finalizers: + finalizer() + + def runpytest_inprocess(self, *args, **kwargs): + """Return result of running pytest in-process, providing a similar + interface to what self.runpytest() provides. + + """ + if kwargs.get("syspathinsert"): + self.syspathinsert() + now = time.time() + capture = MultiCapture(Capture=SysCapture) + capture.start_capturing() + try: + try: + reprec = self.inline_run(*args, **kwargs) + except SystemExit as e: + + class reprec(object): + ret = e.args[0] + + except Exception: + traceback.print_exc() + + class reprec(object): + ret = 3 + + finally: + out, err = capture.readouterr() + capture.stop_capturing() + sys.stdout.write(out) + sys.stderr.write(err) + + res = RunResult(reprec.ret, out.split("\n"), err.split("\n"), time.time() - now) + res.reprec = reprec + return res + + def runpytest(self, *args, **kwargs): + """Run pytest inline or in a subprocess, depending on the command line + option "--runpytest" and return a :py:class:`RunResult`. + + """ + args = self._ensure_basetemp(args) + return self._runpytest_method(*args, **kwargs) + + def _ensure_basetemp(self, args): + args = [str(x) for x in args] + for x in args: + if str(x).startswith("--basetemp"): + # print("basedtemp exists: %s" %(args,)) + break + else: + args.append("--basetemp=%s" % self.tmpdir.dirpath("basetemp")) + # print("added basetemp: %s" %(args,)) + return args + + def parseconfig(self, *args): + """Return a new pytest Config instance from given commandline args. + + This invokes the pytest bootstrapping code in _pytest.config to create + a new :py:class:`_pytest.core.PluginManager` and call the + pytest_cmdline_parse hook to create a new + :py:class:`_pytest.config.Config` instance. + + If :py:attr:`plugins` has been populated they should be plugin modules + to be registered with the PluginManager. + + """ + args = self._ensure_basetemp(args) + + import _pytest.config + + config = _pytest.config._prepareconfig(args, self.plugins) + # we don't know what the test will do with this half-setup config + # object and thus we make sure it gets unconfigured properly in any + # case (otherwise capturing could still be active, for example) + self.request.addfinalizer(config._ensure_unconfigure) + return config + + def parseconfigure(self, *args): + """Return a new pytest configured Config instance. + + This returns a new :py:class:`_pytest.config.Config` instance like + :py:meth:`parseconfig`, but also calls the pytest_configure hook. + + """ + config = self.parseconfig(*args) + config._do_configure() + self.request.addfinalizer(config._ensure_unconfigure) + return config + + def getitem(self, source, funcname="test_func"): + """Return the test item for a test function. + + This writes the source to a python file and runs pytest's collection on + the resulting module, returning the test item for the requested + function name. + + :param source: the module source + + :param funcname: the name of the test function for which to return a + test item + + """ + items = self.getitems(source) + for item in items: + if item.name == funcname: + return item + assert 0, "%r item not found in module:\n%s\nitems: %s" % ( + funcname, + source, + items, + ) + + def getitems(self, source): + """Return all test items collected from the module. + + This writes the source to a python file and runs pytest's collection on + the resulting module, returning all test items contained within. + + """ + modcol = self.getmodulecol(source) + return self.genitems([modcol]) + + def getmodulecol(self, source, configargs=(), withinit=False): + """Return the module collection node for ``source``. + + This writes ``source`` to a file using :py:meth:`makepyfile` and then + runs the pytest collection on it, returning the collection node for the + test module. + + :param source: the source code of the module to collect + + :param configargs: any extra arguments to pass to + :py:meth:`parseconfigure` + + :param withinit: whether to also write an ``__init__.py`` file to the + same directory to ensure it is a package + + """ + if isinstance(source, Path): + path = self.tmpdir.join(str(source)) + assert not withinit, "not supported for paths" + else: + kw = {self.request.function.__name__: Source(source).strip()} + path = self.makepyfile(**kw) + if withinit: + self.makepyfile(__init__="#") + self.config = config = self.parseconfigure(path, *configargs) + return self.getnode(config, path) + + def collect_by_name(self, modcol, name): + """Return the collection node for name from the module collection. + + This will search a module collection node for a collection node + matching the given name. + + :param modcol: a module collection node; see :py:meth:`getmodulecol` + + :param name: the name of the node to return + + """ + if modcol not in self._mod_collections: + self._mod_collections[modcol] = list(modcol.collect()) + for colitem in self._mod_collections[modcol]: + if colitem.name == name: + return colitem + + def popen(self, cmdargs, stdout, stderr, **kw): + """Invoke subprocess.Popen. + + This calls subprocess.Popen making sure the current working directory + is in the PYTHONPATH. + + You probably want to use :py:meth:`run` instead. + + """ + env = os.environ.copy() + env["PYTHONPATH"] = os.pathsep.join( + filter(None, [str(os.getcwd()), env.get("PYTHONPATH", "")]) + ) + kw["env"] = env + + popen = subprocess.Popen( + cmdargs, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, **kw + ) + popen.stdin.close() + + return popen + + def run(self, *cmdargs): + """Run a command with arguments. + + Run a process using subprocess.Popen saving the stdout and stderr. + + Returns a :py:class:`RunResult`. + + """ + return self._run(*cmdargs) + + def _run(self, *cmdargs): + cmdargs = [str(x) for x in cmdargs] + p1 = self.tmpdir.join("stdout") + p2 = self.tmpdir.join("stderr") + print("running:", " ".join(cmdargs)) + print(" in:", str(py.path.local())) + f1 = codecs.open(str(p1), "w", encoding="utf8") + f2 = codecs.open(str(p2), "w", encoding="utf8") + try: + now = time.time() + popen = self.popen( + cmdargs, stdout=f1, stderr=f2, close_fds=(sys.platform != "win32") + ) + ret = popen.wait() + finally: + f1.close() + f2.close() + f1 = codecs.open(str(p1), "r", encoding="utf8") + f2 = codecs.open(str(p2), "r", encoding="utf8") + try: + out = f1.read().splitlines() + err = f2.read().splitlines() + finally: + f1.close() + f2.close() + self._dump_lines(out, sys.stdout) + self._dump_lines(err, sys.stderr) + return RunResult(ret, out, err, time.time() - now) + + def _dump_lines(self, lines, fp): + try: + for line in lines: + print(line, file=fp) + except UnicodeEncodeError: + print("couldn't print to %s because of encoding" % (fp,)) + + def _getpytestargs(self): + return (sys.executable, "-mpytest") + + def runpython(self, script): + """Run a python script using sys.executable as interpreter. + + Returns a :py:class:`RunResult`. + + """ + return self.run(sys.executable, script) + + def runpython_c(self, command): + """Run python -c "command", return a :py:class:`RunResult`.""" + return self.run(sys.executable, "-c", command) + + def runpytest_subprocess(self, *args, **kwargs): + """Run pytest as a subprocess with given arguments. + + Any plugins added to the :py:attr:`plugins` list will added using the + ``-p`` command line option. Additionally ``--basetemp`` is used put + any temporary files and directories in a numbered directory prefixed + with "runpytest-" so they do not conflict with the normal numbered + pytest location for temporary files and directories. + + Returns a :py:class:`RunResult`. + + """ + p = py.path.local.make_numbered_dir( + prefix="runpytest-", keep=None, rootdir=self.tmpdir + ) + args = ("--basetemp=%s" % p,) + args + plugins = [x for x in self.plugins if isinstance(x, str)] + if plugins: + args = ("-p", plugins[0]) + args + args = self._getpytestargs() + args + return self.run(*args) + + def spawn_pytest(self, string, expect_timeout=10.0): + """Run pytest using pexpect. + + This makes sure to use the right pytest and sets up the temporary + directory locations. + + The pexpect child is returned. + + """ + basetemp = self.tmpdir.mkdir("temp-pexpect") + invoke = " ".join(map(str, self._getpytestargs())) + cmd = "%s --basetemp=%s %s" % (invoke, basetemp, string) + return self.spawn(cmd, expect_timeout=expect_timeout) + + def spawn(self, cmd, expect_timeout=10.0): + """Run a command using pexpect. + + The pexpect child is returned. + + """ + pexpect = pytest.importorskip("pexpect", "3.0") + if hasattr(sys, "pypy_version_info") and "64" in platform.machine(): + pytest.skip("pypy-64 bit not supported") + if sys.platform.startswith("freebsd"): + pytest.xfail("pexpect does not work reliably on freebsd") + logfile = self.tmpdir.join("spawn.out").open("wb") + child = pexpect.spawn(cmd, logfile=logfile) + self.request.addfinalizer(logfile.close) + child.timeout = expect_timeout + return child + + +def getdecoded(out): + try: + return out.decode("utf-8") + except UnicodeDecodeError: + return "INTERNAL not-utf8-decodeable, truncated string:\n%s" % ( + py.io.saferepr(out), + ) + + +class LineComp(object): + def __init__(self): + self.stringio = py.io.TextIO() + + def assert_contains_lines(self, lines2): + """Assert that lines2 are contained (linearly) in lines1. + + Return a list of extralines found. + + """ + __tracebackhide__ = True + val = self.stringio.getvalue() + self.stringio.truncate(0) + self.stringio.seek(0) + lines1 = val.split("\n") + return LineMatcher(lines1).fnmatch_lines(lines2) + + +class LineMatcher(object): + """Flexible matching of text. + + This is a convenience class to test large texts like the output of + commands. + + The constructor takes a list of lines without their trailing newlines, i.e. + ``text.splitlines()``. + + """ + + def __init__(self, lines): + self.lines = lines + self._log_output = [] + + def str(self): + """Return the entire original text.""" + return "\n".join(self.lines) + + def _getlines(self, lines2): + if isinstance(lines2, str): + lines2 = Source(lines2) + if isinstance(lines2, Source): + lines2 = lines2.strip().lines + return lines2 + + def fnmatch_lines_random(self, lines2): + """Check lines exist in the output using in any order. + + Lines are checked using ``fnmatch.fnmatch``. The argument is a list of + lines which have to occur in the output, in any order. + + """ + self._match_lines_random(lines2, fnmatch) + + def re_match_lines_random(self, lines2): + """Check lines exist in the output using ``re.match``, in any order. + + The argument is a list of lines which have to occur in the output, in + any order. + + """ + self._match_lines_random(lines2, lambda name, pat: re.match(pat, name)) + + def _match_lines_random(self, lines2, match_func): + """Check lines exist in the output. + + The argument is a list of lines which have to occur in the output, in + any order. Each line can contain glob whildcards. + + """ + lines2 = self._getlines(lines2) + for line in lines2: + for x in self.lines: + if line == x or match_func(x, line): + self._log("matched: ", repr(line)) + break + else: + self._log("line %r not found in output" % line) + raise ValueError(self._log_text) + + def get_lines_after(self, fnline): + """Return all lines following the given line in the text. + + The given line can contain glob wildcards. + + """ + for i, line in enumerate(self.lines): + if fnline == line or fnmatch(line, fnline): + return self.lines[i + 1 :] + raise ValueError("line %r not found in output" % fnline) + + def _log(self, *args): + self._log_output.append(" ".join((str(x) for x in args))) + + @property + def _log_text(self): + return "\n".join(self._log_output) + + def fnmatch_lines(self, lines2): + """Search captured text for matching lines using ``fnmatch.fnmatch``. + + The argument is a list of lines which have to match and can use glob + wildcards. If they do not match a pytest.fail() is called. The + matches and non-matches are also printed on stdout. + + """ + self._match_lines(lines2, fnmatch, "fnmatch") + + def re_match_lines(self, lines2): + """Search captured text for matching lines using ``re.match``. + + The argument is a list of lines which have to match using ``re.match``. + If they do not match a pytest.fail() is called. + + The matches and non-matches are also printed on stdout. + + """ + self._match_lines(lines2, lambda name, pat: re.match(pat, name), "re.match") + + def _match_lines(self, lines2, match_func, match_nickname): + """Underlying implementation of ``fnmatch_lines`` and ``re_match_lines``. + + :param list[str] lines2: list of string patterns to match. The actual + format depends on ``match_func`` + :param match_func: a callable ``match_func(line, pattern)`` where line + is the captured line from stdout/stderr and pattern is the matching + pattern + :param str match_nickname: the nickname for the match function that + will be logged to stdout when a match occurs + + """ + lines2 = self._getlines(lines2) + lines1 = self.lines[:] + nextline = None + extralines = [] + __tracebackhide__ = True + for line in lines2: + nomatchprinted = False + while lines1: + nextline = lines1.pop(0) + if line == nextline: + self._log("exact match:", repr(line)) + break + elif match_func(nextline, line): + self._log("%s:" % match_nickname, repr(line)) + self._log(" with:", repr(nextline)) + break + else: + if not nomatchprinted: + self._log("nomatch:", repr(line)) + nomatchprinted = True + self._log(" and:", repr(nextline)) + extralines.append(nextline) + else: + self._log("remains unmatched: %r" % (line,)) + pytest.fail(self._log_text) diff --git a/Lib/site-packages/_pytest/python.py b/Lib/site-packages/_pytest/python.py new file mode 100644 index 0000000..5b8305e --- /dev/null +++ b/Lib/site-packages/_pytest/python.py @@ -0,0 +1,1447 @@ +""" Python test discovery, setup and run of test functions. """ +from __future__ import absolute_import, division, print_function + +import fnmatch +import inspect +import sys +import os +import collections +import warnings +from textwrap import dedent + + +import py +import six +from _pytest.main import FSHookProxy +from _pytest.mark import MarkerError +from _pytest.config import hookimpl + +import _pytest +import pluggy +from _pytest import fixtures +from _pytest import nodes +from _pytest import deprecated +from _pytest.compat import ( + isclass, + isfunction, + is_generator, + ascii_escaped, + REGEX_TYPE, + STRING_TYPES, + NoneType, + NOTSET, + get_real_func, + getfslineno, + safe_getattr, + safe_str, + getlocation, + enum, + get_default_arg_names, +) +from _pytest.outcomes import fail +from _pytest.mark.structures import ( + transfer_markers, + get_unpacked_marks, + normalize_mark_list, +) + + +# relative paths that we use to filter traceback entries from appearing to the user; +# see filter_traceback +# note: if we need to add more paths than what we have now we should probably use a list +# for better maintenance +_pluggy_dir = py.path.local(pluggy.__file__.rstrip("oc")) +# pluggy is either a package or a single module depending on the version +if _pluggy_dir.basename == "__init__.py": + _pluggy_dir = _pluggy_dir.dirpath() +_pytest_dir = py.path.local(_pytest.__file__).dirpath() +_py_dir = py.path.local(py.__file__).dirpath() + + +def filter_traceback(entry): + """Return True if a TracebackEntry instance should be removed from tracebacks: + * dynamically generated code (no code to show up for it); + * internal traceback from pytest or its internal libraries, py and pluggy. + """ + # entry.path might sometimes return a str object when the entry + # points to dynamically generated code + # see https://bitbucket.org/pytest-dev/py/issues/71 + raw_filename = entry.frame.code.raw.co_filename + is_generated = "<" in raw_filename and ">" in raw_filename + if is_generated: + return False + # entry.path might point to a non-existing file, in which case it will + # also return a str object. see #1133 + p = py.path.local(entry.path) + return ( + not p.relto(_pluggy_dir) and not p.relto(_pytest_dir) and not p.relto(_py_dir) + ) + + +def pyobj_property(name): + def get(self): + node = self.getparent(getattr(__import__("pytest"), name)) + if node is not None: + return node.obj + + doc = "python %s object this node was collected from (can be None)." % ( + name.lower(), + ) + return property(get, None, None, doc) + + +def pytest_addoption(parser): + group = parser.getgroup("general") + group.addoption( + "--fixtures", + "--funcargs", + action="store_true", + dest="showfixtures", + default=False, + help="show available fixtures, sorted by plugin appearance " + "(fixtures with leading '_' are only shown with '-v')", + ) + group.addoption( + "--fixtures-per-test", + action="store_true", + dest="show_fixtures_per_test", + default=False, + help="show fixtures per test", + ) + parser.addini( + "usefixtures", + type="args", + default=[], + help="list of default fixtures to be used with this project", + ) + parser.addini( + "python_files", + type="args", + default=["test_*.py", "*_test.py"], + help="glob-style file patterns for Python test module discovery", + ) + parser.addini( + "python_classes", + type="args", + default=["Test"], + help="prefixes or glob names for Python test class discovery", + ) + parser.addini( + "python_functions", + type="args", + default=["test"], + help="prefixes or glob names for Python test function and " "method discovery", + ) + + group.addoption( + "--import-mode", + default="prepend", + choices=["prepend", "append"], + dest="importmode", + help="prepend/append to sys.path when importing test modules, " + "default is to prepend.", + ) + + +def pytest_cmdline_main(config): + if config.option.showfixtures: + showfixtures(config) + return 0 + if config.option.show_fixtures_per_test: + show_fixtures_per_test(config) + return 0 + + +def pytest_generate_tests(metafunc): + # those alternative spellings are common - raise a specific error to alert + # the user + alt_spellings = ["parameterize", "parametrise", "parameterise"] + for attr in alt_spellings: + if hasattr(metafunc.function, attr): + msg = "{0} has '{1}', spelling should be 'parametrize'" + raise MarkerError(msg.format(metafunc.function.__name__, attr)) + for marker in metafunc.definition.iter_markers(name="parametrize"): + metafunc.parametrize(*marker.args, **marker.kwargs) + + +def pytest_configure(config): + config.addinivalue_line( + "markers", + "parametrize(argnames, argvalues): call a test function multiple " + "times passing in different arguments in turn. argvalues generally " + "needs to be a list of values if argnames specifies only one name " + "or a list of tuples of values if argnames specifies multiple names. " + "Example: @parametrize('arg1', [1,2]) would lead to two calls of the " + "decorated test function, one with arg1=1 and another with arg1=2." + "see http://pytest.org/latest/parametrize.html for more info and " + "examples.", + ) + config.addinivalue_line( + "markers", + "usefixtures(fixturename1, fixturename2, ...): mark tests as needing " + "all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures ", + ) + + +@hookimpl(trylast=True) +def pytest_pyfunc_call(pyfuncitem): + testfunction = pyfuncitem.obj + if pyfuncitem._isyieldedfunction(): + testfunction(*pyfuncitem._args) + else: + funcargs = pyfuncitem.funcargs + testargs = {} + for arg in pyfuncitem._fixtureinfo.argnames: + testargs[arg] = funcargs[arg] + testfunction(**testargs) + return True + + +def pytest_collect_file(path, parent): + ext = path.ext + if ext == ".py": + if not parent.session.isinitpath(path): + for pat in parent.config.getini("python_files") + ["__init__.py"]: + if path.fnmatch(pat): + break + else: + return + ihook = parent.session.gethookproxy(path) + return ihook.pytest_pycollect_makemodule(path=path, parent=parent) + + +def pytest_pycollect_makemodule(path, parent): + if path.basename == "__init__.py": + return Package(path, parent) + return Module(path, parent) + + +def pytest_ignore_collect(path, config): + # Skip duplicate packages. + keepduplicates = config.getoption("keepduplicates") + if keepduplicates: + duplicate_paths = config.pluginmanager._duplicatepaths + if path.basename == "__init__.py": + if path in duplicate_paths: + return True + else: + duplicate_paths.add(path) + + +@hookimpl(hookwrapper=True) +def pytest_pycollect_makeitem(collector, name, obj): + outcome = yield + res = outcome.get_result() + if res is not None: + return + # nothing was collected elsewhere, let's do it here + if isclass(obj): + if collector.istestclass(obj, name): + Class = collector._getcustomclass("Class") + outcome.force_result(Class(name, parent=collector)) + elif collector.istestfunction(obj, name): + # mock seems to store unbound methods (issue473), normalize it + obj = getattr(obj, "__func__", obj) + # We need to try and unwrap the function if it's a functools.partial + # or a funtools.wrapped. + # We musn't if it's been wrapped with mock.patch (python 2 only) + if not (isfunction(obj) or isfunction(get_real_func(obj))): + collector.warn( + code="C2", + message="cannot collect %r because it is not a function." % name, + ) + elif getattr(obj, "__test__", True): + if is_generator(obj): + res = Generator(name, parent=collector) + else: + res = list(collector._genfunctions(name, obj)) + outcome.force_result(res) + + +def pytest_make_parametrize_id(config, val, argname=None): + return None + + +class PyobjContext(object): + module = pyobj_property("Module") + cls = pyobj_property("Class") + instance = pyobj_property("Instance") + + +class PyobjMixin(PyobjContext): + _ALLOW_MARKERS = True + + def __init__(self, *k, **kw): + super(PyobjMixin, self).__init__(*k, **kw) + + def obj(): + def fget(self): + obj = getattr(self, "_obj", None) + if obj is None: + self._obj = obj = self._getobj() + # XXX evil hack + # used to avoid Instance collector marker duplication + if self._ALLOW_MARKERS: + self.own_markers.extend(get_unpacked_marks(self.obj)) + return obj + + def fset(self, value): + self._obj = value + + return property(fget, fset, None, "underlying python object") + + obj = obj() + + def _getobj(self): + return getattr(self.parent.obj, self.name) + + def getmodpath(self, stopatmodule=True, includemodule=False): + """ return python path relative to the containing module. """ + chain = self.listchain() + chain.reverse() + parts = [] + for node in chain: + if isinstance(node, Instance): + continue + name = node.name + if isinstance(node, Module): + name = os.path.splitext(name)[0] + if stopatmodule: + if includemodule: + parts.append(name) + break + parts.append(name) + parts.reverse() + s = ".".join(parts) + return s.replace(".[", "[") + + def _getfslineno(self): + return getfslineno(self.obj) + + def reportinfo(self): + # XXX caching? + obj = self.obj + compat_co_firstlineno = getattr(obj, "compat_co_firstlineno", None) + if isinstance(compat_co_firstlineno, int): + # nose compatibility + fspath = sys.modules[obj.__module__].__file__ + if fspath.endswith(".pyc"): + fspath = fspath[:-1] + lineno = compat_co_firstlineno + else: + fspath, lineno = getfslineno(obj) + modpath = self.getmodpath() + assert isinstance(lineno, int) + return fspath, lineno, modpath + + +class PyCollector(PyobjMixin, nodes.Collector): + def funcnamefilter(self, name): + return self._matches_prefix_or_glob_option("python_functions", name) + + def isnosetest(self, obj): + """ Look for the __test__ attribute, which is applied by the + @nose.tools.istest decorator + """ + # We explicitly check for "is True" here to not mistakenly treat + # classes with a custom __getattr__ returning something truthy (like a + # function) as test classes. + return safe_getattr(obj, "__test__", False) is True + + def classnamefilter(self, name): + return self._matches_prefix_or_glob_option("python_classes", name) + + def istestfunction(self, obj, name): + if self.funcnamefilter(name) or self.isnosetest(obj): + if isinstance(obj, staticmethod): + # static methods need to be unwrapped + obj = safe_getattr(obj, "__func__", False) + if obj is False: + # Python 2.6 wraps in a different way that we won't try to handle + msg = "cannot collect static method %r because it is not a function" + self.warn(code="C2", message=msg % name) + return False + return ( + safe_getattr(obj, "__call__", False) + and fixtures.getfixturemarker(obj) is None + ) + else: + return False + + def istestclass(self, obj, name): + return self.classnamefilter(name) or self.isnosetest(obj) + + def _matches_prefix_or_glob_option(self, option_name, name): + """ + checks if the given name matches the prefix or glob-pattern defined + in ini configuration. + """ + for option in self.config.getini(option_name): + if name.startswith(option): + return True + # check that name looks like a glob-string before calling fnmatch + # because this is called for every name in each collected module, + # and fnmatch is somewhat expensive to call + elif ("*" in option or "?" in option or "[" in option) and fnmatch.fnmatch( + name, option + ): + return True + return False + + def collect(self): + if not getattr(self.obj, "__test__", True): + return [] + + # NB. we avoid random getattrs and peek in the __dict__ instead + # (XXX originally introduced from a PyPy need, still true?) + dicts = [getattr(self.obj, "__dict__", {})] + for basecls in inspect.getmro(self.obj.__class__): + dicts.append(basecls.__dict__) + seen = {} + values = [] + for dic in dicts: + for name, obj in list(dic.items()): + if name in seen: + continue + seen[name] = True + res = self._makeitem(name, obj) + if res is None: + continue + if not isinstance(res, list): + res = [res] + values.extend(res) + values.sort(key=lambda item: item.reportinfo()[:2]) + return values + + def makeitem(self, name, obj): + warnings.warn(deprecated.COLLECTOR_MAKEITEM, stacklevel=2) + self._makeitem(name, obj) + + def _makeitem(self, name, obj): + # assert self.ihook.fspath == self.fspath, self + return self.ihook.pytest_pycollect_makeitem(collector=self, name=name, obj=obj) + + def _genfunctions(self, name, funcobj): + module = self.getparent(Module).obj + clscol = self.getparent(Class) + cls = clscol and clscol.obj or None + transfer_markers(funcobj, cls, module) + fm = self.session._fixturemanager + + definition = FunctionDefinition(name=name, parent=self, callobj=funcobj) + fixtureinfo = fm.getfixtureinfo(definition, funcobj, cls) + + metafunc = Metafunc( + definition, fixtureinfo, self.config, cls=cls, module=module + ) + methods = [] + if hasattr(module, "pytest_generate_tests"): + methods.append(module.pytest_generate_tests) + if hasattr(cls, "pytest_generate_tests"): + methods.append(cls().pytest_generate_tests) + if methods: + self.ihook.pytest_generate_tests.call_extra( + methods, dict(metafunc=metafunc) + ) + else: + self.ihook.pytest_generate_tests(metafunc=metafunc) + + Function = self._getcustomclass("Function") + if not metafunc._calls: + yield Function(name, parent=self, fixtureinfo=fixtureinfo) + else: + # add funcargs() as fixturedefs to fixtureinfo.arg2fixturedefs + fixtures.add_funcarg_pseudo_fixture_def(self, metafunc, fm) + + # add_funcarg_pseudo_fixture_def may have shadowed some fixtures + # with direct parametrization, so make sure we update what the + # function really needs. + fixtureinfo.prune_dependency_tree() + + for callspec in metafunc._calls: + subname = "%s[%s]" % (name, callspec.id) + yield Function( + name=subname, + parent=self, + callspec=callspec, + callobj=funcobj, + fixtureinfo=fixtureinfo, + keywords={callspec.id: True}, + originalname=name, + ) + + +class Module(nodes.File, PyCollector): + """ Collector for test classes and functions. """ + + def _getobj(self): + return self._importtestmodule() + + def collect(self): + self.session._fixturemanager.parsefactories(self) + return super(Module, self).collect() + + def _importtestmodule(self): + # we assume we are only called once per module + importmode = self.config.getoption("--import-mode") + try: + mod = self.fspath.pyimport(ensuresyspath=importmode) + except SyntaxError: + raise self.CollectError( + _pytest._code.ExceptionInfo().getrepr(style="short") + ) + except self.fspath.ImportMismatchError: + e = sys.exc_info()[1] + raise self.CollectError( + "import file mismatch:\n" + "imported module %r has this __file__ attribute:\n" + " %s\n" + "which is not the same as the test file we want to collect:\n" + " %s\n" + "HINT: remove __pycache__ / .pyc files and/or use a " + "unique basename for your test file modules" % e.args + ) + except ImportError: + from _pytest._code.code import ExceptionInfo + + exc_info = ExceptionInfo() + if self.config.getoption("verbose") < 2: + exc_info.traceback = exc_info.traceback.filter(filter_traceback) + exc_repr = ( + exc_info.getrepr(style="short") + if exc_info.traceback + else exc_info.exconly() + ) + formatted_tb = safe_str(exc_repr) + raise self.CollectError( + "ImportError while importing test module '{fspath}'.\n" + "Hint: make sure your test modules/packages have valid Python names.\n" + "Traceback:\n" + "{traceback}".format(fspath=self.fspath, traceback=formatted_tb) + ) + except _pytest.runner.Skipped as e: + if e.allow_module_level: + raise + raise self.CollectError( + "Using pytest.skip outside of a test is not allowed. " + "To decorate a test function, use the @pytest.mark.skip " + "or @pytest.mark.skipif decorators instead, and to skip a " + "module use `pytestmark = pytest.mark.{skip,skipif}." + ) + self.config.pluginmanager.consider_module(mod) + return mod + + def setup(self): + setup_module = _get_xunit_setup_teardown(self.obj, "setUpModule") + if setup_module is None: + setup_module = _get_xunit_setup_teardown(self.obj, "setup_module") + if setup_module is not None: + setup_module() + + teardown_module = _get_xunit_setup_teardown(self.obj, "tearDownModule") + if teardown_module is None: + teardown_module = _get_xunit_setup_teardown(self.obj, "teardown_module") + if teardown_module is not None: + self.addfinalizer(teardown_module) + + +class Package(Module): + def __init__(self, fspath, parent=None, config=None, session=None, nodeid=None): + session = parent.session + nodes.FSCollector.__init__( + self, fspath, parent=parent, config=config, session=session, nodeid=nodeid + ) + self.name = fspath.dirname + self.trace = session.trace + self._norecursepatterns = session._norecursepatterns + for path in list(session.config.pluginmanager._duplicatepaths): + if path.dirname == fspath.dirname and path != fspath: + session.config.pluginmanager._duplicatepaths.remove(path) + + def _recurse(self, path): + ihook = self.gethookproxy(path.dirpath()) + if ihook.pytest_ignore_collect(path=path, config=self.config): + return + for pat in self._norecursepatterns: + if path.check(fnmatch=pat): + return False + ihook = self.gethookproxy(path) + ihook.pytest_collect_directory(path=path, parent=self) + return True + + def gethookproxy(self, fspath): + # check if we have the common case of running + # hooks with all conftest.py filesall conftest.py + pm = self.config.pluginmanager + my_conftestmodules = pm._getconftestmodules(fspath) + remove_mods = pm._conftest_plugins.difference(my_conftestmodules) + if remove_mods: + # one or more conftests are not in use at this fspath + proxy = FSHookProxy(fspath, pm, remove_mods) + else: + # all plugis are active for this fspath + proxy = self.config.hook + return proxy + + def _collectfile(self, path): + ihook = self.gethookproxy(path) + if not self.isinitpath(path): + if ihook.pytest_ignore_collect(path=path, config=self.config): + return () + return ihook.pytest_collect_file(path=path, parent=self) + + def isinitpath(self, path): + return path in self.session._initialpaths + + def collect(self): + path = self.fspath.dirpath() + pkg_prefix = None + for path in path.visit(fil=lambda x: 1, rec=self._recurse, bf=True, sort=True): + if pkg_prefix and pkg_prefix in path.parts(): + continue + for x in self._collectfile(path): + yield x + if isinstance(x, Package): + pkg_prefix = path.dirpath() + + +def _get_xunit_setup_teardown(holder, attr_name, param_obj=None): + """ + Return a callable to perform xunit-style setup or teardown if + the function exists in the ``holder`` object. + The ``param_obj`` parameter is the parameter which will be passed to the function + when the callable is called without arguments, defaults to the ``holder`` object. + Return ``None`` if a suitable callable is not found. + """ + param_obj = param_obj if param_obj is not None else holder + result = _get_xunit_func(holder, attr_name) + if result is not None: + arg_count = result.__code__.co_argcount + if inspect.ismethod(result): + arg_count -= 1 + if arg_count: + return lambda: result(param_obj) + else: + return result + + +def _get_xunit_func(obj, name): + """Return the attribute from the given object to be used as a setup/teardown + xunit-style function, but only if not marked as a fixture to + avoid calling it twice. + """ + meth = getattr(obj, name, None) + if fixtures.getfixturemarker(meth) is None: + return meth + + +class Class(PyCollector): + """ Collector for test methods. """ + + def collect(self): + if not safe_getattr(self.obj, "__test__", True): + return [] + if hasinit(self.obj): + self.warn( + "C1", + "cannot collect test class %r because it has a " + "__init__ constructor" % self.obj.__name__, + ) + return [] + elif hasnew(self.obj): + self.warn( + "C1", + "cannot collect test class %r because it has a " + "__new__ constructor" % self.obj.__name__, + ) + return [] + return [self._getcustomclass("Instance")(name="()", parent=self)] + + def setup(self): + setup_class = _get_xunit_func(self.obj, "setup_class") + if setup_class is not None: + setup_class = getattr(setup_class, "im_func", setup_class) + setup_class = getattr(setup_class, "__func__", setup_class) + setup_class(self.obj) + + fin_class = getattr(self.obj, "teardown_class", None) + if fin_class is not None: + fin_class = getattr(fin_class, "im_func", fin_class) + fin_class = getattr(fin_class, "__func__", fin_class) + self.addfinalizer(lambda: fin_class(self.obj)) + + +class Instance(PyCollector): + _ALLOW_MARKERS = False # hack, destroy later + # instances share the object with their parents in a way + # that duplicates markers instances if not taken out + # can be removed at node strucutre reorganization time + + def _getobj(self): + return self.parent.obj() + + def collect(self): + self.session._fixturemanager.parsefactories(self) + return super(Instance, self).collect() + + def newinstance(self): + self.obj = self._getobj() + return self.obj + + +class FunctionMixin(PyobjMixin): + """ mixin for the code common to Function and Generator. + """ + + def setup(self): + """ perform setup for this test function. """ + if hasattr(self, "_preservedparent"): + obj = self._preservedparent + elif isinstance(self.parent, Instance): + obj = self.parent.newinstance() + self.obj = self._getobj() + else: + obj = self.parent.obj + if inspect.ismethod(self.obj): + setup_name = "setup_method" + teardown_name = "teardown_method" + else: + setup_name = "setup_function" + teardown_name = "teardown_function" + setup_func_or_method = _get_xunit_setup_teardown( + obj, setup_name, param_obj=self.obj + ) + if setup_func_or_method is not None: + setup_func_or_method() + teardown_func_or_method = _get_xunit_setup_teardown( + obj, teardown_name, param_obj=self.obj + ) + if teardown_func_or_method is not None: + self.addfinalizer(teardown_func_or_method) + + def _prunetraceback(self, excinfo): + if hasattr(self, "_obj") and not self.config.option.fulltrace: + code = _pytest._code.Code(get_real_func(self.obj)) + path, firstlineno = code.path, code.firstlineno + traceback = excinfo.traceback + ntraceback = traceback.cut(path=path, firstlineno=firstlineno) + if ntraceback == traceback: + ntraceback = ntraceback.cut(path=path) + if ntraceback == traceback: + ntraceback = ntraceback.filter(filter_traceback) + if not ntraceback: + ntraceback = traceback + + excinfo.traceback = ntraceback.filter() + # issue364: mark all but first and last frames to + # only show a single-line message for each frame + if self.config.option.tbstyle == "auto": + if len(excinfo.traceback) > 2: + for entry in excinfo.traceback[1:-1]: + entry.set_repr_style("short") + + def _repr_failure_py(self, excinfo, style="long"): + if excinfo.errisinstance(fail.Exception): + if not excinfo.value.pytrace: + return py._builtin._totext(excinfo.value) + return super(FunctionMixin, self)._repr_failure_py(excinfo, style=style) + + def repr_failure(self, excinfo, outerr=None): + assert outerr is None, "XXX outerr usage is deprecated" + style = self.config.option.tbstyle + if style == "auto": + style = "long" + return self._repr_failure_py(excinfo, style=style) + + +class Generator(FunctionMixin, PyCollector): + def collect(self): + # test generators are seen as collectors but they also + # invoke setup/teardown on popular request + # (induced by the common "test_*" naming shared with normal tests) + from _pytest import deprecated + + self.session._setupstate.prepare(self) + # see FunctionMixin.setup and test_setupstate_is_preserved_134 + self._preservedparent = self.parent.obj + values = [] + seen = {} + for i, x in enumerate(self.obj()): + name, call, args = self.getcallargs(x) + if not callable(call): + raise TypeError("%r yielded non callable test %r" % (self.obj, call)) + if name is None: + name = "[%d]" % i + else: + name = "['%s']" % name + if name in seen: + raise ValueError( + "%r generated tests with non-unique name %r" % (self, name) + ) + seen[name] = True + values.append(self.Function(name, self, args=args, callobj=call)) + self.warn("C1", deprecated.YIELD_TESTS) + return values + + def getcallargs(self, obj): + if not isinstance(obj, (tuple, list)): + obj = (obj,) + # explicit naming + if isinstance(obj[0], six.string_types): + name = obj[0] + obj = obj[1:] + else: + name = None + call, args = obj[0], obj[1:] + return name, call, args + + +def hasinit(obj): + init = getattr(obj, "__init__", None) + if init: + return init != object.__init__ + + +def hasnew(obj): + new = getattr(obj, "__new__", None) + if new: + return new != object.__new__ + + +class CallSpec2(object): + def __init__(self, metafunc): + self.metafunc = metafunc + self.funcargs = {} + self._idlist = [] + self.params = {} + self._globalid = NOTSET + self._globalparam = NOTSET + self._arg2scopenum = {} # used for sorting parametrized resources + self.marks = [] + self.indices = {} + + def copy(self): + cs = CallSpec2(self.metafunc) + cs.funcargs.update(self.funcargs) + cs.params.update(self.params) + cs.marks.extend(self.marks) + cs.indices.update(self.indices) + cs._arg2scopenum.update(self._arg2scopenum) + cs._idlist = list(self._idlist) + cs._globalid = self._globalid + cs._globalparam = self._globalparam + return cs + + def _checkargnotcontained(self, arg): + if arg in self.params or arg in self.funcargs: + raise ValueError("duplicate %r" % (arg,)) + + def getparam(self, name): + try: + return self.params[name] + except KeyError: + if self._globalparam is NOTSET: + raise ValueError(name) + return self._globalparam + + @property + def id(self): + return "-".join(map(str, filter(None, self._idlist))) + + def setmulti2(self, valtypes, argnames, valset, id, marks, scopenum, param_index): + for arg, val in zip(argnames, valset): + self._checkargnotcontained(arg) + valtype_for_arg = valtypes[arg] + getattr(self, valtype_for_arg)[arg] = val + self.indices[arg] = param_index + self._arg2scopenum[arg] = scopenum + self._idlist.append(id) + self.marks.extend(normalize_mark_list(marks)) + + def setall(self, funcargs, id, param): + for x in funcargs: + self._checkargnotcontained(x) + self.funcargs.update(funcargs) + if id is not NOTSET: + self._idlist.append(id) + if param is not NOTSET: + assert self._globalparam is NOTSET + self._globalparam = param + for arg in funcargs: + self._arg2scopenum[arg] = fixtures.scopenum_function + + +class Metafunc(fixtures.FuncargnamesCompatAttr): + """ + Metafunc objects are passed to the :func:`pytest_generate_tests <_pytest.hookspec.pytest_generate_tests>` hook. + They help to inspect a test function and to generate tests according to + test configuration or values specified in the class or module where a + test function is defined. + """ + + def __init__(self, definition, fixtureinfo, config, cls=None, module=None): + #: access to the :class:`_pytest.config.Config` object for the test session + assert ( + isinstance(definition, FunctionDefinition) + or type(definition).__name__ == "DefinitionMock" + ) + self.definition = definition + self.config = config + + #: the module object where the test function is defined in. + self.module = module + + #: underlying python test function + self.function = definition.obj + + #: set of fixture names required by the test function + self.fixturenames = fixtureinfo.names_closure + + #: class object where the test function is defined in or ``None``. + self.cls = cls + + self._calls = [] + self._ids = set() + self._arg2fixturedefs = fixtureinfo.name2fixturedefs + + def parametrize(self, argnames, argvalues, indirect=False, ids=None, scope=None): + """ Add new invocations to the underlying test function using the list + of argvalues for the given argnames. Parametrization is performed + during the collection phase. If you need to setup expensive resources + see about setting indirect to do it rather at test setup time. + + :arg argnames: a comma-separated string denoting one or more argument + names, or a list/tuple of argument strings. + + :arg argvalues: The list of argvalues determines how often a + test is invoked with different argument values. If only one + argname was specified argvalues is a list of values. If N + argnames were specified, argvalues must be a list of N-tuples, + where each tuple-element specifies a value for its respective + argname. + + :arg indirect: The list of argnames or boolean. A list of arguments' + names (subset of argnames). If True the list contains all names from + the argnames. Each argvalue corresponding to an argname in this list will + be passed as request.param to its respective argname fixture + function so that it can perform more expensive setups during the + setup phase of a test rather than at collection time. + + :arg ids: list of string ids, or a callable. + If strings, each is corresponding to the argvalues so that they are + part of the test id. If None is given as id of specific test, the + automatically generated id for that argument will be used. + If callable, it should take one argument (a single argvalue) and return + a string or return None. If None, the automatically generated id for that + argument will be used. + If no ids are provided they will be generated automatically from + the argvalues. + + :arg scope: if specified it denotes the scope of the parameters. + The scope is used for grouping tests by parameter instances. + It will also override any fixture-function defined scope, allowing + to set a dynamic scope using test context or configuration. + """ + from _pytest.fixtures import scope2index + from _pytest.mark import ParameterSet + + argnames, parameters = ParameterSet._for_parametrize( + argnames, argvalues, self.function, self.config + ) + del argvalues + + if scope is None: + scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect) + + self._validate_if_using_arg_names(argnames, indirect) + + arg_values_types = self._resolve_arg_value_types(argnames, indirect) + + ids = self._resolve_arg_ids(argnames, ids, parameters) + + scopenum = scope2index(scope, descr="call to {}".format(self.parametrize)) + + # create the new calls: if we are parametrize() multiple times (by applying the decorator + # more than once) then we accumulate those calls generating the cartesian product + # of all calls + newcalls = [] + for callspec in self._calls or [CallSpec2(self)]: + for param_index, (param_id, param_set) in enumerate(zip(ids, parameters)): + newcallspec = callspec.copy() + newcallspec.setmulti2( + arg_values_types, + argnames, + param_set.values, + param_id, + param_set.marks, + scopenum, + param_index, + ) + newcalls.append(newcallspec) + self._calls = newcalls + + def _resolve_arg_ids(self, argnames, ids, parameters): + """Resolves the actual ids for the given argnames, based on the ``ids`` parameter given + to ``parametrize``. + + :param List[str] argnames: list of argument names passed to ``parametrize()``. + :param ids: the ids parameter of the parametrized call (see docs). + :param List[ParameterSet] parameters: the list of parameter values, same size as ``argnames``. + :rtype: List[str] + :return: the list of ids for each argname given + """ + from py.io import saferepr + + idfn = None + if callable(ids): + idfn = ids + ids = None + if ids: + if len(ids) != len(parameters): + raise ValueError( + "%d tests specified with %d ids" % (len(parameters), len(ids)) + ) + for id_value in ids: + if id_value is not None and not isinstance(id_value, six.string_types): + msg = "ids must be list of strings, found: %s (type: %s)" + raise ValueError( + msg % (saferepr(id_value), type(id_value).__name__) + ) + ids = idmaker(argnames, parameters, idfn, ids, self.config) + return ids + + def _resolve_arg_value_types(self, argnames, indirect): + """Resolves if each parametrized argument must be considered a parameter to a fixture or a "funcarg" + to the function, based on the ``indirect`` parameter of the parametrized() call. + + :param List[str] argnames: list of argument names passed to ``parametrize()``. + :param indirect: same ``indirect`` parameter of ``parametrize()``. + :rtype: Dict[str, str] + A dict mapping each arg name to either: + * "params" if the argname should be the parameter of a fixture of the same name. + * "funcargs" if the argname should be a parameter to the parametrized test function. + """ + valtypes = {} + if indirect is True: + valtypes = dict.fromkeys(argnames, "params") + elif indirect is False: + valtypes = dict.fromkeys(argnames, "funcargs") + elif isinstance(indirect, (tuple, list)): + valtypes = dict.fromkeys(argnames, "funcargs") + for arg in indirect: + if arg not in argnames: + raise ValueError( + "indirect given to %r: fixture %r doesn't exist" + % (self.function, arg) + ) + valtypes[arg] = "params" + return valtypes + + def _validate_if_using_arg_names(self, argnames, indirect): + """ + Check if all argnames are being used, by default values, or directly/indirectly. + + :param List[str] argnames: list of argument names passed to ``parametrize()``. + :param indirect: same ``indirect`` parameter of ``parametrize()``. + :raise ValueError: if validation fails. + """ + default_arg_names = set(get_default_arg_names(self.function)) + for arg in argnames: + if arg not in self.fixturenames: + if arg in default_arg_names: + raise ValueError( + "%r already takes an argument %r with a default value" + % (self.function, arg) + ) + else: + if isinstance(indirect, (tuple, list)): + name = "fixture" if arg in indirect else "argument" + else: + name = "fixture" if indirect else "argument" + raise ValueError("%r uses no %s %r" % (self.function, name, arg)) + + def addcall(self, funcargs=None, id=NOTSET, param=NOTSET): + """ Add a new call to the underlying test function during the collection phase of a test run. + + .. deprecated:: 3.3 + + Use :meth:`parametrize` instead. + + Note that request.addcall() is called during the test collection phase prior and + independently to actual test execution. You should only use addcall() + if you need to specify multiple arguments of a test function. + + :arg funcargs: argument keyword dictionary used when invoking + the test function. + + :arg id: used for reporting and identification purposes. If you + don't supply an `id` an automatic unique id will be generated. + + :arg param: a parameter which will be exposed to a later fixture function + invocation through the ``request.param`` attribute. + """ + if self.config: + self.config.warn( + "C1", message=deprecated.METAFUNC_ADD_CALL, fslocation=None + ) + assert funcargs is None or isinstance(funcargs, dict) + if funcargs is not None: + for name in funcargs: + if name not in self.fixturenames: + fail("funcarg %r not used in this function." % name) + else: + funcargs = {} + if id is None: + raise ValueError("id=None not allowed") + if id is NOTSET: + id = len(self._calls) + id = str(id) + if id in self._ids: + raise ValueError("duplicate id %r" % id) + self._ids.add(id) + + cs = CallSpec2(self) + cs.setall(funcargs, id, param) + self._calls.append(cs) + + +def _find_parametrized_scope(argnames, arg2fixturedefs, indirect): + """Find the most appropriate scope for a parametrized call based on its arguments. + + When there's at least one direct argument, always use "function" scope. + + When a test function is parametrized and all its arguments are indirect + (e.g. fixtures), return the most narrow scope based on the fixtures used. + + Related to issue #1832, based on code posted by @Kingdread. + """ + from _pytest.fixtures import scopes + + indirect_as_list = isinstance(indirect, (list, tuple)) + all_arguments_are_fixtures = ( + indirect is True or indirect_as_list and len(indirect) == argnames + ) + if all_arguments_are_fixtures: + fixturedefs = arg2fixturedefs or {} + used_scopes = [fixturedef[0].scope for name, fixturedef in fixturedefs.items()] + if used_scopes: + # Takes the most narrow scope from used fixtures + for scope in reversed(scopes): + if scope in used_scopes: + return scope + + return "function" + + +def _idval(val, argname, idx, idfn, config=None): + if idfn: + s = None + try: + s = idfn(val) + except Exception: + # See issue https://github.com/pytest-dev/pytest/issues/2169 + import warnings + + msg = ( + "Raised while trying to determine id of parameter %s at position %d." + % (argname, idx) + ) + msg += "\nUpdate your code as this will raise an error in pytest-4.0." + warnings.warn(msg, DeprecationWarning) + if s: + return ascii_escaped(s) + + if config: + hook_id = config.hook.pytest_make_parametrize_id( + config=config, val=val, argname=argname + ) + if hook_id: + return hook_id + + if isinstance(val, STRING_TYPES): + return ascii_escaped(val) + elif isinstance(val, (float, int, bool, NoneType)): + return str(val) + elif isinstance(val, REGEX_TYPE): + return ascii_escaped(val.pattern) + elif enum is not None and isinstance(val, enum.Enum): + return str(val) + elif (isclass(val) or isfunction(val)) and hasattr(val, "__name__"): + return val.__name__ + return str(argname) + str(idx) + + +def _idvalset(idx, parameterset, argnames, idfn, ids, config=None): + if parameterset.id is not None: + return parameterset.id + if ids is None or (idx >= len(ids) or ids[idx] is None): + this_id = [ + _idval(val, argname, idx, idfn, config) + for val, argname in zip(parameterset.values, argnames) + ] + return "-".join(this_id) + else: + return ascii_escaped(ids[idx]) + + +def idmaker(argnames, parametersets, idfn=None, ids=None, config=None): + ids = [ + _idvalset(valindex, parameterset, argnames, idfn, ids, config) + for valindex, parameterset in enumerate(parametersets) + ] + if len(set(ids)) != len(ids): + # The ids are not unique + duplicates = [testid for testid in ids if ids.count(testid) > 1] + counters = collections.defaultdict(lambda: 0) + for index, testid in enumerate(ids): + if testid in duplicates: + ids[index] = testid + str(counters[testid]) + counters[testid] += 1 + return ids + + +def show_fixtures_per_test(config): + from _pytest.main import wrap_session + + return wrap_session(config, _show_fixtures_per_test) + + +def _show_fixtures_per_test(config, session): + import _pytest.config + + session.perform_collect() + curdir = py.path.local() + tw = _pytest.config.create_terminal_writer(config) + verbose = config.getvalue("verbose") + + def get_best_relpath(func): + loc = getlocation(func, curdir) + return curdir.bestrelpath(loc) + + def write_fixture(fixture_def): + argname = fixture_def.argname + if verbose <= 0 and argname.startswith("_"): + return + if verbose > 0: + bestrel = get_best_relpath(fixture_def.func) + funcargspec = "{} -- {}".format(argname, bestrel) + else: + funcargspec = argname + tw.line(funcargspec, green=True) + fixture_doc = fixture_def.func.__doc__ + if fixture_doc: + write_docstring(tw, fixture_doc) + else: + tw.line(" no docstring available", red=True) + + def write_item(item): + try: + info = item._fixtureinfo + except AttributeError: + # doctests items have no _fixtureinfo attribute + return + if not info.name2fixturedefs: + # this test item does not use any fixtures + return + tw.line() + tw.sep("-", "fixtures used by {}".format(item.name)) + tw.sep("-", "({})".format(get_best_relpath(item.function))) + # dict key not used in loop but needed for sorting + for _, fixturedefs in sorted(info.name2fixturedefs.items()): + assert fixturedefs is not None + if not fixturedefs: + continue + # last item is expected to be the one used by the test item + write_fixture(fixturedefs[-1]) + + for session_item in session.items: + write_item(session_item) + + +def showfixtures(config): + from _pytest.main import wrap_session + + return wrap_session(config, _showfixtures_main) + + +def _showfixtures_main(config, session): + import _pytest.config + + session.perform_collect() + curdir = py.path.local() + tw = _pytest.config.create_terminal_writer(config) + verbose = config.getvalue("verbose") + + fm = session._fixturemanager + + available = [] + seen = set() + + for argname, fixturedefs in fm._arg2fixturedefs.items(): + assert fixturedefs is not None + if not fixturedefs: + continue + for fixturedef in fixturedefs: + loc = getlocation(fixturedef.func, curdir) + if (fixturedef.argname, loc) in seen: + continue + seen.add((fixturedef.argname, loc)) + available.append( + ( + len(fixturedef.baseid), + fixturedef.func.__module__, + curdir.bestrelpath(loc), + fixturedef.argname, + fixturedef, + ) + ) + + available.sort() + currentmodule = None + for baseid, module, bestrel, argname, fixturedef in available: + if currentmodule != module: + if not module.startswith("_pytest."): + tw.line() + tw.sep("-", "fixtures defined from %s" % (module,)) + currentmodule = module + if verbose <= 0 and argname[0] == "_": + continue + if verbose > 0: + funcargspec = "%s -- %s" % (argname, bestrel) + else: + funcargspec = argname + tw.line(funcargspec, green=True) + loc = getlocation(fixturedef.func, curdir) + doc = fixturedef.func.__doc__ or "" + if doc: + write_docstring(tw, doc) + else: + tw.line(" %s: no docstring available" % (loc,), red=True) + + +def write_docstring(tw, doc): + INDENT = " " + doc = doc.rstrip() + if "\n" in doc: + firstline, rest = doc.split("\n", 1) + else: + firstline, rest = doc, "" + + if firstline.strip(): + tw.line(INDENT + firstline.strip()) + + if rest: + for line in dedent(rest).split("\n"): + tw.write(INDENT + line + "\n") + + +class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr): + """ a Function Item is responsible for setting up and executing a + Python test function. + """ + + _genid = None + # disable since functions handle it themselfes + _ALLOW_MARKERS = False + + def __init__( + self, + name, + parent, + args=None, + config=None, + callspec=None, + callobj=NOTSET, + keywords=None, + session=None, + fixtureinfo=None, + originalname=None, + ): + super(Function, self).__init__(name, parent, config=config, session=session) + self._args = args + if callobj is not NOTSET: + self.obj = callobj + + self.keywords.update(self.obj.__dict__) + self.own_markers.extend(get_unpacked_marks(self.obj)) + if callspec: + self.callspec = callspec + # this is total hostile and a mess + # keywords are broken by design by now + # this will be redeemed later + for mark in callspec.marks: + # feel free to cry, this was broken for years before + # and keywords cant fix it per design + self.keywords[mark.name] = mark + self.own_markers.extend(normalize_mark_list(callspec.marks)) + if keywords: + self.keywords.update(keywords) + + if fixtureinfo is None: + fixtureinfo = self.session._fixturemanager.getfixtureinfo( + self, self.obj, self.cls, funcargs=not self._isyieldedfunction() + ) + self._fixtureinfo = fixtureinfo + self.fixturenames = fixtureinfo.names_closure + self._initrequest() + + #: original function name, without any decorations (for example + #: parametrization adds a ``"[...]"`` suffix to function names). + #: + #: .. versionadded:: 3.0 + self.originalname = originalname + + def _initrequest(self): + self.funcargs = {} + if self._isyieldedfunction(): + assert not hasattr( + self, "callspec" + ), "yielded functions (deprecated) cannot have funcargs" + else: + if hasattr(self, "callspec"): + callspec = self.callspec + assert not callspec.funcargs + self._genid = callspec.id + if hasattr(callspec, "param"): + self.param = callspec.param + self._request = fixtures.FixtureRequest(self) + + @property + def function(self): + "underlying python 'function' object" + return getattr(self.obj, "im_func", self.obj) + + def _getobj(self): + name = self.name + i = name.find("[") # parametrization + if i != -1: + name = name[:i] + return getattr(self.parent.obj, name) + + @property + def _pyfuncitem(self): + "(compatonly) for code expecting pytest-2.2 style request objects" + return self + + def _isyieldedfunction(self): + return getattr(self, "_args", None) is not None + + def runtest(self): + """ execute the underlying test function. """ + self.ihook.pytest_pyfunc_call(pyfuncitem=self) + + def setup(self): + super(Function, self).setup() + fixtures.fillfixtures(self) + + +class FunctionDefinition(Function): + """ + internal hack until we get actual definition nodes instead of the + crappy metafunc hack + """ + + def runtest(self): + raise RuntimeError("function definitions are not supposed to be used") + + setup = runtest diff --git a/Lib/site-packages/_pytest/python_api.py b/Lib/site-packages/_pytest/python_api.py new file mode 100644 index 0000000..abc4d1e --- /dev/null +++ b/Lib/site-packages/_pytest/python_api.py @@ -0,0 +1,721 @@ +import math +import pprint +import sys +from numbers import Number +from decimal import Decimal + +import py +from six.moves import zip, filterfalse +from more_itertools.more import always_iterable + +from _pytest.compat import isclass + +from _pytest.compat import Mapping, Sequence +from _pytest.compat import STRING_TYPES + +from _pytest.outcomes import fail +import _pytest._code + +BASE_TYPE = (type, STRING_TYPES) + + +def _cmp_raises_type_error(self, other): + """__cmp__ implementation which raises TypeError. Used + by Approx base classes to implement only == and != and raise a + TypeError for other comparisons. + + Needed in Python 2 only, Python 3 all it takes is not implementing the + other operators at all. + """ + __tracebackhide__ = True + raise TypeError( + "Comparison operators other than == and != not supported by approx objects" + ) + + +def _non_numeric_type_error(value, at): + at_str = " at {}".format(at) if at else "" + return TypeError( + "cannot make approximate comparisons to non-numeric values: {!r} {}".format( + value, at_str + ) + ) + + +# builtin pytest.approx helper + + +class ApproxBase(object): + """ + Provide shared utilities for making approximate comparisons between numbers + or sequences of numbers. + """ + + # Tell numpy to use our `__eq__` operator instead of its. + __array_ufunc__ = None + __array_priority__ = 100 + + def __init__(self, expected, rel=None, abs=None, nan_ok=False): + __tracebackhide__ = True + self.expected = expected + self.abs = abs + self.rel = rel + self.nan_ok = nan_ok + self._check_type() + + def __repr__(self): + raise NotImplementedError + + def __eq__(self, actual): + return all( + a == self._approx_scalar(x) for a, x in self._yield_comparisons(actual) + ) + + __hash__ = None + + def __ne__(self, actual): + return not (actual == self) + + if sys.version_info[0] == 2: + __cmp__ = _cmp_raises_type_error + + def _approx_scalar(self, x): + return ApproxScalar(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok) + + def _yield_comparisons(self, actual): + """ + Yield all the pairs of numbers to be compared. This is used to + implement the `__eq__` method. + """ + raise NotImplementedError + + def _check_type(self): + """ + Raise a TypeError if the expected value is not a valid type. + """ + # This is only a concern if the expected value is a sequence. In every + # other case, the approx() function ensures that the expected value has + # a numeric type. For this reason, the default is to do nothing. The + # classes that deal with sequences should reimplement this method to + # raise if there are any non-numeric elements in the sequence. + pass + + +def _recursive_list_map(f, x): + if isinstance(x, list): + return list(_recursive_list_map(f, xi) for xi in x) + else: + return f(x) + + +class ApproxNumpy(ApproxBase): + """ + Perform approximate comparisons where the expected value is numpy array. + """ + + def __repr__(self): + list_scalars = _recursive_list_map(self._approx_scalar, self.expected.tolist()) + return "approx({!r})".format(list_scalars) + + if sys.version_info[0] == 2: + __cmp__ = _cmp_raises_type_error + + def __eq__(self, actual): + import numpy as np + + # self.expected is supposed to always be an array here + + if not np.isscalar(actual): + try: + actual = np.asarray(actual) + except: # noqa + raise TypeError("cannot compare '{}' to numpy.ndarray".format(actual)) + + if not np.isscalar(actual) and actual.shape != self.expected.shape: + return False + + return ApproxBase.__eq__(self, actual) + + def _yield_comparisons(self, actual): + import numpy as np + + # `actual` can either be a numpy array or a scalar, it is treated in + # `__eq__` before being passed to `ApproxBase.__eq__`, which is the + # only method that calls this one. + + if np.isscalar(actual): + for i in np.ndindex(self.expected.shape): + yield actual, np.asscalar(self.expected[i]) + else: + for i in np.ndindex(self.expected.shape): + yield np.asscalar(actual[i]), np.asscalar(self.expected[i]) + + +class ApproxMapping(ApproxBase): + """ + Perform approximate comparisons where the expected value is a mapping with + numeric values (the keys can be anything). + """ + + def __repr__(self): + return "approx({!r})".format( + {k: self._approx_scalar(v) for k, v in self.expected.items()} + ) + + def __eq__(self, actual): + if set(actual.keys()) != set(self.expected.keys()): + return False + + return ApproxBase.__eq__(self, actual) + + def _yield_comparisons(self, actual): + for k in self.expected.keys(): + yield actual[k], self.expected[k] + + def _check_type(self): + __tracebackhide__ = True + for key, value in self.expected.items(): + if isinstance(value, type(self.expected)): + msg = "pytest.approx() does not support nested dictionaries: key={!r} value={!r}\n full mapping={}" + raise TypeError(msg.format(key, value, pprint.pformat(self.expected))) + elif not isinstance(value, Number): + raise _non_numeric_type_error(self.expected, at="key={!r}".format(key)) + + +class ApproxSequence(ApproxBase): + """ + Perform approximate comparisons where the expected value is a sequence of + numbers. + """ + + def __repr__(self): + seq_type = type(self.expected) + if seq_type not in (tuple, list, set): + seq_type = list + return "approx({!r})".format( + seq_type(self._approx_scalar(x) for x in self.expected) + ) + + def __eq__(self, actual): + if len(actual) != len(self.expected): + return False + return ApproxBase.__eq__(self, actual) + + def _yield_comparisons(self, actual): + return zip(actual, self.expected) + + def _check_type(self): + __tracebackhide__ = True + for index, x in enumerate(self.expected): + if isinstance(x, type(self.expected)): + msg = "pytest.approx() does not support nested data structures: {!r} at index {}\n full sequence: {}" + raise TypeError(msg.format(x, index, pprint.pformat(self.expected))) + elif not isinstance(x, Number): + raise _non_numeric_type_error( + self.expected, at="index {}".format(index) + ) + + +class ApproxScalar(ApproxBase): + """ + Perform approximate comparisons where the expected value is a single number. + """ + + DEFAULT_ABSOLUTE_TOLERANCE = 1e-12 + DEFAULT_RELATIVE_TOLERANCE = 1e-6 + + def __repr__(self): + """ + Return a string communicating both the expected value and the tolerance + for the comparison being made, e.g. '1.0 +- 1e-6'. Use the unicode + plus/minus symbol if this is python3 (it's too hard to get right for + python2). + """ + if isinstance(self.expected, complex): + return str(self.expected) + + # Infinities aren't compared using tolerances, so don't show a + # tolerance. + if math.isinf(self.expected): + return str(self.expected) + + # If a sensible tolerance can't be calculated, self.tolerance will + # raise a ValueError. In this case, display '???'. + try: + vetted_tolerance = "{:.1e}".format(self.tolerance) + except ValueError: + vetted_tolerance = "???" + + if sys.version_info[0] == 2: + return "{} +- {}".format(self.expected, vetted_tolerance) + else: + return u"{} \u00b1 {}".format(self.expected, vetted_tolerance) + + def __eq__(self, actual): + """ + Return true if the given value is equal to the expected value within + the pre-specified tolerance. + """ + if _is_numpy_array(actual): + # Call ``__eq__()`` manually to prevent infinite-recursion with + # numpy<1.13. See #3748. + return all(self.__eq__(a) for a in actual.flat) + + # Short-circuit exact equality. + if actual == self.expected: + return True + + # Allow the user to control whether NaNs are considered equal to each + # other or not. The abs() calls are for compatibility with complex + # numbers. + if math.isnan(abs(self.expected)): + return self.nan_ok and math.isnan(abs(actual)) + + # Infinity shouldn't be approximately equal to anything but itself, but + # if there's a relative tolerance, it will be infinite and infinity + # will seem approximately equal to everything. The equal-to-itself + # case would have been short circuited above, so here we can just + # return false if the expected value is infinite. The abs() call is + # for compatibility with complex numbers. + if math.isinf(abs(self.expected)): + return False + + # Return true if the two numbers are within the tolerance. + return abs(self.expected - actual) <= self.tolerance + + __hash__ = None + + @property + def tolerance(self): + """ + Return the tolerance for the comparison. This could be either an + absolute tolerance or a relative tolerance, depending on what the user + specified or which would be larger. + """ + + def set_default(x, default): + return x if x is not None else default + + # Figure out what the absolute tolerance should be. ``self.abs`` is + # either None or a value specified by the user. + absolute_tolerance = set_default(self.abs, self.DEFAULT_ABSOLUTE_TOLERANCE) + + if absolute_tolerance < 0: + raise ValueError( + "absolute tolerance can't be negative: {}".format(absolute_tolerance) + ) + if math.isnan(absolute_tolerance): + raise ValueError("absolute tolerance can't be NaN.") + + # If the user specified an absolute tolerance but not a relative one, + # just return the absolute tolerance. + if self.rel is None: + if self.abs is not None: + return absolute_tolerance + + # Figure out what the relative tolerance should be. ``self.rel`` is + # either None or a value specified by the user. This is done after + # we've made sure the user didn't ask for an absolute tolerance only, + # because we don't want to raise errors about the relative tolerance if + # we aren't even going to use it. + relative_tolerance = set_default( + self.rel, self.DEFAULT_RELATIVE_TOLERANCE + ) * abs(self.expected) + + if relative_tolerance < 0: + raise ValueError( + "relative tolerance can't be negative: {}".format(absolute_tolerance) + ) + if math.isnan(relative_tolerance): + raise ValueError("relative tolerance can't be NaN.") + + # Return the larger of the relative and absolute tolerances. + return max(relative_tolerance, absolute_tolerance) + + +class ApproxDecimal(ApproxScalar): + """ + Perform approximate comparisons where the expected value is a decimal. + """ + + DEFAULT_ABSOLUTE_TOLERANCE = Decimal("1e-12") + DEFAULT_RELATIVE_TOLERANCE = Decimal("1e-6") + + +def approx(expected, rel=None, abs=None, nan_ok=False): + """ + Assert that two numbers (or two sets of numbers) are equal to each other + within some tolerance. + + Due to the `intricacies of floating-point arithmetic`__, numbers that we + would intuitively expect to be equal are not always so:: + + >>> 0.1 + 0.2 == 0.3 + False + + __ https://docs.python.org/3/tutorial/floatingpoint.html + + This problem is commonly encountered when writing tests, e.g. when making + sure that floating-point values are what you expect them to be. One way to + deal with this problem is to assert that two floating-point numbers are + equal to within some appropriate tolerance:: + + >>> abs((0.1 + 0.2) - 0.3) < 1e-6 + True + + However, comparisons like this are tedious to write and difficult to + understand. Furthermore, absolute comparisons like the one above are + usually discouraged because there's no tolerance that works well for all + situations. ``1e-6`` is good for numbers around ``1``, but too small for + very big numbers and too big for very small ones. It's better to express + the tolerance as a fraction of the expected value, but relative comparisons + like that are even more difficult to write correctly and concisely. + + The ``approx`` class performs floating-point comparisons using a syntax + that's as intuitive as possible:: + + >>> from pytest import approx + >>> 0.1 + 0.2 == approx(0.3) + True + + The same syntax also works for sequences of numbers:: + + >>> (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6)) + True + + Dictionary *values*:: + + >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6}) + True + + ``numpy`` arrays:: + + >>> import numpy as np # doctest: +SKIP + >>> np.array([0.1, 0.2]) + np.array([0.2, 0.4]) == approx(np.array([0.3, 0.6])) # doctest: +SKIP + True + + And for a ``numpy`` array against a scalar:: + + >>> import numpy as np # doctest: +SKIP + >>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) # doctest: +SKIP + True + + By default, ``approx`` considers numbers within a relative tolerance of + ``1e-6`` (i.e. one part in a million) of its expected value to be equal. + This treatment would lead to surprising results if the expected value was + ``0.0``, because nothing but ``0.0`` itself is relatively close to ``0.0``. + To handle this case less surprisingly, ``approx`` also considers numbers + within an absolute tolerance of ``1e-12`` of its expected value to be + equal. Infinity and NaN are special cases. Infinity is only considered + equal to itself, regardless of the relative tolerance. NaN is not + considered equal to anything by default, but you can make it be equal to + itself by setting the ``nan_ok`` argument to True. (This is meant to + facilitate comparing arrays that use NaN to mean "no data".) + + Both the relative and absolute tolerances can be changed by passing + arguments to the ``approx`` constructor:: + + >>> 1.0001 == approx(1) + False + >>> 1.0001 == approx(1, rel=1e-3) + True + >>> 1.0001 == approx(1, abs=1e-3) + True + + If you specify ``abs`` but not ``rel``, the comparison will not consider + the relative tolerance at all. In other words, two numbers that are within + the default relative tolerance of ``1e-6`` will still be considered unequal + if they exceed the specified absolute tolerance. If you specify both + ``abs`` and ``rel``, the numbers will be considered equal if either + tolerance is met:: + + >>> 1 + 1e-8 == approx(1) + True + >>> 1 + 1e-8 == approx(1, abs=1e-12) + False + >>> 1 + 1e-8 == approx(1, rel=1e-6, abs=1e-12) + True + + If you're thinking about using ``approx``, then you might want to know how + it compares to other good ways of comparing floating-point numbers. All of + these algorithms are based on relative and absolute tolerances and should + agree for the most part, but they do have meaningful differences: + + - ``math.isclose(a, b, rel_tol=1e-9, abs_tol=0.0)``: True if the relative + tolerance is met w.r.t. either ``a`` or ``b`` or if the absolute + tolerance is met. Because the relative tolerance is calculated w.r.t. + both ``a`` and ``b``, this test is symmetric (i.e. neither ``a`` nor + ``b`` is a "reference value"). You have to specify an absolute tolerance + if you want to compare to ``0.0`` because there is no tolerance by + default. Only available in python>=3.5. `More information...`__ + + __ https://docs.python.org/3/library/math.html#math.isclose + + - ``numpy.isclose(a, b, rtol=1e-5, atol=1e-8)``: True if the difference + between ``a`` and ``b`` is less that the sum of the relative tolerance + w.r.t. ``b`` and the absolute tolerance. Because the relative tolerance + is only calculated w.r.t. ``b``, this test is asymmetric and you can + think of ``b`` as the reference value. Support for comparing sequences + is provided by ``numpy.allclose``. `More information...`__ + + __ http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.isclose.html + + - ``unittest.TestCase.assertAlmostEqual(a, b)``: True if ``a`` and ``b`` + are within an absolute tolerance of ``1e-7``. No relative tolerance is + considered and the absolute tolerance cannot be changed, so this function + is not appropriate for very large or very small numbers. Also, it's only + available in subclasses of ``unittest.TestCase`` and it's ugly because it + doesn't follow PEP8. `More information...`__ + + __ https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertAlmostEqual + + - ``a == pytest.approx(b, rel=1e-6, abs=1e-12)``: True if the relative + tolerance is met w.r.t. ``b`` or if the absolute tolerance is met. + Because the relative tolerance is only calculated w.r.t. ``b``, this test + is asymmetric and you can think of ``b`` as the reference value. In the + special case that you explicitly specify an absolute tolerance but not a + relative tolerance, only the absolute tolerance is considered. + + .. warning:: + + .. versionchanged:: 3.2 + + In order to avoid inconsistent behavior, ``TypeError`` is + raised for ``>``, ``>=``, ``<`` and ``<=`` comparisons. + The example below illustrates the problem:: + + assert approx(0.1) > 0.1 + 1e-10 # calls approx(0.1).__gt__(0.1 + 1e-10) + assert 0.1 + 1e-10 > approx(0.1) # calls approx(0.1).__lt__(0.1 + 1e-10) + + In the second example one expects ``approx(0.1).__le__(0.1 + 1e-10)`` + to be called. But instead, ``approx(0.1).__lt__(0.1 + 1e-10)`` is used to + comparison. This is because the call hierarchy of rich comparisons + follows a fixed behavior. `More information...`__ + + __ https://docs.python.org/3/reference/datamodel.html#object.__ge__ + """ + + # Delegate the comparison to a class that knows how to deal with the type + # of the expected value (e.g. int, float, list, dict, numpy.array, etc). + # + # The primary responsibility of these classes is to implement ``__eq__()`` + # and ``__repr__()``. The former is used to actually check if some + # "actual" value is equivalent to the given expected value within the + # allowed tolerance. The latter is used to show the user the expected + # value and tolerance, in the case that a test failed. + # + # The actual logic for making approximate comparisons can be found in + # ApproxScalar, which is used to compare individual numbers. All of the + # other Approx classes eventually delegate to this class. The ApproxBase + # class provides some convenient methods and overloads, but isn't really + # essential. + + __tracebackhide__ = True + + if isinstance(expected, Decimal): + cls = ApproxDecimal + elif isinstance(expected, Number): + cls = ApproxScalar + elif isinstance(expected, Mapping): + cls = ApproxMapping + elif isinstance(expected, Sequence) and not isinstance(expected, STRING_TYPES): + cls = ApproxSequence + elif _is_numpy_array(expected): + cls = ApproxNumpy + else: + raise _non_numeric_type_error(expected, at=None) + + return cls(expected, rel, abs, nan_ok) + + +def _is_numpy_array(obj): + """ + Return true if the given object is a numpy array. Make a special effort to + avoid importing numpy unless it's really necessary. + """ + import sys + + np = sys.modules.get("numpy") + if np is not None: + return isinstance(obj, np.ndarray) + return False + + +# builtin pytest.raises helper + + +def raises(expected_exception, *args, **kwargs): + r""" + Assert that a code block/function call raises ``expected_exception`` + and raise a failure exception otherwise. + + :arg message: if specified, provides a custom failure message if the + exception is not raised + :arg match: if specified, asserts that the exception matches a text or regex + + This helper produces a ``ExceptionInfo()`` object (see below). + + You may use this function as a context manager:: + + >>> with raises(ZeroDivisionError): + ... 1/0 + + .. versionchanged:: 2.10 + + In the context manager form you may use the keyword argument + ``message`` to specify a custom failure message:: + + >>> with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"): + ... pass + Traceback (most recent call last): + ... + Failed: Expecting ZeroDivisionError + + .. note:: + + When using ``pytest.raises`` as a context manager, it's worthwhile to + note that normal context manager rules apply and that the exception + raised *must* be the final line in the scope of the context manager. + Lines of code after that, within the scope of the context manager will + not be executed. For example:: + + >>> value = 15 + >>> with raises(ValueError) as exc_info: + ... if value > 10: + ... raise ValueError("value must be <= 10") + ... assert exc_info.type == ValueError # this will not execute + + Instead, the following approach must be taken (note the difference in + scope):: + + >>> with raises(ValueError) as exc_info: + ... if value > 10: + ... raise ValueError("value must be <= 10") + ... + >>> assert exc_info.type == ValueError + + + Since version ``3.1`` you can use the keyword argument ``match`` to assert that the + exception matches a text or regex:: + + >>> with raises(ValueError, match='must be 0 or None'): + ... raise ValueError("value must be 0 or None") + + >>> with raises(ValueError, match=r'must be \d+$'): + ... raise ValueError("value must be 42") + + **Legacy forms** + + The forms below are fully supported but are discouraged for new code because the + context manager form is regarded as more readable and less error-prone. + + It is possible to specify a callable by passing a to-be-called lambda:: + + >>> raises(ZeroDivisionError, lambda: 1/0) + + + or you can specify an arbitrary callable with arguments:: + + >>> def f(x): return 1/x + ... + >>> raises(ZeroDivisionError, f, 0) + + >>> raises(ZeroDivisionError, f, x=0) + + + It is also possible to pass a string to be evaluated at runtime:: + + >>> raises(ZeroDivisionError, "f(0)") + + + The string will be evaluated using the same ``locals()`` and ``globals()`` + at the moment of the ``raises`` call. + + .. currentmodule:: _pytest._code + + Consult the API of ``excinfo`` objects: :class:`ExceptionInfo`. + + .. note:: + Similar to caught exception objects in Python, explicitly clearing + local references to returned ``ExceptionInfo`` objects can + help the Python interpreter speed up its garbage collection. + + Clearing those references breaks a reference cycle + (``ExceptionInfo`` --> caught exception --> frame stack raising + the exception --> current frame stack --> local variables --> + ``ExceptionInfo``) which makes Python keep all objects referenced + from that cycle (including all local variables in the current + frame) alive until the next cyclic garbage collection run. See the + official Python ``try`` statement documentation for more detailed + information. + + """ + __tracebackhide__ = True + for exc in filterfalse(isclass, always_iterable(expected_exception, BASE_TYPE)): + msg = ( + "exceptions must be old-style classes or" + " derived from BaseException, not %s" + ) + raise TypeError(msg % type(exc)) + + message = "DID NOT RAISE {}".format(expected_exception) + match_expr = None + + if not args: + if "message" in kwargs: + message = kwargs.pop("message") + if "match" in kwargs: + match_expr = kwargs.pop("match") + if kwargs: + msg = "Unexpected keyword arguments passed to pytest.raises: " + msg += ", ".join(kwargs.keys()) + raise TypeError(msg) + return RaisesContext(expected_exception, message, match_expr) + elif isinstance(args[0], str): + code, = args + assert isinstance(code, str) + frame = sys._getframe(1) + loc = frame.f_locals.copy() + loc.update(kwargs) + # print "raises frame scope: %r" % frame.f_locals + try: + code = _pytest._code.Source(code).compile() + py.builtin.exec_(code, frame.f_globals, loc) + # XXX didn'T mean f_globals == f_locals something special? + # this is destroyed here ... + except expected_exception: + return _pytest._code.ExceptionInfo() + else: + func = args[0] + try: + func(*args[1:], **kwargs) + except expected_exception: + return _pytest._code.ExceptionInfo() + fail(message) + + +raises.Exception = fail.Exception + + +class RaisesContext(object): + def __init__(self, expected_exception, message, match_expr): + self.expected_exception = expected_exception + self.message = message + self.match_expr = match_expr + self.excinfo = None + + def __enter__(self): + self.excinfo = object.__new__(_pytest._code.ExceptionInfo) + return self.excinfo + + def __exit__(self, *tp): + __tracebackhide__ = True + if tp[0] is None: + fail(self.message) + self.excinfo.__init__(tp) + suppress_exception = issubclass(self.excinfo.type, self.expected_exception) + if sys.version_info[0] == 2 and suppress_exception: + sys.exc_clear() + if self.match_expr and suppress_exception: + self.excinfo.match(self.match_expr) + return suppress_exception diff --git a/Lib/site-packages/_pytest/recwarn.py b/Lib/site-packages/_pytest/recwarn.py new file mode 100644 index 0000000..177757f --- /dev/null +++ b/Lib/site-packages/_pytest/recwarn.py @@ -0,0 +1,240 @@ +""" recording warnings during test function execution. """ +from __future__ import absolute_import, division, print_function + +import inspect + +import _pytest._code +import py +import sys +import warnings + +import re + +from _pytest.fixtures import yield_fixture +from _pytest.outcomes import fail + + +@yield_fixture +def recwarn(): + """Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions. + + See http://docs.python.org/library/warnings.html for information + on warning categories. + """ + wrec = WarningsRecorder() + with wrec: + warnings.simplefilter("default") + yield wrec + + +def deprecated_call(func=None, *args, **kwargs): + """context manager that can be used to ensure a block of code triggers a + ``DeprecationWarning`` or ``PendingDeprecationWarning``:: + + >>> import warnings + >>> def api_call_v2(): + ... warnings.warn('use v3 of this api', DeprecationWarning) + ... return 200 + + >>> with deprecated_call(): + ... assert api_call_v2() == 200 + + ``deprecated_call`` can also be used by passing a function and ``*args`` and ``*kwargs``, + in which case it will ensure calling ``func(*args, **kwargs)`` produces one of the warnings + types above. + """ + if not func: + return _DeprecatedCallContext() + else: + __tracebackhide__ = True + with _DeprecatedCallContext(): + return func(*args, **kwargs) + + +class _DeprecatedCallContext(object): + """Implements the logic to capture deprecation warnings as a context manager.""" + + def __enter__(self): + self._captured_categories = [] + self._old_warn = warnings.warn + self._old_warn_explicit = warnings.warn_explicit + warnings.warn_explicit = self._warn_explicit + warnings.warn = self._warn + + def _warn_explicit(self, message, category, *args, **kwargs): + self._captured_categories.append(category) + + def _warn(self, message, category=None, *args, **kwargs): + if isinstance(message, Warning): + self._captured_categories.append(message.__class__) + else: + self._captured_categories.append(category) + + def __exit__(self, exc_type, exc_val, exc_tb): + warnings.warn_explicit = self._old_warn_explicit + warnings.warn = self._old_warn + + if exc_type is None: + deprecation_categories = (DeprecationWarning, PendingDeprecationWarning) + if not any( + issubclass(c, deprecation_categories) for c in self._captured_categories + ): + __tracebackhide__ = True + msg = "Did not produce DeprecationWarning or PendingDeprecationWarning" + raise AssertionError(msg) + + +def warns(expected_warning, *args, **kwargs): + r"""Assert that code raises a particular class of warning. + + Specifically, the parameter ``expected_warning`` can be a warning class or + sequence of warning classes, and the inside the ``with`` block must issue a warning of that class or + classes. + + This helper produces a list of :class:`warnings.WarningMessage` objects, + one for each warning raised. + + This function can be used as a context manager, or any of the other ways + ``pytest.raises`` can be used:: + + >>> with warns(RuntimeWarning): + ... warnings.warn("my warning", RuntimeWarning) + + In the context manager form you may use the keyword argument ``match`` to assert + that the exception matches a text or regex:: + + >>> with warns(UserWarning, match='must be 0 or None'): + ... warnings.warn("value must be 0 or None", UserWarning) + + >>> with warns(UserWarning, match=r'must be \d+$'): + ... warnings.warn("value must be 42", UserWarning) + + >>> with warns(UserWarning, match=r'must be \d+$'): + ... warnings.warn("this is not here", UserWarning) + Traceback (most recent call last): + ... + Failed: DID NOT WARN. No warnings of type ...UserWarning... was emitted... + + """ + match_expr = None + if not args: + if "match" in kwargs: + match_expr = kwargs.pop("match") + return WarningsChecker(expected_warning, match_expr=match_expr) + elif isinstance(args[0], str): + code, = args + assert isinstance(code, str) + frame = sys._getframe(1) + loc = frame.f_locals.copy() + loc.update(kwargs) + + with WarningsChecker(expected_warning, match_expr=match_expr): + code = _pytest._code.Source(code).compile() + py.builtin.exec_(code, frame.f_globals, loc) + else: + func = args[0] + with WarningsChecker(expected_warning, match_expr=match_expr): + return func(*args[1:], **kwargs) + + +class WarningsRecorder(warnings.catch_warnings): + """A context manager to record raised warnings. + + Adapted from `warnings.catch_warnings`. + """ + + def __init__(self): + super(WarningsRecorder, self).__init__(record=True) + self._entered = False + self._list = [] + + @property + def list(self): + """The list of recorded warnings.""" + return self._list + + def __getitem__(self, i): + """Get a recorded warning by index.""" + return self._list[i] + + def __iter__(self): + """Iterate through the recorded warnings.""" + return iter(self._list) + + def __len__(self): + """The number of recorded warnings.""" + return len(self._list) + + def pop(self, cls=Warning): + """Pop the first recorded warning, raise exception if not exists.""" + for i, w in enumerate(self._list): + if issubclass(w.category, cls): + return self._list.pop(i) + __tracebackhide__ = True + raise AssertionError("%r not found in warning list" % cls) + + def clear(self): + """Clear the list of recorded warnings.""" + self._list[:] = [] + + def __enter__(self): + if self._entered: + __tracebackhide__ = True + raise RuntimeError("Cannot enter %r twice" % self) + self._list = super(WarningsRecorder, self).__enter__() + warnings.simplefilter("always") + return self + + def __exit__(self, *exc_info): + if not self._entered: + __tracebackhide__ = True + raise RuntimeError("Cannot exit %r without entering first" % self) + super(WarningsRecorder, self).__exit__(*exc_info) + + +class WarningsChecker(WarningsRecorder): + def __init__(self, expected_warning=None, match_expr=None): + super(WarningsChecker, self).__init__() + + msg = "exceptions must be old-style classes or " "derived from Warning, not %s" + if isinstance(expected_warning, tuple): + for exc in expected_warning: + if not inspect.isclass(exc): + raise TypeError(msg % type(exc)) + elif inspect.isclass(expected_warning): + expected_warning = (expected_warning,) + elif expected_warning is not None: + raise TypeError(msg % type(expected_warning)) + + self.expected_warning = expected_warning + self.match_expr = match_expr + + def __exit__(self, *exc_info): + super(WarningsChecker, self).__exit__(*exc_info) + + # only check if we're not currently handling an exception + if all(a is None for a in exc_info): + if self.expected_warning is not None: + if not any(issubclass(r.category, self.expected_warning) for r in self): + __tracebackhide__ = True + fail( + "DID NOT WARN. No warnings of type {} was emitted. " + "The list of emitted warnings is: {}.".format( + self.expected_warning, [each.message for each in self] + ) + ) + elif self.match_expr is not None: + for r in self: + if issubclass(r.category, self.expected_warning): + if re.compile(self.match_expr).search(str(r.message)): + break + else: + fail( + "DID NOT WARN. No warnings of type {} matching" + " ('{}') was emitted. The list of emitted warnings" + " is: {}.".format( + self.expected_warning, + self.match_expr, + [each.message for each in self], + ) + ) diff --git a/Lib/site-packages/_pytest/reports.py b/Lib/site-packages/_pytest/reports.py new file mode 100644 index 0000000..33b9067 --- /dev/null +++ b/Lib/site-packages/_pytest/reports.py @@ -0,0 +1,196 @@ +import py +from _pytest._code.code import TerminalRepr + + +def getslaveinfoline(node): + try: + return node._slaveinfocache + except AttributeError: + d = node.slaveinfo + ver = "%s.%s.%s" % d["version_info"][:3] + node._slaveinfocache = s = "[%s] %s -- Python %s %s" % ( + d["id"], + d["sysplatform"], + ver, + d["executable"], + ) + return s + + +class BaseReport(object): + def __init__(self, **kw): + self.__dict__.update(kw) + + def toterminal(self, out): + if hasattr(self, "node"): + out.line(getslaveinfoline(self.node)) + + longrepr = self.longrepr + if longrepr is None: + return + + if hasattr(longrepr, "toterminal"): + longrepr.toterminal(out) + else: + try: + out.line(longrepr) + except UnicodeEncodeError: + out.line("") + + def get_sections(self, prefix): + for name, content in self.sections: + if name.startswith(prefix): + yield prefix, content + + @property + def longreprtext(self): + """ + Read-only property that returns the full string representation + of ``longrepr``. + + .. versionadded:: 3.0 + """ + tw = py.io.TerminalWriter(stringio=True) + tw.hasmarkup = False + self.toterminal(tw) + exc = tw.stringio.getvalue() + return exc.strip() + + @property + def caplog(self): + """Return captured log lines, if log capturing is enabled + + .. versionadded:: 3.5 + """ + return "\n".join( + content for (prefix, content) in self.get_sections("Captured log") + ) + + @property + def capstdout(self): + """Return captured text from stdout, if capturing is enabled + + .. versionadded:: 3.0 + """ + return "".join( + content for (prefix, content) in self.get_sections("Captured stdout") + ) + + @property + def capstderr(self): + """Return captured text from stderr, if capturing is enabled + + .. versionadded:: 3.0 + """ + return "".join( + content for (prefix, content) in self.get_sections("Captured stderr") + ) + + passed = property(lambda x: x.outcome == "passed") + failed = property(lambda x: x.outcome == "failed") + skipped = property(lambda x: x.outcome == "skipped") + + @property + def fspath(self): + return self.nodeid.split("::")[0] + + +class TestReport(BaseReport): + """ Basic test report object (also used for setup and teardown calls if + they fail). + """ + + def __init__( + self, + nodeid, + location, + keywords, + outcome, + longrepr, + when, + sections=(), + duration=0, + user_properties=(), + **extra + ): + #: normalized collection node id + self.nodeid = nodeid + + #: a (filesystempath, lineno, domaininfo) tuple indicating the + #: actual location of a test item - it might be different from the + #: collected one e.g. if a method is inherited from a different module. + self.location = location + + #: a name -> value dictionary containing all keywords and + #: markers associated with a test invocation. + self.keywords = keywords + + #: test outcome, always one of "passed", "failed", "skipped". + self.outcome = outcome + + #: None or a failure representation. + self.longrepr = longrepr + + #: one of 'setup', 'call', 'teardown' to indicate runtest phase. + self.when = when + + #: user properties is a list of tuples (name, value) that holds user + #: defined properties of the test + self.user_properties = user_properties + + #: list of pairs ``(str, str)`` of extra information which needs to + #: marshallable. Used by pytest to add captured text + #: from ``stdout`` and ``stderr``, but may be used by other plugins + #: to add arbitrary information to reports. + self.sections = list(sections) + + #: time it took to run just the test + self.duration = duration + + self.__dict__.update(extra) + + def __repr__(self): + return "" % ( + self.nodeid, + self.when, + self.outcome, + ) + + +class TeardownErrorReport(BaseReport): + outcome = "failed" + when = "teardown" + + def __init__(self, longrepr, **extra): + self.longrepr = longrepr + self.sections = [] + self.__dict__.update(extra) + + +class CollectReport(BaseReport): + def __init__(self, nodeid, outcome, longrepr, result, sections=(), **extra): + self.nodeid = nodeid + self.outcome = outcome + self.longrepr = longrepr + self.result = result or [] + self.sections = list(sections) + self.__dict__.update(extra) + + @property + def location(self): + return (self.fspath, None, self.fspath) + + def __repr__(self): + return "" % ( + self.nodeid, + len(self.result), + self.outcome, + ) + + +class CollectErrorRepr(TerminalRepr): + def __init__(self, msg): + self.longrepr = msg + + def toterminal(self, out): + out.line(self.longrepr, red=True) diff --git a/Lib/site-packages/_pytest/resultlog.py b/Lib/site-packages/_pytest/resultlog.py new file mode 100644 index 0000000..0ad31b8 --- /dev/null +++ b/Lib/site-packages/_pytest/resultlog.py @@ -0,0 +1,119 @@ +""" log machine-parseable test session result information in a plain +text file. +""" +from __future__ import absolute_import, division, print_function + +import py +import os + + +def pytest_addoption(parser): + group = parser.getgroup("terminal reporting", "resultlog plugin options") + group.addoption( + "--resultlog", + "--result-log", + action="store", + metavar="path", + default=None, + help="DEPRECATED path for machine-readable result log.", + ) + + +def pytest_configure(config): + resultlog = config.option.resultlog + # prevent opening resultlog on slave nodes (xdist) + if resultlog and not hasattr(config, "slaveinput"): + dirname = os.path.dirname(os.path.abspath(resultlog)) + if not os.path.isdir(dirname): + os.makedirs(dirname) + logfile = open(resultlog, "w", 1) # line buffered + config._resultlog = ResultLog(config, logfile) + config.pluginmanager.register(config._resultlog) + + from _pytest.deprecated import RESULT_LOG + + config.warn("C1", RESULT_LOG) + + +def pytest_unconfigure(config): + resultlog = getattr(config, "_resultlog", None) + if resultlog: + resultlog.logfile.close() + del config._resultlog + config.pluginmanager.unregister(resultlog) + + +def generic_path(item): + chain = item.listchain() + gpath = [chain[0].name] + fspath = chain[0].fspath + fspart = False + for node in chain[1:]: + newfspath = node.fspath + if newfspath == fspath: + if fspart: + gpath.append(":") + fspart = False + else: + gpath.append(".") + else: + gpath.append("/") + fspart = True + name = node.name + if name[0] in "([": + gpath.pop() + gpath.append(name) + fspath = newfspath + return "".join(gpath) + + +class ResultLog(object): + def __init__(self, config, logfile): + self.config = config + self.logfile = logfile # preferably line buffered + + def write_log_entry(self, testpath, lettercode, longrepr): + print("%s %s" % (lettercode, testpath), file=self.logfile) + for line in longrepr.splitlines(): + print(" %s" % line, file=self.logfile) + + def log_outcome(self, report, lettercode, longrepr): + testpath = getattr(report, "nodeid", None) + if testpath is None: + testpath = report.fspath + self.write_log_entry(testpath, lettercode, longrepr) + + def pytest_runtest_logreport(self, report): + if report.when != "call" and report.passed: + return + res = self.config.hook.pytest_report_teststatus(report=report) + code = res[1] + if code == "x": + longrepr = str(report.longrepr) + elif code == "X": + longrepr = "" + elif report.passed: + longrepr = "" + elif report.failed: + longrepr = str(report.longrepr) + elif report.skipped: + longrepr = str(report.longrepr[2]) + self.log_outcome(report, code, longrepr) + + def pytest_collectreport(self, report): + if not report.passed: + if report.failed: + code = "F" + longrepr = str(report.longrepr) + else: + assert report.skipped + code = "S" + longrepr = "%s:%d: %s" % report.longrepr + self.log_outcome(report, code, longrepr) + + def pytest_internalerror(self, excrepr): + reprcrash = getattr(excrepr, "reprcrash", None) + path = getattr(reprcrash, "path", None) + if path is None: + path = "cwd:%s" % py.path.local() + self.write_log_entry(path, "!", str(excrepr)) diff --git a/Lib/site-packages/_pytest/runner.py b/Lib/site-packages/_pytest/runner.py new file mode 100644 index 0000000..5739bbe --- /dev/null +++ b/Lib/site-packages/_pytest/runner.py @@ -0,0 +1,383 @@ +""" basic collect and runtest protocol implementations """ +from __future__ import absolute_import, division, print_function + +import bdb +import os +import sys +from time import time + +import py +from _pytest._code.code import ExceptionInfo +from _pytest.outcomes import skip, Skipped, TEST_OUTCOME + +from .reports import TestReport, CollectReport, CollectErrorRepr + +# +# pytest plugin hooks + + +def pytest_addoption(parser): + group = parser.getgroup("terminal reporting", "reporting", after="general") + group.addoption( + "--durations", + action="store", + type=int, + default=None, + metavar="N", + help="show N slowest setup/test durations (N=0 for all).", + ), + + +def pytest_terminal_summary(terminalreporter): + durations = terminalreporter.config.option.durations + if durations is None: + return + tr = terminalreporter + dlist = [] + for replist in tr.stats.values(): + for rep in replist: + if hasattr(rep, "duration"): + dlist.append(rep) + if not dlist: + return + dlist.sort(key=lambda x: x.duration) + dlist.reverse() + if not durations: + tr.write_sep("=", "slowest test durations") + else: + tr.write_sep("=", "slowest %s test durations" % durations) + dlist = dlist[:durations] + + for rep in dlist: + nodeid = rep.nodeid.replace("::()::", "::") + tr.write_line("%02.2fs %-8s %s" % (rep.duration, rep.when, nodeid)) + + +def pytest_sessionstart(session): + session._setupstate = SetupState() + + +def pytest_sessionfinish(session): + session._setupstate.teardown_all() + + +def pytest_runtest_protocol(item, nextitem): + item.ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location) + runtestprotocol(item, nextitem=nextitem) + item.ihook.pytest_runtest_logfinish(nodeid=item.nodeid, location=item.location) + return True + + +def runtestprotocol(item, log=True, nextitem=None): + hasrequest = hasattr(item, "_request") + if hasrequest and not item._request: + item._initrequest() + rep = call_and_report(item, "setup", log) + reports = [rep] + if rep.passed: + if item.config.option.setupshow: + show_test_item(item) + if not item.config.option.setuponly: + reports.append(call_and_report(item, "call", log)) + reports.append(call_and_report(item, "teardown", log, nextitem=nextitem)) + # after all teardown hooks have been called + # want funcargs and request info to go away + if hasrequest: + item._request = False + item.funcargs = None + return reports + + +def show_test_item(item): + """Show test function, parameters and the fixtures of the test item.""" + tw = item.config.get_terminal_writer() + tw.line() + tw.write(" " * 8) + tw.write(item._nodeid) + used_fixtures = sorted(item._fixtureinfo.name2fixturedefs.keys()) + if used_fixtures: + tw.write(" (fixtures used: {})".format(", ".join(used_fixtures))) + + +def pytest_runtest_setup(item): + _update_current_test_var(item, "setup") + item.session._setupstate.prepare(item) + + +def pytest_runtest_call(item): + _update_current_test_var(item, "call") + sys.last_type, sys.last_value, sys.last_traceback = (None, None, None) + try: + item.runtest() + except Exception: + # Store trace info to allow postmortem debugging + type, value, tb = sys.exc_info() + tb = tb.tb_next # Skip *this* frame + sys.last_type = type + sys.last_value = value + sys.last_traceback = tb + del type, value, tb # Get rid of these in this frame + raise + + +def pytest_runtest_teardown(item, nextitem): + _update_current_test_var(item, "teardown") + item.session._setupstate.teardown_exact(item, nextitem) + _update_current_test_var(item, None) + + +def _update_current_test_var(item, when): + """ + Update PYTEST_CURRENT_TEST to reflect the current item and stage. + + If ``when`` is None, delete PYTEST_CURRENT_TEST from the environment. + """ + var_name = "PYTEST_CURRENT_TEST" + if when: + value = "{} ({})".format(item.nodeid, when) + # don't allow null bytes on environment variables (see #2644, #2957) + value = value.replace("\x00", "(null)") + os.environ[var_name] = value + else: + os.environ.pop(var_name) + + +def pytest_report_teststatus(report): + if report.when in ("setup", "teardown"): + if report.failed: + # category, shortletter, verbose-word + return "error", "E", "ERROR" + elif report.skipped: + return "skipped", "s", "SKIPPED" + else: + return "", "", "" + + +# +# Implementation + + +def call_and_report(item, when, log=True, **kwds): + call = call_runtest_hook(item, when, **kwds) + hook = item.ihook + report = hook.pytest_runtest_makereport(item=item, call=call) + if log: + hook.pytest_runtest_logreport(report=report) + if check_interactive_exception(call, report): + hook.pytest_exception_interact(node=item, call=call, report=report) + return report + + +def check_interactive_exception(call, report): + return call.excinfo and not ( + hasattr(report, "wasxfail") + or call.excinfo.errisinstance(skip.Exception) + or call.excinfo.errisinstance(bdb.BdbQuit) + ) + + +def call_runtest_hook(item, when, **kwds): + hookname = "pytest_runtest_" + when + ihook = getattr(item.ihook, hookname) + return CallInfo( + lambda: ihook(item=item, **kwds), + when=when, + treat_keyboard_interrupt_as_exception=item.config.getvalue("usepdb"), + ) + + +class CallInfo(object): + """ Result/Exception info a function invocation. """ + + #: None or ExceptionInfo object. + excinfo = None + + def __init__(self, func, when, treat_keyboard_interrupt_as_exception=False): + #: context of invocation: one of "setup", "call", + #: "teardown", "memocollect" + self.when = when + self.start = time() + try: + self.result = func() + except KeyboardInterrupt: + if treat_keyboard_interrupt_as_exception: + self.excinfo = ExceptionInfo() + else: + self.stop = time() + raise + except: # noqa + self.excinfo = ExceptionInfo() + self.stop = time() + + def __repr__(self): + if self.excinfo: + status = "exception: %s" % str(self.excinfo.value) + else: + status = "result: %r" % (self.result,) + return "" % (self.when, status) + + +def pytest_runtest_makereport(item, call): + when = call.when + duration = call.stop - call.start + keywords = {x: 1 for x in item.keywords} + excinfo = call.excinfo + sections = [] + if not call.excinfo: + outcome = "passed" + longrepr = None + else: + if not isinstance(excinfo, ExceptionInfo): + outcome = "failed" + longrepr = excinfo + elif excinfo.errisinstance(skip.Exception): + outcome = "skipped" + r = excinfo._getreprcrash() + longrepr = (str(r.path), r.lineno, r.message) + else: + outcome = "failed" + if call.when == "call": + longrepr = item.repr_failure(excinfo) + else: # exception in setup or teardown + longrepr = item._repr_failure_py( + excinfo, style=item.config.option.tbstyle + ) + for rwhen, key, content in item._report_sections: + sections.append(("Captured %s %s" % (key, rwhen), content)) + return TestReport( + item.nodeid, + item.location, + keywords, + outcome, + longrepr, + when, + sections, + duration, + user_properties=item.user_properties, + ) + + +def pytest_make_collect_report(collector): + call = CallInfo(lambda: list(collector.collect()), "collect") + longrepr = None + if not call.excinfo: + outcome = "passed" + else: + from _pytest import nose + + skip_exceptions = (Skipped,) + nose.get_skip_exceptions() + if call.excinfo.errisinstance(skip_exceptions): + outcome = "skipped" + r = collector._repr_failure_py(call.excinfo, "line").reprcrash + longrepr = (str(r.path), r.lineno, r.message) + else: + outcome = "failed" + errorinfo = collector.repr_failure(call.excinfo) + if not hasattr(errorinfo, "toterminal"): + errorinfo = CollectErrorRepr(errorinfo) + longrepr = errorinfo + rep = CollectReport( + collector.nodeid, outcome, longrepr, getattr(call, "result", None) + ) + rep.call = call # see collect_one_node + return rep + + +class SetupState(object): + """ shared state for setting up/tearing down test items or collectors. """ + + def __init__(self): + self.stack = [] + self._finalizers = {} + + def addfinalizer(self, finalizer, colitem): + """ attach a finalizer to the given colitem. + if colitem is None, this will add a finalizer that + is called at the end of teardown_all(). + """ + assert colitem and not isinstance(colitem, tuple) + assert callable(finalizer) + # assert colitem in self.stack # some unit tests don't setup stack :/ + self._finalizers.setdefault(colitem, []).append(finalizer) + + def _pop_and_teardown(self): + colitem = self.stack.pop() + self._teardown_with_finalization(colitem) + + def _callfinalizers(self, colitem): + finalizers = self._finalizers.pop(colitem, None) + exc = None + while finalizers: + fin = finalizers.pop() + try: + fin() + except TEST_OUTCOME: + # XXX Only first exception will be seen by user, + # ideally all should be reported. + if exc is None: + exc = sys.exc_info() + if exc: + py.builtin._reraise(*exc) + + def _teardown_with_finalization(self, colitem): + self._callfinalizers(colitem) + if hasattr(colitem, "teardown"): + colitem.teardown() + for colitem in self._finalizers: + assert ( + colitem is None or colitem in self.stack or isinstance(colitem, tuple) + ) + + def teardown_all(self): + while self.stack: + self._pop_and_teardown() + for key in list(self._finalizers): + self._teardown_with_finalization(key) + assert not self._finalizers + + def teardown_exact(self, item, nextitem): + needed_collectors = nextitem and nextitem.listchain() or [] + self._teardown_towards(needed_collectors) + + def _teardown_towards(self, needed_collectors): + exc = None + while self.stack: + if self.stack == needed_collectors[: len(self.stack)]: + break + try: + self._pop_and_teardown() + except TEST_OUTCOME: + # XXX Only first exception will be seen by user, + # ideally all should be reported. + if exc is None: + exc = sys.exc_info() + if exc: + py.builtin._reraise(*exc) + + def prepare(self, colitem): + """ setup objects along the collector chain to the test-method + and teardown previously setup objects.""" + needed_collectors = colitem.listchain() + self._teardown_towards(needed_collectors) + + # check if the last collection node has raised an error + for col in self.stack: + if hasattr(col, "_prepare_exc"): + py.builtin._reraise(*col._prepare_exc) + for col in needed_collectors[len(self.stack) :]: + self.stack.append(col) + try: + col.setup() + except TEST_OUTCOME: + col._prepare_exc = sys.exc_info() + raise + + +def collect_one_node(collector): + ihook = collector.ihook + ihook.pytest_collectstart(collector=collector) + rep = ihook.pytest_make_collect_report(collector=collector) + call = rep.__dict__.pop("call", None) + if call and check_interactive_exception(call, rep): + ihook.pytest_exception_interact(node=collector, call=call, report=rep) + return rep diff --git a/Lib/site-packages/_pytest/setuponly.py b/Lib/site-packages/_pytest/setuponly.py new file mode 100644 index 0000000..81240d9 --- /dev/null +++ b/Lib/site-packages/_pytest/setuponly.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import, division, print_function + +import pytest +import sys + + +def pytest_addoption(parser): + group = parser.getgroup("debugconfig") + group.addoption( + "--setuponly", + "--setup-only", + action="store_true", + help="only setup fixtures, do not execute tests.", + ) + group.addoption( + "--setupshow", + "--setup-show", + action="store_true", + help="show setup of fixtures while executing tests.", + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_fixture_setup(fixturedef, request): + yield + config = request.config + if config.option.setupshow: + if hasattr(request, "param"): + # Save the fixture parameter so ._show_fixture_action() can + # display it now and during the teardown (in .finish()). + if fixturedef.ids: + if callable(fixturedef.ids): + fixturedef.cached_param = fixturedef.ids(request.param) + else: + fixturedef.cached_param = fixturedef.ids[request.param_index] + else: + fixturedef.cached_param = request.param + _show_fixture_action(fixturedef, "SETUP") + + +def pytest_fixture_post_finalizer(fixturedef): + if hasattr(fixturedef, "cached_result"): + config = fixturedef._fixturemanager.config + if config.option.setupshow: + _show_fixture_action(fixturedef, "TEARDOWN") + if hasattr(fixturedef, "cached_param"): + del fixturedef.cached_param + + +def _show_fixture_action(fixturedef, msg): + config = fixturedef._fixturemanager.config + capman = config.pluginmanager.getplugin("capturemanager") + if capman: + out, err = capman.suspend_global_capture() + + tw = config.get_terminal_writer() + tw.line() + tw.write(" " * 2 * fixturedef.scopenum) + tw.write( + "{step} {scope} {fixture}".format( + step=msg.ljust(8), # align the output to TEARDOWN + scope=fixturedef.scope[0].upper(), + fixture=fixturedef.argname, + ) + ) + + if msg == "SETUP": + deps = sorted(arg for arg in fixturedef.argnames if arg != "request") + if deps: + tw.write(" (fixtures used: {})".format(", ".join(deps))) + + if hasattr(fixturedef, "cached_param"): + tw.write("[{}]".format(fixturedef.cached_param)) + + if capman: + capman.resume_global_capture() + sys.stdout.write(out) + sys.stderr.write(err) + + +@pytest.hookimpl(tryfirst=True) +def pytest_cmdline_main(config): + if config.option.setuponly: + config.option.setupshow = True diff --git a/Lib/site-packages/_pytest/setupplan.py b/Lib/site-packages/_pytest/setupplan.py new file mode 100644 index 0000000..23f4f97 --- /dev/null +++ b/Lib/site-packages/_pytest/setupplan.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import, division, print_function + +import pytest + + +def pytest_addoption(parser): + group = parser.getgroup("debugconfig") + group.addoption( + "--setupplan", + "--setup-plan", + action="store_true", + help="show what fixtures and tests would be executed but " + "don't execute anything.", + ) + + +@pytest.hookimpl(tryfirst=True) +def pytest_fixture_setup(fixturedef, request): + # Will return a dummy fixture if the setuponly option is provided. + if request.config.option.setupplan: + fixturedef.cached_result = (None, None, None) + return fixturedef.cached_result + + +@pytest.hookimpl(tryfirst=True) +def pytest_cmdline_main(config): + if config.option.setupplan: + config.option.setuponly = True + config.option.setupshow = True diff --git a/Lib/site-packages/_pytest/skipping.py b/Lib/site-packages/_pytest/skipping.py new file mode 100644 index 0000000..64bc770 --- /dev/null +++ b/Lib/site-packages/_pytest/skipping.py @@ -0,0 +1,294 @@ +""" support for skip/xfail functions and markers. """ +from __future__ import absolute_import, division, print_function + +from _pytest.config import hookimpl +from _pytest.mark.evaluate import MarkEvaluator +from _pytest.outcomes import fail, skip, xfail + + +def pytest_addoption(parser): + group = parser.getgroup("general") + group.addoption( + "--runxfail", + action="store_true", + dest="runxfail", + default=False, + help="run tests even if they are marked xfail", + ) + + parser.addini( + "xfail_strict", + "default for the strict parameter of xfail " + "markers when not given explicitly (default: False)", + default=False, + type="bool", + ) + + +def pytest_configure(config): + if config.option.runxfail: + # yay a hack + import pytest + + old = pytest.xfail + config._cleanup.append(lambda: setattr(pytest, "xfail", old)) + + def nop(*args, **kwargs): + pass + + nop.Exception = xfail.Exception + setattr(pytest, "xfail", nop) + + config.addinivalue_line( + "markers", + "skip(reason=None): skip the given test function with an optional reason. " + 'Example: skip(reason="no way of currently testing this") skips the ' + "test.", + ) + config.addinivalue_line( + "markers", + "skipif(condition): skip the given test function if eval(condition) " + "results in a True value. Evaluation happens within the " + "module global context. Example: skipif('sys.platform == \"win32\"') " + "skips the test if we are on the win32 platform. see " + "http://pytest.org/latest/skipping.html", + ) + config.addinivalue_line( + "markers", + "xfail(condition, reason=None, run=True, raises=None, strict=False): " + "mark the test function as an expected failure if eval(condition) " + "has a True value. Optionally specify a reason for better reporting " + "and run=False if you don't even want to execute the test function. " + "If only specific exception(s) are expected, you can list them in " + "raises, and if the test fails in other ways, it will be reported as " + "a true failure. See http://pytest.org/latest/skipping.html", + ) + + +@hookimpl(tryfirst=True) +def pytest_runtest_setup(item): + # Check if skip or skipif are specified as pytest marks + item._skipped_by_mark = False + eval_skipif = MarkEvaluator(item, "skipif") + if eval_skipif.istrue(): + item._skipped_by_mark = True + skip(eval_skipif.getexplanation()) + + for skip_info in item.iter_markers(name="skip"): + item._skipped_by_mark = True + if "reason" in skip_info.kwargs: + skip(skip_info.kwargs["reason"]) + elif skip_info.args: + skip(skip_info.args[0]) + else: + skip("unconditional skip") + + item._evalxfail = MarkEvaluator(item, "xfail") + check_xfail_no_run(item) + + +@hookimpl(hookwrapper=True) +def pytest_pyfunc_call(pyfuncitem): + check_xfail_no_run(pyfuncitem) + outcome = yield + passed = outcome.excinfo is None + if passed: + check_strict_xfail(pyfuncitem) + + +def check_xfail_no_run(item): + """check xfail(run=False)""" + if not item.config.option.runxfail: + evalxfail = item._evalxfail + if evalxfail.istrue(): + if not evalxfail.get("run", True): + xfail("[NOTRUN] " + evalxfail.getexplanation()) + + +def check_strict_xfail(pyfuncitem): + """check xfail(strict=True) for the given PASSING test""" + evalxfail = pyfuncitem._evalxfail + if evalxfail.istrue(): + strict_default = pyfuncitem.config.getini("xfail_strict") + is_strict_xfail = evalxfail.get("strict", strict_default) + if is_strict_xfail: + del pyfuncitem._evalxfail + explanation = evalxfail.getexplanation() + fail("[XPASS(strict)] " + explanation, pytrace=False) + + +@hookimpl(hookwrapper=True) +def pytest_runtest_makereport(item, call): + outcome = yield + rep = outcome.get_result() + evalxfail = getattr(item, "_evalxfail", None) + # unitttest special case, see setting of _unexpectedsuccess + if hasattr(item, "_unexpectedsuccess") and rep.when == "call": + from _pytest.compat import _is_unittest_unexpected_success_a_failure + + if item._unexpectedsuccess: + rep.longrepr = "Unexpected success: {}".format(item._unexpectedsuccess) + else: + rep.longrepr = "Unexpected success" + if _is_unittest_unexpected_success_a_failure(): + rep.outcome = "failed" + else: + rep.outcome = "passed" + rep.wasxfail = rep.longrepr + elif item.config.option.runxfail: + pass # don't interefere + elif call.excinfo and call.excinfo.errisinstance(xfail.Exception): + rep.wasxfail = "reason: " + call.excinfo.value.msg + rep.outcome = "skipped" + elif evalxfail and not rep.skipped and evalxfail.wasvalid() and evalxfail.istrue(): + if call.excinfo: + if evalxfail.invalidraise(call.excinfo.value): + rep.outcome = "failed" + else: + rep.outcome = "skipped" + rep.wasxfail = evalxfail.getexplanation() + elif call.when == "call": + strict_default = item.config.getini("xfail_strict") + is_strict_xfail = evalxfail.get("strict", strict_default) + explanation = evalxfail.getexplanation() + if is_strict_xfail: + rep.outcome = "failed" + rep.longrepr = "[XPASS(strict)] {}".format(explanation) + else: + rep.outcome = "passed" + rep.wasxfail = explanation + elif ( + getattr(item, "_skipped_by_mark", False) + and rep.skipped + and type(rep.longrepr) is tuple + ): + # skipped by mark.skipif; change the location of the failure + # to point to the item definition, otherwise it will display + # the location of where the skip exception was raised within pytest + filename, line, reason = rep.longrepr + filename, line = item.location[:2] + rep.longrepr = filename, line, reason + + +# called by terminalreporter progress reporting + + +def pytest_report_teststatus(report): + if hasattr(report, "wasxfail"): + if report.skipped: + return "xfailed", "x", "xfail" + elif report.passed: + return "xpassed", "X", ("XPASS", {"yellow": True}) + + +# called by the terminalreporter instance/plugin + + +def pytest_terminal_summary(terminalreporter): + tr = terminalreporter + if not tr.reportchars: + # for name in "xfailed skipped failed xpassed": + # if not tr.stats.get(name, 0): + # tr.write_line("HINT: use '-r' option to see extra " + # "summary info about tests") + # break + return + + lines = [] + for char in tr.reportchars: + action = REPORTCHAR_ACTIONS.get(char, lambda tr, lines: None) + action(terminalreporter, lines) + + if lines: + tr._tw.sep("=", "short test summary info") + for line in lines: + tr._tw.line(line) + + +def show_simple(terminalreporter, lines, stat, format): + failed = terminalreporter.stats.get(stat) + if failed: + for rep in failed: + pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid) + lines.append(format % (pos,)) + + +def show_xfailed(terminalreporter, lines): + xfailed = terminalreporter.stats.get("xfailed") + if xfailed: + for rep in xfailed: + pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid) + reason = rep.wasxfail + lines.append("XFAIL %s" % (pos,)) + if reason: + lines.append(" " + str(reason)) + + +def show_xpassed(terminalreporter, lines): + xpassed = terminalreporter.stats.get("xpassed") + if xpassed: + for rep in xpassed: + pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid) + reason = rep.wasxfail + lines.append("XPASS %s %s" % (pos, reason)) + + +def folded_skips(skipped): + d = {} + for event in skipped: + key = event.longrepr + assert len(key) == 3, (event, key) + keywords = getattr(event, "keywords", {}) + # folding reports with global pytestmark variable + # this is workaround, because for now we cannot identify the scope of a skip marker + # TODO: revisit after marks scope would be fixed + when = getattr(event, "when", None) + if when == "setup" and "skip" in keywords and "pytestmark" not in keywords: + key = (key[0], None, key[2]) + d.setdefault(key, []).append(event) + values = [] + for key, events in d.items(): + values.append((len(events),) + key) + return values + + +def show_skipped(terminalreporter, lines): + tr = terminalreporter + skipped = tr.stats.get("skipped", []) + if skipped: + # if not tr.hasopt('skipped'): + # tr.write_line( + # "%d skipped tests, specify -rs for more info" % + # len(skipped)) + # return + fskips = folded_skips(skipped) + if fskips: + # tr.write_sep("_", "skipped test summary") + for num, fspath, lineno, reason in fskips: + if reason.startswith("Skipped: "): + reason = reason[9:] + if lineno is not None: + lines.append( + "SKIP [%d] %s:%d: %s" % (num, fspath, lineno + 1, reason) + ) + else: + lines.append("SKIP [%d] %s: %s" % (num, fspath, reason)) + + +def shower(stat, format): + def show_(terminalreporter, lines): + return show_simple(terminalreporter, lines, stat, format) + + return show_ + + +REPORTCHAR_ACTIONS = { + "x": show_xfailed, + "X": show_xpassed, + "f": shower("failed", "FAIL %s"), + "F": shower("failed", "FAIL %s"), + "s": show_skipped, + "S": show_skipped, + "p": shower("passed", "PASSED %s"), + "E": shower("error", "ERROR %s"), +} diff --git a/Lib/site-packages/_pytest/terminal.py b/Lib/site-packages/_pytest/terminal.py new file mode 100644 index 0000000..7dd2edd --- /dev/null +++ b/Lib/site-packages/_pytest/terminal.py @@ -0,0 +1,832 @@ +""" terminal reporting of the full testing process. + +This is a good source for looking at the various reporting hooks. +""" +from __future__ import absolute_import, division, print_function + +import itertools +import platform +import sys +import time + +import pluggy +import py +import six +from more_itertools import collapse + +import pytest +from _pytest import nodes +from _pytest.main import ( + EXIT_OK, + EXIT_TESTSFAILED, + EXIT_INTERRUPTED, + EXIT_USAGEERROR, + EXIT_NOTESTSCOLLECTED, +) + + +import argparse + + +class MoreQuietAction(argparse.Action): + """ + a modified copy of the argparse count action which counts down and updates + the legacy quiet attribute at the same time + + used to unify verbosity handling + """ + + def __init__(self, option_strings, dest, default=None, required=False, help=None): + super(MoreQuietAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + default=default, + required=required, + help=help, + ) + + def __call__(self, parser, namespace, values, option_string=None): + new_count = getattr(namespace, self.dest, 0) - 1 + setattr(namespace, self.dest, new_count) + # todo Deprecate config.quiet + namespace.quiet = getattr(namespace, "quiet", 0) + 1 + + +def pytest_addoption(parser): + group = parser.getgroup("terminal reporting", "reporting", after="general") + group._addoption( + "-v", + "--verbose", + action="count", + default=0, + dest="verbose", + help="increase verbosity.", + ), + group._addoption( + "-q", + "--quiet", + action=MoreQuietAction, + default=0, + dest="verbose", + help="decrease verbosity.", + ), + group._addoption( + "--verbosity", dest="verbose", type=int, default=0, help="set verbosity" + ) + group._addoption( + "-r", + action="store", + dest="reportchars", + default="", + metavar="chars", + help="show extra test summary info as specified by chars (f)ailed, " + "(E)error, (s)skipped, (x)failed, (X)passed, " + "(p)passed, (P)passed with output, (a)all except pP. " + "Warnings are displayed at all times except when " + "--disable-warnings is set", + ) + group._addoption( + "--disable-warnings", + "--disable-pytest-warnings", + default=False, + dest="disable_warnings", + action="store_true", + help="disable warnings summary", + ) + group._addoption( + "-l", + "--showlocals", + action="store_true", + dest="showlocals", + default=False, + help="show locals in tracebacks (disabled by default).", + ) + group._addoption( + "--tb", + metavar="style", + action="store", + dest="tbstyle", + default="auto", + choices=["auto", "long", "short", "no", "line", "native"], + help="traceback print mode (auto/long/short/line/native/no).", + ) + group._addoption( + "--show-capture", + action="store", + dest="showcapture", + choices=["no", "stdout", "stderr", "log", "all"], + default="all", + help="Controls how captured stdout/stderr/log is shown on failed tests. " + "Default is 'all'.", + ) + group._addoption( + "--fulltrace", + "--full-trace", + action="store_true", + default=False, + help="don't cut any tracebacks (default is to cut).", + ) + group._addoption( + "--color", + metavar="color", + action="store", + dest="color", + default="auto", + choices=["yes", "no", "auto"], + help="color terminal output (yes/no/auto).", + ) + + parser.addini( + "console_output_style", + help="console output: classic or with additional progress information (classic|progress).", + default="progress", + ) + + +def pytest_configure(config): + reporter = TerminalReporter(config, sys.stdout) + config.pluginmanager.register(reporter, "terminalreporter") + if config.option.debug or config.option.traceconfig: + + def mywriter(tags, args): + msg = " ".join(map(str, args)) + reporter.write_line("[traceconfig] " + msg) + + config.trace.root.setprocessor("pytest:config", mywriter) + + +def getreportopt(config): + reportopts = "" + reportchars = config.option.reportchars + if not config.option.disable_warnings and "w" not in reportchars: + reportchars += "w" + elif config.option.disable_warnings and "w" in reportchars: + reportchars = reportchars.replace("w", "") + if reportchars: + for char in reportchars: + if char not in reportopts and char != "a": + reportopts += char + elif char == "a": + reportopts = "fEsxXw" + return reportopts + + +def pytest_report_teststatus(report): + if report.passed: + letter = "." + elif report.skipped: + letter = "s" + elif report.failed: + letter = "F" + if report.when != "call": + letter = "f" + return report.outcome, letter, report.outcome.upper() + + +class WarningReport(object): + """ + Simple structure to hold warnings information captured by ``pytest_logwarning``. + """ + + def __init__(self, code, message, nodeid=None, fslocation=None): + """ + :param code: unused + :param str message: user friendly message about the warning + :param str|None nodeid: node id that generated the warning (see ``get_location``). + :param tuple|py.path.local fslocation: + file system location of the source of the warning (see ``get_location``). + """ + self.code = code + self.message = message + self.nodeid = nodeid + self.fslocation = fslocation + + def get_location(self, config): + """ + Returns the more user-friendly information about the location + of a warning, or None. + """ + if self.nodeid: + return self.nodeid + if self.fslocation: + if isinstance(self.fslocation, tuple) and len(self.fslocation) >= 2: + filename, linenum = self.fslocation[:2] + relpath = py.path.local(filename).relto(config.invocation_dir) + return "%s:%s" % (relpath, linenum) + else: + return str(self.fslocation) + return None + + +class TerminalReporter(object): + def __init__(self, config, file=None): + import _pytest.config + + self.config = config + self.verbosity = self.config.option.verbose + self.showheader = self.verbosity >= 0 + self.showfspath = self.verbosity >= 0 + self.showlongtestinfo = self.verbosity > 0 + self._numcollected = 0 + self._session = None + + self.stats = {} + self.startdir = py.path.local() + if file is None: + file = sys.stdout + self._tw = _pytest.config.create_terminal_writer(config, file) + # self.writer will be deprecated in pytest-3.4 + self.writer = self._tw + self._screen_width = self._tw.fullwidth + self.currentfspath = None + self.reportchars = getreportopt(config) + self.hasmarkup = self._tw.hasmarkup + self.isatty = file.isatty() + self._progress_nodeids_reported = set() + self._show_progress_info = self._determine_show_progress_info() + + def _determine_show_progress_info(self): + """Return True if we should display progress information based on the current config""" + # do not show progress if we are not capturing output (#3038) + if self.config.getoption("capture") == "no": + return False + # do not show progress if we are showing fixture setup/teardown + if self.config.getoption("setupshow"): + return False + return self.config.getini("console_output_style") == "progress" + + def hasopt(self, char): + char = {"xfailed": "x", "skipped": "s"}.get(char, char) + return char in self.reportchars + + def write_fspath_result(self, nodeid, res): + fspath = self.config.rootdir.join(nodeid.split("::")[0]) + if fspath != self.currentfspath: + if self.currentfspath is not None: + self._write_progress_information_filling_space() + self.currentfspath = fspath + fspath = self.startdir.bestrelpath(fspath) + self._tw.line() + self._tw.write(fspath + " ") + self._tw.write(res) + + def write_ensure_prefix(self, prefix, extra="", **kwargs): + if self.currentfspath != prefix: + self._tw.line() + self.currentfspath = prefix + self._tw.write(prefix) + if extra: + self._tw.write(extra, **kwargs) + self.currentfspath = -2 + + def ensure_newline(self): + if self.currentfspath: + self._tw.line() + self.currentfspath = None + + def write(self, content, **markup): + self._tw.write(content, **markup) + + def write_line(self, line, **markup): + if not isinstance(line, six.text_type): + line = six.text_type(line, errors="replace") + self.ensure_newline() + self._tw.line(line, **markup) + + def rewrite(self, line, **markup): + """ + Rewinds the terminal cursor to the beginning and writes the given line. + + :kwarg erase: if True, will also add spaces until the full terminal width to ensure + previous lines are properly erased. + + The rest of the keyword arguments are markup instructions. + """ + erase = markup.pop("erase", False) + if erase: + fill_count = self._tw.fullwidth - len(line) - 1 + fill = " " * fill_count + else: + fill = "" + line = str(line) + self._tw.write("\r" + line + fill, **markup) + + def write_sep(self, sep, title=None, **markup): + self.ensure_newline() + self._tw.sep(sep, title, **markup) + + def section(self, title, sep="=", **kw): + self._tw.sep(sep, title, **kw) + + def line(self, msg, **kw): + self._tw.line(msg, **kw) + + def pytest_internalerror(self, excrepr): + for line in six.text_type(excrepr).split("\n"): + self.write_line("INTERNALERROR> " + line) + return 1 + + def pytest_logwarning(self, code, fslocation, message, nodeid): + warnings = self.stats.setdefault("warnings", []) + warning = WarningReport( + code=code, fslocation=fslocation, message=message, nodeid=nodeid + ) + warnings.append(warning) + + def pytest_plugin_registered(self, plugin): + if self.config.option.traceconfig: + msg = "PLUGIN registered: %s" % (plugin,) + # XXX this event may happen during setup/teardown time + # which unfortunately captures our output here + # which garbles our output if we use self.write_line + self.write_line(msg) + + def pytest_deselected(self, items): + self.stats.setdefault("deselected", []).extend(items) + + def pytest_runtest_logstart(self, nodeid, location): + # ensure that the path is printed before the + # 1st test of a module starts running + if self.showlongtestinfo: + line = self._locationline(nodeid, *location) + self.write_ensure_prefix(line, "") + elif self.showfspath: + fsid = nodeid.split("::")[0] + self.write_fspath_result(fsid, "") + + def pytest_runtest_logreport(self, report): + rep = report + res = self.config.hook.pytest_report_teststatus(report=rep) + cat, letter, word = res + if isinstance(word, tuple): + word, markup = word + else: + markup = None + self.stats.setdefault(cat, []).append(rep) + self._tests_ran = True + if not letter and not word: + # probably passed setup/teardown + return + running_xdist = hasattr(rep, "node") + if self.verbosity <= 0: + if not running_xdist and self.showfspath: + self.write_fspath_result(rep.nodeid, letter) + else: + self._tw.write(letter) + else: + self._progress_nodeids_reported.add(rep.nodeid) + if markup is None: + if rep.passed: + markup = {"green": True} + elif rep.failed: + markup = {"red": True} + elif rep.skipped: + markup = {"yellow": True} + else: + markup = {} + line = self._locationline(rep.nodeid, *rep.location) + if not running_xdist: + self.write_ensure_prefix(line, word, **markup) + if self._show_progress_info: + self._write_progress_information_filling_space() + else: + self.ensure_newline() + self._tw.write("[%s]" % rep.node.gateway.id) + if self._show_progress_info: + self._tw.write( + self._get_progress_information_message() + " ", cyan=True + ) + else: + self._tw.write(" ") + self._tw.write(word, **markup) + self._tw.write(" " + line) + self.currentfspath = -2 + + def pytest_runtest_logfinish(self, nodeid): + if self.verbosity <= 0 and self._show_progress_info: + self._progress_nodeids_reported.add(nodeid) + last_item = ( + len(self._progress_nodeids_reported) == self._session.testscollected + ) + if last_item: + self._write_progress_information_filling_space() + else: + past_edge = ( + self._tw.chars_on_current_line + self._PROGRESS_LENGTH + 1 + >= self._screen_width + ) + if past_edge: + msg = self._get_progress_information_message() + self._tw.write(msg + "\n", cyan=True) + + _PROGRESS_LENGTH = len(" [100%]") + + def _get_progress_information_message(self): + if self.config.getoption("capture") == "no": + return "" + collected = self._session.testscollected + if collected: + progress = len(self._progress_nodeids_reported) * 100 // collected + return " [{:3d}%]".format(progress) + return " [100%]" + + def _write_progress_information_filling_space(self): + msg = self._get_progress_information_message() + fill = " " * ( + self._tw.fullwidth - self._tw.chars_on_current_line - len(msg) - 1 + ) + self.write(fill + msg, cyan=True) + + def pytest_collection(self): + if not self.isatty and self.config.option.verbose >= 1: + self.write("collecting ... ", bold=True) + + def pytest_collectreport(self, report): + if report.failed: + self.stats.setdefault("error", []).append(report) + elif report.skipped: + self.stats.setdefault("skipped", []).append(report) + items = [x for x in report.result if isinstance(x, pytest.Item)] + self._numcollected += len(items) + if self.isatty: + # self.write_fspath_result(report.nodeid, 'E') + self.report_collect() + + def report_collect(self, final=False): + if self.config.option.verbose < 0: + return + + errors = len(self.stats.get("error", [])) + skipped = len(self.stats.get("skipped", [])) + deselected = len(self.stats.get("deselected", [])) + if final: + line = "collected " + else: + line = "collecting " + line += ( + str(self._numcollected) + " item" + ("" if self._numcollected == 1 else "s") + ) + if errors: + line += " / %d errors" % errors + if deselected: + line += " / %d deselected" % deselected + if skipped: + line += " / %d skipped" % skipped + if self.isatty: + self.rewrite(line, bold=True, erase=True) + if final: + self.write("\n") + else: + self.write_line(line) + + @pytest.hookimpl(trylast=True) + def pytest_collection_modifyitems(self): + self.report_collect(True) + + @pytest.hookimpl(trylast=True) + def pytest_sessionstart(self, session): + self._session = session + self._sessionstarttime = time.time() + if not self.showheader: + return + self.write_sep("=", "test session starts", bold=True) + verinfo = platform.python_version() + msg = "platform %s -- Python %s" % (sys.platform, verinfo) + if hasattr(sys, "pypy_version_info"): + verinfo = ".".join(map(str, sys.pypy_version_info[:3])) + msg += "[pypy-%s-%s]" % (verinfo, sys.pypy_version_info[3]) + msg += ", pytest-%s, py-%s, pluggy-%s" % ( + pytest.__version__, + py.__version__, + pluggy.__version__, + ) + if ( + self.verbosity > 0 + or self.config.option.debug + or getattr(self.config.option, "pastebin", None) + ): + msg += " -- " + str(sys.executable) + self.write_line(msg) + lines = self.config.hook.pytest_report_header( + config=self.config, startdir=self.startdir + ) + self._write_report_lines_from_hooks(lines) + + def _write_report_lines_from_hooks(self, lines): + lines.reverse() + for line in collapse(lines): + self.write_line(line) + + def pytest_report_header(self, config): + inifile = "" + if config.inifile: + inifile = " " + config.rootdir.bestrelpath(config.inifile) + lines = ["rootdir: %s, inifile:%s" % (config.rootdir, inifile)] + + plugininfo = config.pluginmanager.list_plugin_distinfo() + if plugininfo: + + lines.append("plugins: %s" % ", ".join(_plugin_nameversions(plugininfo))) + return lines + + def pytest_collection_finish(self, session): + if self.config.option.collectonly: + self._printcollecteditems(session.items) + if self.stats.get("failed"): + self._tw.sep("!", "collection failures") + for rep in self.stats.get("failed"): + rep.toterminal(self._tw) + return 1 + return 0 + lines = self.config.hook.pytest_report_collectionfinish( + config=self.config, startdir=self.startdir, items=session.items + ) + self._write_report_lines_from_hooks(lines) + + def _printcollecteditems(self, items): + # to print out items and their parent collectors + # we take care to leave out Instances aka () + # because later versions are going to get rid of them anyway + if self.config.option.verbose < 0: + if self.config.option.verbose < -1: + counts = {} + for item in items: + name = item.nodeid.split("::", 1)[0] + counts[name] = counts.get(name, 0) + 1 + for name, count in sorted(counts.items()): + self._tw.line("%s: %d" % (name, count)) + else: + for item in items: + nodeid = item.nodeid + nodeid = nodeid.replace("::()::", "::") + self._tw.line(nodeid) + return + stack = [] + indent = "" + for item in items: + needed_collectors = item.listchain()[1:] # strip root node + while stack: + if stack == needed_collectors[: len(stack)]: + break + stack.pop() + for col in needed_collectors[len(stack) :]: + stack.append(col) + # if col.name == "()": + # continue + indent = (len(stack) - 1) * " " + self._tw.line("%s%s" % (indent, col)) + + @pytest.hookimpl(hookwrapper=True) + def pytest_sessionfinish(self, exitstatus): + outcome = yield + outcome.get_result() + self._tw.line("") + summary_exit_codes = ( + EXIT_OK, + EXIT_TESTSFAILED, + EXIT_INTERRUPTED, + EXIT_USAGEERROR, + EXIT_NOTESTSCOLLECTED, + ) + if exitstatus in summary_exit_codes: + self.config.hook.pytest_terminal_summary( + terminalreporter=self, exitstatus=exitstatus + ) + if exitstatus == EXIT_INTERRUPTED: + self._report_keyboardinterrupt() + del self._keyboardinterrupt_memo + self.summary_stats() + + @pytest.hookimpl(hookwrapper=True) + def pytest_terminal_summary(self): + self.summary_errors() + self.summary_failures() + yield + self.summary_warnings() + self.summary_passes() + + def pytest_keyboard_interrupt(self, excinfo): + self._keyboardinterrupt_memo = excinfo.getrepr(funcargs=True) + + def pytest_unconfigure(self): + if hasattr(self, "_keyboardinterrupt_memo"): + self._report_keyboardinterrupt() + + def _report_keyboardinterrupt(self): + excrepr = self._keyboardinterrupt_memo + msg = excrepr.reprcrash.message + self.write_sep("!", msg) + if "KeyboardInterrupt" in msg: + if self.config.option.fulltrace: + excrepr.toterminal(self._tw) + else: + excrepr.reprcrash.toterminal(self._tw) + self._tw.line( + "(to show a full traceback on KeyboardInterrupt use --fulltrace)", + yellow=True, + ) + + def _locationline(self, nodeid, fspath, lineno, domain): + def mkrel(nodeid): + line = self.config.cwd_relative_nodeid(nodeid) + if domain and line.endswith(domain): + line = line[: -len(domain)] + values = domain.split("[") + values[0] = values[0].replace(".", "::") # don't replace '.' in params + line += "[".join(values) + return line + + # collect_fspath comes from testid which has a "/"-normalized path + + if fspath: + res = mkrel(nodeid).replace("::()", "") # parens-normalization + if nodeid.split("::")[0] != fspath.replace("\\", nodes.SEP): + res += " <- " + self.startdir.bestrelpath(fspath) + else: + res = "[location]" + return res + " " + + def _getfailureheadline(self, rep): + if hasattr(rep, "location"): + fspath, lineno, domain = rep.location + return domain + else: + return "test session" # XXX? + + def _getcrashline(self, rep): + try: + return str(rep.longrepr.reprcrash) + except AttributeError: + try: + return str(rep.longrepr)[:50] + except AttributeError: + return "" + + # + # summaries for sessionfinish + # + def getreports(self, name): + values = [] + for x in self.stats.get(name, []): + if not hasattr(x, "_pdbshown"): + values.append(x) + return values + + def summary_warnings(self): + if self.hasopt("w"): + all_warnings = self.stats.get("warnings") + if not all_warnings: + return + + grouped = itertools.groupby( + all_warnings, key=lambda wr: wr.get_location(self.config) + ) + + self.write_sep("=", "warnings summary", yellow=True, bold=False) + for location, warning_records in grouped: + self._tw.line(str(location) if location else "") + for w in warning_records: + lines = w.message.splitlines() + indented = "\n".join(" " + x for x in lines) + self._tw.line(indented) + self._tw.line() + self._tw.line("-- Docs: http://doc.pytest.org/en/latest/warnings.html") + + def summary_passes(self): + if self.config.option.tbstyle != "no": + if self.hasopt("P"): + reports = self.getreports("passed") + if not reports: + return + self.write_sep("=", "PASSES") + for rep in reports: + msg = self._getfailureheadline(rep) + self.write_sep("_", msg) + self._outrep_summary(rep) + + def print_teardown_sections(self, rep): + for secname, content in rep.sections: + if "teardown" in secname: + self._tw.sep("-", secname) + if content[-1:] == "\n": + content = content[:-1] + self._tw.line(content) + + def summary_failures(self): + if self.config.option.tbstyle != "no": + reports = self.getreports("failed") + if not reports: + return + self.write_sep("=", "FAILURES") + for rep in reports: + if self.config.option.tbstyle == "line": + line = self._getcrashline(rep) + self.write_line(line) + else: + msg = self._getfailureheadline(rep) + markup = {"red": True, "bold": True} + self.write_sep("_", msg, **markup) + self._outrep_summary(rep) + for report in self.getreports(""): + if report.nodeid == rep.nodeid and report.when == "teardown": + self.print_teardown_sections(report) + + def summary_errors(self): + if self.config.option.tbstyle != "no": + reports = self.getreports("error") + if not reports: + return + self.write_sep("=", "ERRORS") + for rep in self.stats["error"]: + msg = self._getfailureheadline(rep) + if not hasattr(rep, "when"): + # collect + msg = "ERROR collecting " + msg + elif rep.when == "setup": + msg = "ERROR at setup of " + msg + elif rep.when == "teardown": + msg = "ERROR at teardown of " + msg + self.write_sep("_", msg) + self._outrep_summary(rep) + + def _outrep_summary(self, rep): + rep.toterminal(self._tw) + showcapture = self.config.option.showcapture + if showcapture == "no": + return + for secname, content in rep.sections: + if showcapture != "all" and showcapture not in secname: + continue + self._tw.sep("-", secname) + if content[-1:] == "\n": + content = content[:-1] + self._tw.line(content) + + def summary_stats(self): + session_duration = time.time() - self._sessionstarttime + (line, color) = build_summary_stats_line(self.stats) + msg = "%s in %.2f seconds" % (line, session_duration) + markup = {color: True, "bold": True} + + if self.verbosity >= 0: + self.write_sep("=", msg, **markup) + if self.verbosity == -1: + self.write_line(msg, **markup) + + +def repr_pythonversion(v=None): + if v is None: + v = sys.version_info + try: + return "%s.%s.%s-%s-%s" % v + except (TypeError, ValueError): + return str(v) + + +def build_summary_stats_line(stats): + keys = ( + "failed passed skipped deselected " "xfailed xpassed warnings error" + ).split() + unknown_key_seen = False + for key in stats.keys(): + if key not in keys: + if key: # setup/teardown reports have an empty key, ignore them + keys.append(key) + unknown_key_seen = True + parts = [] + for key in keys: + val = stats.get(key, None) + if val: + parts.append("%d %s" % (len(val), key)) + + if parts: + line = ", ".join(parts) + else: + line = "no tests ran" + + if "failed" in stats or "error" in stats: + color = "red" + elif "warnings" in stats or unknown_key_seen: + color = "yellow" + elif "passed" in stats: + color = "green" + else: + color = "yellow" + + return (line, color) + + +def _plugin_nameversions(plugininfo): + values = [] + for plugin, dist in plugininfo: + # gets us name and version! + name = "{dist.project_name}-{dist.version}".format(dist=dist) + # questionable convenience, but it keeps things short + if name.startswith("pytest-"): + name = name[7:] + # we decided to print python package names + # they can have more than one plugin + if name not in values: + values.append(name) + return values diff --git a/Lib/site-packages/_pytest/tmpdir.py b/Lib/site-packages/_pytest/tmpdir.py new file mode 100644 index 0000000..260d284 --- /dev/null +++ b/Lib/site-packages/_pytest/tmpdir.py @@ -0,0 +1,131 @@ +""" support for providing temporary directories to test functions. """ +from __future__ import absolute_import, division, print_function + +import re + +import pytest +import py +from _pytest.monkeypatch import MonkeyPatch + + +class TempdirFactory(object): + """Factory for temporary directories under the common base temp directory. + + The base directory can be configured using the ``--basetemp`` option. + """ + + def __init__(self, config): + self.config = config + self.trace = config.trace.get("tmpdir") + + def ensuretemp(self, string, dir=1): + """ (deprecated) return temporary directory path with + the given string as the trailing part. It is usually + better to use the 'tmpdir' function argument which + provides an empty unique-per-test-invocation directory + and is guaranteed to be empty. + """ + # py.log._apiwarn(">1.1", "use tmpdir function argument") + return self.getbasetemp().ensure(string, dir=dir) + + def mktemp(self, basename, numbered=True): + """Create a subdirectory of the base temporary directory and return it. + If ``numbered``, ensure the directory is unique by adding a number + prefix greater than any existing one. + """ + basetemp = self.getbasetemp() + if not numbered: + p = basetemp.mkdir(basename) + else: + p = py.path.local.make_numbered_dir( + prefix=basename, keep=0, rootdir=basetemp, lock_timeout=None + ) + self.trace("mktemp", p) + return p + + def getbasetemp(self): + """ return base temporary directory. """ + try: + return self._basetemp + except AttributeError: + basetemp = self.config.option.basetemp + if basetemp: + basetemp = py.path.local(basetemp) + if basetemp.check(): + basetemp.remove() + basetemp.mkdir() + else: + temproot = py.path.local.get_temproot() + user = get_user() + if user: + # use a sub-directory in the temproot to speed-up + # make_numbered_dir() call + rootdir = temproot.join("pytest-of-%s" % user) + else: + rootdir = temproot + rootdir.ensure(dir=1) + basetemp = py.path.local.make_numbered_dir( + prefix="pytest-", rootdir=rootdir + ) + self._basetemp = t = basetemp.realpath() + self.trace("new basetemp", t) + return t + + def finish(self): + self.trace("finish") + + +def get_user(): + """Return the current user name, or None if getuser() does not work + in the current environment (see #1010). + """ + import getpass + + try: + return getpass.getuser() + except (ImportError, KeyError): + return None + + +# backward compatibility +TempdirHandler = TempdirFactory + + +def pytest_configure(config): + """Create a TempdirFactory and attach it to the config object. + + This is to comply with existing plugins which expect the handler to be + available at pytest_configure time, but ideally should be moved entirely + to the tmpdir_factory session fixture. + """ + mp = MonkeyPatch() + t = TempdirFactory(config) + config._cleanup.extend([mp.undo, t.finish]) + mp.setattr(config, "_tmpdirhandler", t, raising=False) + mp.setattr(pytest, "ensuretemp", t.ensuretemp, raising=False) + + +@pytest.fixture(scope="session") +def tmpdir_factory(request): + """Return a TempdirFactory instance for the test session. + """ + return request.config._tmpdirhandler + + +@pytest.fixture +def tmpdir(request, tmpdir_factory): + """Return a temporary directory path object + which is unique to each test function invocation, + created as a sub directory of the base temporary + directory. The returned object is a `py.path.local`_ + path object. + + .. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html + """ + name = request.node.name + name = re.sub(r"[\W]", "_", name) + MAXVAL = 30 + if len(name) > MAXVAL: + name = name[:MAXVAL] + x = tmpdir_factory.mktemp(name, numbered=True) + return x diff --git a/Lib/site-packages/_pytest/unittest.py b/Lib/site-packages/_pytest/unittest.py new file mode 100644 index 0000000..d6e7cb2 --- /dev/null +++ b/Lib/site-packages/_pytest/unittest.py @@ -0,0 +1,251 @@ +""" discovery and running of std-library "unittest" style tests. """ +from __future__ import absolute_import, division, print_function + +import sys +import traceback + +# for transferring markers +import _pytest._code +from _pytest.config import hookimpl +from _pytest.outcomes import fail, skip, xfail +from _pytest.python import transfer_markers, Class, Module, Function + + +def pytest_pycollect_makeitem(collector, name, obj): + # has unittest been imported and is obj a subclass of its TestCase? + try: + if not issubclass(obj, sys.modules["unittest"].TestCase): + return + except Exception: + return + # yes, so let's collect it + return UnitTestCase(name, parent=collector) + + +class UnitTestCase(Class): + # marker for fixturemanger.getfixtureinfo() + # to declare that our children do not support funcargs + nofuncargs = True + + def setup(self): + cls = self.obj + if getattr(cls, "__unittest_skip__", False): + return # skipped + setup = getattr(cls, "setUpClass", None) + if setup is not None: + setup() + teardown = getattr(cls, "tearDownClass", None) + if teardown is not None: + self.addfinalizer(teardown) + super(UnitTestCase, self).setup() + + def collect(self): + from unittest import TestLoader + + cls = self.obj + if not getattr(cls, "__test__", True): + return + self.session._fixturemanager.parsefactories(self, unittest=True) + loader = TestLoader() + module = self.getparent(Module).obj + foundsomething = False + for name in loader.getTestCaseNames(self.obj): + x = getattr(self.obj, name) + if not getattr(x, "__test__", True): + continue + funcobj = getattr(x, "im_func", x) + transfer_markers(funcobj, cls, module) + yield TestCaseFunction(name, parent=self, callobj=funcobj) + foundsomething = True + + if not foundsomething: + runtest = getattr(self.obj, "runTest", None) + if runtest is not None: + ut = sys.modules.get("twisted.trial.unittest", None) + if ut is None or runtest != ut.TestCase.runTest: + yield TestCaseFunction("runTest", parent=self) + + +class TestCaseFunction(Function): + nofuncargs = True + _excinfo = None + + def setup(self): + self._testcase = self.parent.obj(self.name) + self._fix_unittest_skip_decorator() + self._obj = getattr(self._testcase, self.name) + if hasattr(self._testcase, "setup_method"): + self._testcase.setup_method(self._obj) + if hasattr(self, "_request"): + self._request._fillfixtures() + + def _fix_unittest_skip_decorator(self): + """ + The @unittest.skip decorator calls functools.wraps(self._testcase) + The call to functools.wraps() fails unless self._testcase + has a __name__ attribute. This is usually automatically supplied + if the test is a function or method, but we need to add manually + here. + + See issue #1169 + """ + if sys.version_info[0] == 2: + setattr(self._testcase, "__name__", self.name) + + def teardown(self): + if hasattr(self._testcase, "teardown_method"): + self._testcase.teardown_method(self._obj) + # Allow garbage collection on TestCase instance attributes. + self._testcase = None + self._obj = None + + def startTest(self, testcase): + pass + + def _addexcinfo(self, rawexcinfo): + # unwrap potential exception info (see twisted trial support below) + rawexcinfo = getattr(rawexcinfo, "_rawexcinfo", rawexcinfo) + try: + excinfo = _pytest._code.ExceptionInfo(rawexcinfo) + except TypeError: + try: + try: + values = traceback.format_exception(*rawexcinfo) + values.insert( + 0, + "NOTE: Incompatible Exception Representation, " + "displaying natively:\n\n", + ) + fail("".join(values), pytrace=False) + except (fail.Exception, KeyboardInterrupt): + raise + except: # noqa + fail( + "ERROR: Unknown Incompatible Exception " + "representation:\n%r" % (rawexcinfo,), + pytrace=False, + ) + except KeyboardInterrupt: + raise + except fail.Exception: + excinfo = _pytest._code.ExceptionInfo() + self.__dict__.setdefault("_excinfo", []).append(excinfo) + + def addError(self, testcase, rawexcinfo): + self._addexcinfo(rawexcinfo) + + def addFailure(self, testcase, rawexcinfo): + self._addexcinfo(rawexcinfo) + + def addSkip(self, testcase, reason): + try: + skip(reason) + except skip.Exception: + self._skipped_by_mark = True + self._addexcinfo(sys.exc_info()) + + def addExpectedFailure(self, testcase, rawexcinfo, reason=""): + try: + xfail(str(reason)) + except xfail.Exception: + self._addexcinfo(sys.exc_info()) + + def addUnexpectedSuccess(self, testcase, reason=""): + self._unexpectedsuccess = reason + + def addSuccess(self, testcase): + pass + + def stopTest(self, testcase): + pass + + def _handle_skip(self): + # implements the skipping machinery (see #2137) + # analog to pythons Lib/unittest/case.py:run + testMethod = getattr(self._testcase, self._testcase._testMethodName) + if getattr(self._testcase.__class__, "__unittest_skip__", False) or getattr( + testMethod, "__unittest_skip__", False + ): + # If the class or method was skipped. + skip_why = getattr( + self._testcase.__class__, "__unittest_skip_why__", "" + ) or getattr(testMethod, "__unittest_skip_why__", "") + try: # PY3, unittest2 on PY2 + self._testcase._addSkip(self, self._testcase, skip_why) + except TypeError: # PY2 + if sys.version_info[0] != 2: + raise + self._testcase._addSkip(self, skip_why) + return True + return False + + def runtest(self): + if self.config.pluginmanager.get_plugin("pdbinvoke") is None: + self._testcase(result=self) + else: + # disables tearDown and cleanups for post mortem debugging (see #1890) + if self._handle_skip(): + return + self._testcase.debug() + + def _prunetraceback(self, excinfo): + Function._prunetraceback(self, excinfo) + traceback = excinfo.traceback.filter( + lambda x: not x.frame.f_globals.get("__unittest") + ) + if traceback: + excinfo.traceback = traceback + + +@hookimpl(tryfirst=True) +def pytest_runtest_makereport(item, call): + if isinstance(item, TestCaseFunction): + if item._excinfo: + call.excinfo = item._excinfo.pop(0) + try: + del call.result + except AttributeError: + pass + + +# twisted trial support + + +@hookimpl(hookwrapper=True) +def pytest_runtest_protocol(item): + if isinstance(item, TestCaseFunction) and "twisted.trial.unittest" in sys.modules: + ut = sys.modules["twisted.python.failure"] + Failure__init__ = ut.Failure.__init__ + check_testcase_implements_trial_reporter() + + def excstore( + self, exc_value=None, exc_type=None, exc_tb=None, captureVars=None + ): + if exc_value is None: + self._rawexcinfo = sys.exc_info() + else: + if exc_type is None: + exc_type = type(exc_value) + self._rawexcinfo = (exc_type, exc_value, exc_tb) + try: + Failure__init__( + self, exc_value, exc_type, exc_tb, captureVars=captureVars + ) + except TypeError: + Failure__init__(self, exc_value, exc_type, exc_tb) + + ut.Failure.__init__ = excstore + yield + ut.Failure.__init__ = Failure__init__ + else: + yield + + +def check_testcase_implements_trial_reporter(done=[]): + if done: + return + from zope.interface import classImplements + from twisted.trial.itrial import IReporter + + classImplements(TestCaseFunction, IReporter) + done.append(1) diff --git a/Lib/site-packages/_pytest/warnings.py b/Lib/site-packages/_pytest/warnings.py new file mode 100644 index 0000000..abd0480 --- /dev/null +++ b/Lib/site-packages/_pytest/warnings.py @@ -0,0 +1,111 @@ +from __future__ import absolute_import, division, print_function + +import warnings +from contextlib import contextmanager + +import pytest + +from _pytest import compat + + +def _setoption(wmod, arg): + """ + Copy of the warning._setoption function but does not escape arguments. + """ + parts = arg.split(":") + if len(parts) > 5: + raise wmod._OptionError("too many fields (max 5): %r" % (arg,)) + while len(parts) < 5: + parts.append("") + action, message, category, module, lineno = [s.strip() for s in parts] + action = wmod._getaction(action) + category = wmod._getcategory(category) + if lineno: + try: + lineno = int(lineno) + if lineno < 0: + raise ValueError + except (ValueError, OverflowError): + raise wmod._OptionError("invalid lineno %r" % (lineno,)) + else: + lineno = 0 + wmod.filterwarnings(action, message, category, module, lineno) + + +def pytest_addoption(parser): + group = parser.getgroup("pytest-warnings") + group.addoption( + "-W", + "--pythonwarnings", + action="append", + help="set which warnings to report, see -W option of python itself.", + ) + parser.addini( + "filterwarnings", + type="linelist", + help="Each line specifies a pattern for " + "warnings.filterwarnings. " + "Processed after -W and --pythonwarnings.", + ) + + +@contextmanager +def catch_warnings_for_item(item): + """ + catches the warnings generated during setup/call/teardown execution + of the given item and after it is done posts them as warnings to this + item. + """ + args = item.config.getoption("pythonwarnings") or [] + inifilters = item.config.getini("filterwarnings") + with warnings.catch_warnings(record=True) as log: + for arg in args: + warnings._setoption(arg) + + for arg in inifilters: + _setoption(warnings, arg) + + for mark in item.iter_markers(name="filterwarnings"): + for arg in mark.args: + warnings._setoption(arg) + + yield + + for warning in log: + warn_msg = warning.message + unicode_warning = False + + if compat._PY2 and any( + isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args + ): + new_args = [] + for m in warn_msg.args: + new_args.append( + compat.ascii_escaped(m) + if isinstance(m, compat.UNICODE_TYPES) + else m + ) + unicode_warning = list(warn_msg.args) != new_args + warn_msg.args = new_args + + msg = warnings.formatwarning( + warn_msg, + warning.category, + warning.filename, + warning.lineno, + warning.line, + ) + item.warn("unused", msg) + + if unicode_warning: + warnings.warn( + "Warning is using unicode non convertible to ascii, " + "converting to a safe representation:\n %s" % msg, + UnicodeWarning, + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_runtest_protocol(item): + with catch_warnings_for_item(item): + yield diff --git a/Lib/site-packages/atomicwrites-1.1.5.dist-info/DESCRIPTION.rst b/Lib/site-packages/atomicwrites-1.1.5.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..ab0e079 --- /dev/null +++ b/Lib/site-packages/atomicwrites-1.1.5.dist-info/DESCRIPTION.rst @@ -0,0 +1,104 @@ +=================== +python-atomicwrites +=================== + +.. image:: https://travis-ci.org/untitaker/python-atomicwrites.svg?branch=master + :target: https://travis-ci.org/untitaker/python-atomicwrites + +.. image:: https://ci.appveyor.com/api/projects/status/vadc4le3c27to59x/branch/master?svg=true + :target: https://ci.appveyor.com/project/untitaker/python-atomicwrites/branch/master + +Atomic file writes. + +.. code-block:: python + + from atomicwrites import atomic_write + + with atomic_write('foo.txt', overwrite=True) as f: + f.write('Hello world.') + # "foo.txt" doesn't exist yet. + + # Now it does. + + +Features that distinguish it from other similar libraries (see `Alternatives and Credit`_): + +- Race-free assertion that the target file doesn't yet exist. This can be + controlled with the ``overwrite`` parameter. + +- Windows support, although not well-tested. The MSDN resources are not very + explicit about which operations are atomic. + +- Simple high-level API that wraps a very flexible class-based API. + +- Consistent error handling across platforms. + + +How it works +============ + +It uses a temporary file in the same directory as the given path. This ensures +that the temporary file resides on the same filesystem. + +The temporary file will then be atomically moved to the target location: On +POSIX, it will use ``rename`` if files should be overwritten, otherwise a +combination of ``link`` and ``unlink``. On Windows, it uses MoveFileEx_ through +stdlib's ``ctypes`` with the appropriate flags. + +Note that with ``link`` and ``unlink``, there's a timewindow where the file +might be available under two entries in the filesystem: The name of the +temporary file, and the name of the target file. + +Also note that the permissions of the target file may change this way. In some +situations a ``chmod`` can be issued without any concurrency problems, but +since that is not always the case, this library doesn't do it by itself. + +.. _MoveFileEx: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365240%28v=vs.85%29.aspx + +fsync +----- + +On POSIX, ``fsync`` is invoked on the temporary file after it is written (to +flush file content and metadata), and on the parent directory after the file is +moved (to flush filename). + +``fsync`` does not take care of disks' internal buffers, but there don't seem +to be any standard POSIX APIs for that. On OS X, ``fcntl`` is used with +``F_FULLFSYNC`` instead of ``fsync`` for that reason. + +On Windows, `_commit `_ +is used, but there are no guarantees about disk internal buffers. + +Alternatives and Credit +======================= + +Atomicwrites is directly inspired by the following libraries (and shares a +minimal amount of code): + +- The Trac project's `utility functions + `_, + also used in `Werkzeug `_ and + `mitsuhiko/python-atomicfile + `_. The idea to use + ``ctypes`` instead of ``PyWin32`` originated there. + +- `abarnert/fatomic `_. Windows support + (based on ``PyWin32``) was originally taken from there. + +Other alternatives to atomicwrites include: + +- `sashka/atomicfile `_. Originally I + considered using that, but at the time it was lacking a lot of features I + needed (Windows support, overwrite-parameter, overriding behavior through + subclassing). + +- The `Boltons library collection `_ + features a class for atomic file writes, which seems to have a very similar + ``overwrite`` parameter. It is lacking Windows support though. + +License +======= + +Licensed under the MIT, see ``LICENSE``. + + diff --git a/Lib/site-packages/atomicwrites-1.1.5.dist-info/INSTALLER b/Lib/site-packages/atomicwrites-1.1.5.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/atomicwrites-1.1.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/atomicwrites-1.1.5.dist-info/METADATA b/Lib/site-packages/atomicwrites-1.1.5.dist-info/METADATA new file mode 100644 index 0000000..b729095 --- /dev/null +++ b/Lib/site-packages/atomicwrites-1.1.5.dist-info/METADATA @@ -0,0 +1,114 @@ +Metadata-Version: 2.0 +Name: atomicwrites +Version: 1.1.5 +Summary: Atomic file writes. +Home-page: https://github.com/untitaker/python-atomicwrites +Author: Markus Unterwaditzer +Author-email: markus@unterwaditzer.net +License: MIT +Platform: UNKNOWN + +=================== +python-atomicwrites +=================== + +.. image:: https://travis-ci.org/untitaker/python-atomicwrites.svg?branch=master + :target: https://travis-ci.org/untitaker/python-atomicwrites + +.. image:: https://ci.appveyor.com/api/projects/status/vadc4le3c27to59x/branch/master?svg=true + :target: https://ci.appveyor.com/project/untitaker/python-atomicwrites/branch/master + +Atomic file writes. + +.. code-block:: python + + from atomicwrites import atomic_write + + with atomic_write('foo.txt', overwrite=True) as f: + f.write('Hello world.') + # "foo.txt" doesn't exist yet. + + # Now it does. + + +Features that distinguish it from other similar libraries (see `Alternatives and Credit`_): + +- Race-free assertion that the target file doesn't yet exist. This can be + controlled with the ``overwrite`` parameter. + +- Windows support, although not well-tested. The MSDN resources are not very + explicit about which operations are atomic. + +- Simple high-level API that wraps a very flexible class-based API. + +- Consistent error handling across platforms. + + +How it works +============ + +It uses a temporary file in the same directory as the given path. This ensures +that the temporary file resides on the same filesystem. + +The temporary file will then be atomically moved to the target location: On +POSIX, it will use ``rename`` if files should be overwritten, otherwise a +combination of ``link`` and ``unlink``. On Windows, it uses MoveFileEx_ through +stdlib's ``ctypes`` with the appropriate flags. + +Note that with ``link`` and ``unlink``, there's a timewindow where the file +might be available under two entries in the filesystem: The name of the +temporary file, and the name of the target file. + +Also note that the permissions of the target file may change this way. In some +situations a ``chmod`` can be issued without any concurrency problems, but +since that is not always the case, this library doesn't do it by itself. + +.. _MoveFileEx: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365240%28v=vs.85%29.aspx + +fsync +----- + +On POSIX, ``fsync`` is invoked on the temporary file after it is written (to +flush file content and metadata), and on the parent directory after the file is +moved (to flush filename). + +``fsync`` does not take care of disks' internal buffers, but there don't seem +to be any standard POSIX APIs for that. On OS X, ``fcntl`` is used with +``F_FULLFSYNC`` instead of ``fsync`` for that reason. + +On Windows, `_commit `_ +is used, but there are no guarantees about disk internal buffers. + +Alternatives and Credit +======================= + +Atomicwrites is directly inspired by the following libraries (and shares a +minimal amount of code): + +- The Trac project's `utility functions + `_, + also used in `Werkzeug `_ and + `mitsuhiko/python-atomicfile + `_. The idea to use + ``ctypes`` instead of ``PyWin32`` originated there. + +- `abarnert/fatomic `_. Windows support + (based on ``PyWin32``) was originally taken from there. + +Other alternatives to atomicwrites include: + +- `sashka/atomicfile `_. Originally I + considered using that, but at the time it was lacking a lot of features I + needed (Windows support, overwrite-parameter, overriding behavior through + subclassing). + +- The `Boltons library collection `_ + features a class for atomic file writes, which seems to have a very similar + ``overwrite`` parameter. It is lacking Windows support though. + +License +======= + +Licensed under the MIT, see ``LICENSE``. + + diff --git a/Lib/site-packages/atomicwrites-1.1.5.dist-info/RECORD b/Lib/site-packages/atomicwrites-1.1.5.dist-info/RECORD new file mode 100644 index 0000000..714ccb0 --- /dev/null +++ b/Lib/site-packages/atomicwrites-1.1.5.dist-info/RECORD @@ -0,0 +1,9 @@ +atomicwrites-1.1.5.dist-info/DESCRIPTION.rst,sha256=Ia6eAs4RhHYEFnlTyHiv-2KRbqc3nsvs9h1qZjswZpI,3793 +atomicwrites-1.1.5.dist-info/metadata.json,sha256=LhGqv-JWg00kC8dQy7ViPGi1WhkZ7kWtDSw9Z04z05w,431 +atomicwrites-1.1.5.dist-info/RECORD,, +atomicwrites-1.1.5.dist-info/top_level.txt,sha256=ks64zKVUkrl2ZrrP046CsytXlSGf8gLG-IcoXpNyeoc,13 +atomicwrites-1.1.5.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 +atomicwrites-1.1.5.dist-info/METADATA,sha256=l9iz0IXOVeIS3sa_DpBG4HwePk0kKPqWhOGj_pxZqaM,4038 +atomicwrites/__init__.py,sha256=qqGl8x1hJTc7dqug1kO-jMsjQe11SSWZZIdUp_IQx8A,5965 +atomicwrites-1.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +atomicwrites/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/atomicwrites-1.1.5.dist-info/WHEEL b/Lib/site-packages/atomicwrites-1.1.5.dist-info/WHEEL new file mode 100644 index 0000000..9dff69d --- /dev/null +++ b/Lib/site-packages/atomicwrites-1.1.5.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.24.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/atomicwrites-1.1.5.dist-info/metadata.json b/Lib/site-packages/atomicwrites-1.1.5.dist-info/metadata.json new file mode 100644 index 0000000..326eed9 --- /dev/null +++ b/Lib/site-packages/atomicwrites-1.1.5.dist-info/metadata.json @@ -0,0 +1 @@ +{"metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "license": "MIT", "name": "atomicwrites", "extensions": {"python.details": {"contacts": [{"role": "author", "email": "markus@unterwaditzer.net", "name": "Markus Unterwaditzer"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/untitaker/python-atomicwrites"}}}, "version": "1.1.5", "summary": "Atomic file writes."} \ No newline at end of file diff --git a/Lib/site-packages/atomicwrites-1.1.5.dist-info/top_level.txt b/Lib/site-packages/atomicwrites-1.1.5.dist-info/top_level.txt new file mode 100644 index 0000000..5fa5a87 --- /dev/null +++ b/Lib/site-packages/atomicwrites-1.1.5.dist-info/top_level.txt @@ -0,0 +1 @@ +atomicwrites diff --git a/Lib/site-packages/atomicwrites/__init__.py b/Lib/site-packages/atomicwrites/__init__.py new file mode 100644 index 0000000..a182c07 --- /dev/null +++ b/Lib/site-packages/atomicwrites/__init__.py @@ -0,0 +1,201 @@ +import contextlib +import os +import sys +import tempfile + +try: + import fcntl +except ImportError: + fcntl = None + +__version__ = '1.1.5' + + +PY2 = sys.version_info[0] == 2 + +text_type = unicode if PY2 else str # noqa + + +def _path_to_unicode(x): + if not isinstance(x, text_type): + return x.decode(sys.getfilesystemencoding()) + return x + + +_proper_fsync = os.fsync + + +if sys.platform != 'win32': + if hasattr(fcntl, 'F_FULLFSYNC'): + def _proper_fsync(fd): + # https://lists.apple.com/archives/darwin-dev/2005/Feb/msg00072.html + # https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/fsync.2.html + # https://github.com/untitaker/python-atomicwrites/issues/6 + fcntl.fcntl(fd, fcntl.F_FULLFSYNC) + + def _sync_directory(directory): + # Ensure that filenames are written to disk + fd = os.open(directory, 0) + try: + _proper_fsync(fd) + finally: + os.close(fd) + + def _replace_atomic(src, dst): + os.rename(src, dst) + _sync_directory(os.path.normpath(os.path.dirname(dst))) + + def _move_atomic(src, dst): + os.link(src, dst) + os.unlink(src) + + src_dir = os.path.normpath(os.path.dirname(src)) + dst_dir = os.path.normpath(os.path.dirname(dst)) + _sync_directory(dst_dir) + if src_dir != dst_dir: + _sync_directory(src_dir) +else: + from ctypes import windll, WinError + + _MOVEFILE_REPLACE_EXISTING = 0x1 + _MOVEFILE_WRITE_THROUGH = 0x8 + _windows_default_flags = _MOVEFILE_WRITE_THROUGH + + def _handle_errors(rv): + if not rv: + raise WinError() + + def _replace_atomic(src, dst): + _handle_errors(windll.kernel32.MoveFileExW( + _path_to_unicode(src), _path_to_unicode(dst), + _windows_default_flags | _MOVEFILE_REPLACE_EXISTING + )) + + def _move_atomic(src, dst): + _handle_errors(windll.kernel32.MoveFileExW( + _path_to_unicode(src), _path_to_unicode(dst), + _windows_default_flags + )) + + +def replace_atomic(src, dst): + ''' + Move ``src`` to ``dst``. If ``dst`` exists, it will be silently + overwritten. + + Both paths must reside on the same filesystem for the operation to be + atomic. + ''' + return _replace_atomic(src, dst) + + +def move_atomic(src, dst): + ''' + Move ``src`` to ``dst``. There might a timewindow where both filesystem + entries exist. If ``dst`` already exists, :py:exc:`FileExistsError` will be + raised. + + Both paths must reside on the same filesystem for the operation to be + atomic. + ''' + return _move_atomic(src, dst) + + +class AtomicWriter(object): + ''' + A helper class for performing atomic writes. Usage:: + + with AtomicWriter(path).open() as f: + f.write(...) + + :param path: The destination filepath. May or may not exist. + :param mode: The filemode for the temporary file. + :param overwrite: If set to false, an error is raised if ``path`` exists. + Errors are only raised after the file has been written to. Either way, + the operation is atomic. + + If you need further control over the exact behavior, you are encouraged to + subclass. + ''' + + def __init__(self, path, mode='w', overwrite=False): + if 'a' in mode: + raise ValueError( + 'Appending to an existing file is not supported, because that ' + 'would involve an expensive `copy`-operation to a temporary ' + 'file. Open the file in normal `w`-mode and copy explicitly ' + 'if that\'s what you\'re after.' + ) + if 'x' in mode: + raise ValueError('Use the `overwrite`-parameter instead.') + if 'w' not in mode: + raise ValueError('AtomicWriters can only be written to.') + + self._path = path + self._mode = mode + self._overwrite = overwrite + + def open(self): + ''' + Open the temporary file. + ''' + return self._open(self.get_fileobject) + + @contextlib.contextmanager + def _open(self, get_fileobject): + f = None # make sure f exists even if get_fileobject() fails + try: + success = False + with get_fileobject() as f: + yield f + self.sync(f) + self.commit(f) + success = True + finally: + if not success: + try: + self.rollback(f) + except Exception: + pass + + def get_fileobject(self, dir=None, **kwargs): + '''Return the temporary file to use.''' + if dir is None: + dir = os.path.normpath(os.path.dirname(self._path)) + return tempfile.NamedTemporaryFile(mode=self._mode, dir=dir, + delete=False, **kwargs) + + def sync(self, f): + '''responsible for clearing as many file caches as possible before + commit''' + f.flush() + _proper_fsync(f.fileno()) + + def commit(self, f): + '''Move the temporary file to the target location.''' + if self._overwrite: + replace_atomic(f.name, self._path) + else: + move_atomic(f.name, self._path) + + def rollback(self, f): + '''Clean up all temporary resources.''' + os.unlink(f.name) + + +def atomic_write(path, writer_cls=AtomicWriter, **cls_kwargs): + ''' + Simple atomic writes. This wraps :py:class:`AtomicWriter`:: + + with atomic_write(path) as f: + f.write(...) + + :param path: The target path to write to. + :param writer_cls: The writer class to use. This parameter is useful if you + subclassed :py:class:`AtomicWriter` to change some behavior and want to + use that new subclass. + + Additional keyword arguments are passed to the writer class. See + :py:class:`AtomicWriter`. + ''' + return writer_cls(path, **cls_kwargs).open() diff --git a/Lib/site-packages/atomicwrites/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/atomicwrites/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0db8dfc6a5f3f9ef952d0f61fb53734630c4926 GIT binary patch literal 6099 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" + +__author__ = "Hynek Schlawack" +__email__ = "hs@ox.cx" + +__license__ = "MIT" +__copyright__ = "Copyright (c) 2015 Hynek Schlawack" + + +s = attributes = attrs +ib = attr = attrib +dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) + +__all__ = [ + "Attribute", + "Factory", + "NOTHING", + "asdict", + "assoc", + "astuple", + "attr", + "attrib", + "attributes", + "attrs", + "converters", + "evolve", + "exceptions", + "fields", + "fields_dict", + "filters", + "get_run_validators", + "has", + "ib", + "make_class", + "s", + "set_run_validators", + "validate", + "validators", +] diff --git a/Lib/site-packages/attr/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/attr/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8221a08968c7256ae12aea9ddaf00999939bcd00 GIT binary patch literal 1396 zcmb7DTW{Mo6qe+RY{!lr$Byk>mGl<1iIWuA))ht3Hr7uW)?qAIVU zTDC5-MP5gB-ark$gqC;{HTg1H&h~uP;%(ICD`m-kSQucB4HhSvBxTIU;R z!<;RlO(>%+sGtBA&^8I6+HuHs$AMbMK|8RBZb2R0h6cI=OXx1?zr8luDY6^lShynI>#XbZ!*Mu&n*lH)kiWPQTOT=Sm5BZfI!#+bA~iZj6siXMC7h>f!|@ z45VI|&p7j6;n5|*F*9Lw>0?%8Ry=ytKk6Tf6~l72c5HWv41S_&luT6cBB6|kltqfn z+9RdX#|H;jS6BTkOg|CBgP9jR`QSdC)lY85ry=MilHRLuHIe#T>-YnD<0+dG<*{lwie z%K?)0Vc0G1g^_6;;e6t?L*Ak+GmzpBjaa@kG$M07+~F!_ky`ln5gm zOTr_{jA%SE8k4cKZfe-@_;_=s6oHMqX<^I4h5=MIO&`ts%EXA6@$rWv4(+~$4{wei z4}Op)$H6zJKmHsXeKmNVrZ0`n;QJ(w*x-!tbdb_?pN^$6=KH@sfxr$XmuW3)VyCW9bubWi8B+oQ zc(Ig1jrQ~LX=GSCp z&lT({6ZXF4*QN8O@sz%#D*F|+C!79kGLPBSxYe8U=Qxvd{;aI4 zf1s}x&-WJm1?=jI`fKJdiiUql%!nr1OTS@aRhCpW~xDfJ?# zFO}3{sT>u{;xedKWIg|#-CmX|UAUrq(9OGPQnWJFO?1%dCy~bY<~s{h3TJDuHE3J!Y<#?{(jvT=d7^|= zQhe5pG(P8lr=<#aWBElc74=0ByLsqMhp~>5&!f`pm}#!9J-cI_5HP;kc8Uf7B)JZg zNEVJBWU{DGo%{9mILz~BXk(koK7IV1sW~k4-RAl)cWA$SXJhk^+ur*h?L5q~&q5vU z{2`6Pc;}hyWjk3nTQw`k@#@QuMXK)J`(!878ndY038J)@g?cR;6t!+1(fU^jDsj%Z zf?hGzL^Z|`4H|}AG>+LD_Lh~5@S@&@Bv5)e@N!|0mK8Ct7E%2OV_kAgd-|=S436R@UEV!R1FG33dMc5R42aT*jTk-j{>IJ_zFp!4@+?kV{Q#1i>w!Ch8jvyqo<@gj(JN^47z%-V(m0E@P*H2a~X?<($mh9F0TsmOIs3bJuN z=hq{MSH=*Z(~OCgoYy){B0nrR#il(tuN5Q*E9AcH&7;{-?{(`t-fmlkqhzKE2i6|` z8#Q!;fM|l?_al&&#~__iPyocgSzt~Q_GAzgjUecyq90Sc83Zr;VSGALgBhj~rc#hn zH>mmnRX?Q4qw2?0{e-HYQ$>+-q%uKh34K3BF`*TB0`Q8Ydj6S>Brn8=H1 zcEVoqW4_1VSjX%w=j@o5(a$zB)z3g=puwM9Lc6e)%qK7ut)A2&2{15W;R)z+$}JeL z@+Mce(HcUa9AXH8a=tQ$ILjU^HG@7ArEwZ9YM*m$7^W!x1&XvWqbMu6{! z^a|-Z!nt8)a%oZ=|9t7OHHUc*VbbgkvYumh!ruN-7%5-ae5$yha3-a%R5W+JOq4CBld^8U3mCG z8RQkM2+b_2k;%ls|NH2f;J=tHlgOYX3PF(*+stvfqBs%J2R#I?f?`gZG)%+PU~(2E zHs9FDjU5239DOrPF`i4$Bp`>OO3?DQ2KohFA9%Ym3j4YA4y6|=X_AN#L?G{YVKVTd zG>Meda<~#Ya{00^kzM9QWYP|)HIfofzmQ%e<9K9;yXR@nQTK5dDGBIG2G>0AY1)%s zM~1o&wf5rfzVvo!bL25n-D-OfW*A{3Gb;#;ss({}*u@^S@nNd=@ugpQd7SFpGXyeU zQzRY8yMcp<_G5V<<4xo}F0l^)dErp2Xno#Kbhjs;m)+!zLWNOl|8Vkb>U;fM2Q+IB zOXsB7tm1IXvbg#L?Xk0=<2GkQ$0tZdt^c#L*fjjXsZexRA5%49=fuCzj6u&h-6R@+};8@deYpYf_%6yCxlVV zgA&@8=FroC=)R`4$qX4kdaoDmOImA;V(orRH>do;+T=*PfotIQ*0!l3coxs}YFdpp?nEcAFNdMd98rGlK_YulYSxOJLvp lYzV==3~@BMV>`U*xDG^BIt@_k%;&}3WM-4yKHqteKEY-YIvFLGt?d zQIE3O+lRD$R(IC1g=7n@)pV9dK7r91>v&U2ABCvjnXg-UW{fs|_pj+v>?y!}L*^DV z|8sWwEPrREvH98T{RejcN&cd3UvkIuH@f61pUb+<+p0b2D=2mF=}>6%;PKO(I|sLd z&5Keu%W5@k*Jc2qJAs-Z7!)NqCS}-NOQ5f(E`p6iKoZ_O?8kd6U1ysA;Hl3}u?b(P zAL51?hgc}R2WrEYLeVUZeNw=a1HLQ@6QU+Op$R?sQBiQEAl~DJ{(FEMpn)h8kbV5T U)}mALD2!oaFn4H7A{r;Z0LS0Cx&QzG literal 0 HcmV?d00001 diff --git a/Lib/site-packages/attr/__pycache__/_funcs.cpython-37.pyc b/Lib/site-packages/attr/__pycache__/_funcs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6db97e0645bdca3e62c6b7394e3252a99f504cd GIT binary patch literal 6799 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/attr/__pycache__/converters.cpython-37.pyc b/Lib/site-packages/attr/__pycache__/converters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eb3837707eb5ee50101c90dad023796b3217329 GIT binary patch literal 836 zcmYjP&u`N(6tG3v%=VwmyQu&;&8e zJb_DZ;+6iyFM~;d5%XDagC;%JJ4b{5>S1&y%TiY2k~Esn8$oheEx9sW={WigKxp8% z_vlPZ(HNc;Wi6FyLsl#cUC64vTdSfn*}SQ819^_^2rMhc|G)Kpc=?Xz*b2G{zu_wk zQ)^($&<`c}f(()YZq)4HgKMWqd#b@=re zlj`x4=c%<P2DN%10TX64)E%zYl%;UrO~HxSJ@6ZfdfzNz?j;# z!73i$bs>cJHteQsrUMA*&R$R1TRtB2+np?9GS9L$%HWQfM)53D)-h!-m$Ln?*8$%O TYwVL!vPSSz+v~6c@6i7TP6*!7 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/attr/__pycache__/exceptions.cpython-37.pyc b/Lib/site-packages/attr/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d58bf99442fb0ab4e3fffd8262bec83037f52f96 GIT binary patch literal 1868 zcmb_dTaVjB6t-h0ak9yFQ7fdv%kTt2+Q1g63lX4(UZ4_+RCoD;EGM%L7j1?Q4bYk5&x&WKeoLJGyiQgAlx`aK?6QV87B z5WD8EU`@}3(nKxEd@gChnRR8(&3sN47sMGMSAL;^DZ=qZQgCDFiu>)TWW=~dmQ&-G zj`&a6Xg;=9iv@_}zka?sdN?HKT%%N!G0sLKa&mikGW^(Yba_3a@_kDTw@9IWeKKfO zNt)tkrD@eoQy}AVeD0;`nWOn;rk$otWiT8SW>v*hugq_O?t#=k{PpPWX!g{=*|YnT zXV1yW>1nQ}Qp zxt0P9px*UbGBAr;@0bI^gqj~96P8N9$%9)P4<>_HBOTqwkYMOw*a=xb^>OSF!dq~g z285*P@s+sW0JdZ41-OgZQ$dv*-(;@=$D1#a zMSLZ)Z{Oof>T)~IHK*+2F}F3{UpI7FJ-w%hWl$Gi&2A_b9}FM^u-=6EN0Dm|FZjLo z70Y<0G_`NC{&ZJpZ8V`6~Emq0rbzl4v S|78sRb>4`M`bP=;I)4MSuh*jh literal 0 HcmV?d00001 diff --git a/Lib/site-packages/attr/__pycache__/filters.cpython-37.pyc b/Lib/site-packages/attr/__pycache__/filters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f9146d48775e84cb2b38d8233b18c0d0c037f7f GIT binary patch literal 1803 zcmbtUOOMn>5bkcz!{eQWg)HQu2>B328YD)614*pa3fPU51KL9#pbU;YUUyG0+kVj9 z26i+YqFo92B~hgOB42ajFK|j#k3BmOB|^edS68*Gx*lIu-`U*s2z=k4mBa@ z_G7@@f~D^Q;bcNMEANIxX`0T&dFBL}+b5eofJW*8Nl`GS(W{!ELxRJp}6n zf8vKbq)zr==`Vm7o9HQ7kbQDOPbkO^XJ_(^K?@xsNGX_j+v2S5aWG9gG0iXFwL@*Ne}=_W~kNY(eiqppO|R;F}(d zsOo{vh}CTTRqZ5F|49@g`Q~6R2!Ga4$nd*^d%yVCzYcGg<$i49@NSXBGWYc_LIFEJjSZu&DtOOmRszkQ)NI z0ILZL@m7CK&{F+S4Wq6!mCP{6On14GbPfB+KE4Iz6)Uy&E&1)VV* zhg0`CT~NTpng3-0z5g&ZLZ;gISJC^`v1gBiGFEZs<5A$>2kM&wq(*ny3xPQ`Q+J{UMCP)5X9A=+=1)DG4XF!5{&*mclZ0oELz z0oH201K7uS`+oq|n0$%%t^xK5$Oofg-H#$(BvDj*5xn5=s){I5*f0v;MTKJuI!Te0 vFw|&YccUymTD}stYb^E(?^_%Cwaj+1f>%=P+IJS;jt<*qLppR^&%N*uF$Jov literal 0 HcmV?d00001 diff --git a/Lib/site-packages/attr/__pycache__/validators.cpython-37.pyc b/Lib/site-packages/attr/__pycache__/validators.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..058eabcd5ea51c77259867d6f6ea9858e72c396e GIT binary patch literal 5662 zcmc&&OLH5?5#ARbgh)!1s7I_Q87mJGj08%lBu)^PELl+!S5mYSD{=*4)nbVm5G(Bi znpubzNnHZxkb|po%hf*mr{pi}HM#hbAK;U}o_!F2Ad{tXD$Cm8V78~Hr>FbdulJp$ zrG|m)x8vk5-3x~CZ~9SO6?E?6Rw){8bPR5CD=?j^BQt;QGFzR|SPv)-aP^J|X#ED9sfu{yNGOxHSbnfC-*U<>0V{)To z343gG96CMhxk4v~|5aYW-mB@V`)LI!9~qC$v88S$ z7B?T;N7iG9Mvm;ql_Q&5pEyTW_IvF7)#Nr-aSq;Zu>AT^kdK+idR`ECyMbW6z*CAP zG26v34WQc_c+nnu1Hrmo*QHInZnxVi)f~LNb{Kh~c(KO9kxFRpVe)(^-jpxc`d*x{ zLmc5q|4as6!hD4#54~P8@&d>-TR0wv6r>JK!>Q;;X+=-lhGQBy+T1e|sbQoG4~Ze>*_7IF6mSv=%)_N#ChX{ep4PEC zJn6cZv4C1cV>pYZWja>fY?uev<{fXVnA4*`rHlUCxb-NpW=M8C$dg!(aFj0Qp2b@USIdf2)TlW#8eec-KtvkB|SFf z97-(h9MXy;FvjE-)B6uRr-Sm|giCb9NzYe;qOL7I>b1LN@N}8q*MaRve&XXS4}_%f zq*D}J>)Q8|0VeLtINHm6tDQW6)XA+iyNO~}a1t4Lg8`VeKArsVNU07;lI;dD zO>vTk_Cy@%5ITcLKf0+)F#RJ4|~ns$z( zrL@M(?Pf*(02}Nya&`Qj=aN7!LluJFrjwz{RT}*^H3YV^heO%_Hg2Vcx$V8Lr*{eC2YB$X-5z~(#8sW)cv{ms4?qzWO@mW^NlWnQN9Ujd7YZ?QKK=C z7B~R|34ecy`xpZkC5@d51Fs^)b;f-27#Oj5_c1aR*@>4pMGTAZaxVgm_<+F0MP7q*}4*-9tZJIv`Rs(XlsxpL)G5gq-W)$7NHcZ z;c-v3{CHDDn}L_Wtj#-JcLq79mA2k3a^yH(GF&Z{XN0H(S8Yc7|B9NWX(e=OqX>Wt z2xXJdNuiWS{cLtF;n5!{@(3rt0qA@$=gsq>vw}4=bP{X>AdM$=xyX$V0HdE8M<&41 z{>(=8f{~`V-89n$>?dPerw5xpbn8Si%sO}&faWEmP5>GLH)3Fk3GlYY6D(|Pt0)X+ zz~*ot8S;VwcDCb40Ao^zMgXpwgb}BcYiMu`bC{S$nt<${K$>}0e?8LB0w*BN41IX$3$!^LBSy}C02ssV{8)lO7LFGIoQ8m$-zSJ2~n_Uf-4p7YcX~Y z=#odvgaAku9H`?tdt>!5ALWG-K%p4GLH-3o_|VEZC|n%TxbhNT^`C=sX(mCayr|w$bd!v+)G!y#9`%ZgK;xqd>wNM39U7VAyv5Cr;Fa&ke<}^1#Bq4GRv%pg? zm#fW!4%KoI&1nEW#4pnZOdDlI=x)Wfe zi^Xp-VRG$Dt8xZ*$EkS{!i@utqu_+j$=+Q7V zQ}q4!m4Gu-^c|np>8m~@%ZR>wO!A#w5l|_Jz#$ANoLle~K-ohK>mm@9q)x||`A()6 zD)Q;{HARcIvw|)k2KWR)ybnal2PToDl%eEAB}L`jjS@ISGzwb}&~$IGR;$pSyX4pv zuT$SqU8ju&!_akQ0ahoJce%kOO)2R~p-i(B{bLTgY539)5xW!}c?i#P7%D9Oi96#k zXSbWHY0Y)P1+(uH{ZTTK_&y;io}^6;1$J6->HVbPO@9W=*!luJ!gT#nC#`1uR~Mi1 z3{532C5bg<;7AClZIfihgk|Lij= (3, 6): + ordered_dict = dict +else: + from collections import OrderedDict + ordered_dict = OrderedDict + + +if PY2: + from UserDict import IterableUserDict + + # We 'bundle' isclass instead of using inspect as importing inspect is + # fairly expensive (order of 10-15 ms for a modern machine in 2016) + def isclass(klass): + return isinstance(klass, (type, types.ClassType)) + + # TYPE is used in exceptions, repr(int) is different on Python 2 and 3. + TYPE = "type" + + def iteritems(d): + return d.iteritems() + + # Python 2 is bereft of a read-only dict proxy, so we make one! + class ReadOnlyDict(IterableUserDict): + """ + Best-effort read-only dict wrapper. + """ + + def __setitem__(self, key, val): + # We gently pretend we're a Python 3 mappingproxy. + raise TypeError("'mappingproxy' object does not support item " + "assignment") + + def update(self, _): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError("'mappingproxy' object has no attribute " + "'update'") + + def __delitem__(self, _): + # We gently pretend we're a Python 3 mappingproxy. + raise TypeError("'mappingproxy' object does not support item " + "deletion") + + def clear(self): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError("'mappingproxy' object has no attribute " + "'clear'") + + def pop(self, key, default=None): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError("'mappingproxy' object has no attribute " + "'pop'") + + def popitem(self): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError("'mappingproxy' object has no attribute " + "'popitem'") + + def setdefault(self, key, default=None): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError("'mappingproxy' object has no attribute " + "'setdefault'") + + def __repr__(self): + # Override to be identical to the Python 3 version. + return "mappingproxy(" + repr(self.data) + ")" + + def metadata_proxy(d): + res = ReadOnlyDict() + res.data.update(d) # We blocked update, so we have to do it like this. + return res + +else: + def isclass(klass): + return isinstance(klass, type) + + TYPE = "class" + + def iteritems(d): + return d.items() + + def metadata_proxy(d): + return types.MappingProxyType(dict(d)) + + +def import_ctypes(): + """ + Moved into a function for testability. + """ + import ctypes + return ctypes + + +if not PY2: + def just_warn(*args, **kw): + """ + We only warn on Python 3 because we are not aware of any concrete + consequences of not setting the cell on Python 2. + """ + warnings.warn( + "Missing ctypes. Some features like bare super() or accessing " + "__class__ will not work with slots classes.", + RuntimeWarning, + stacklevel=2, + ) +else: + def just_warn(*args, **kw): # pragma: nocover + """ + We only warn on Python 3 because we are not aware of any concrete + consequences of not setting the cell on Python 2. + """ + + +def make_set_closure_cell(): + """ + Moved into a function for testability. + """ + if PYPY: # pragma: no cover + def set_closure_cell(cell, value): + cell.__setstate__((value,)) + else: + try: + ctypes = import_ctypes() + + set_closure_cell = ctypes.pythonapi.PyCell_Set + set_closure_cell.argtypes = (ctypes.py_object, ctypes.py_object) + set_closure_cell.restype = ctypes.c_int + except Exception: + # We try best effort to set the cell, but sometimes it's not + # possible. For example on Jython or on GAE. + set_closure_cell = just_warn + return set_closure_cell + + +set_closure_cell = make_set_closure_cell() diff --git a/Lib/site-packages/attr/_config.py b/Lib/site-packages/attr/_config.py new file mode 100644 index 0000000..8ec9209 --- /dev/null +++ b/Lib/site-packages/attr/_config.py @@ -0,0 +1,23 @@ +from __future__ import absolute_import, division, print_function + + +__all__ = ["set_run_validators", "get_run_validators"] + +_run_validators = True + + +def set_run_validators(run): + """ + Set whether or not validators are run. By default, they are run. + """ + if not isinstance(run, bool): + raise TypeError("'run' must be bool.") + global _run_validators + _run_validators = run + + +def get_run_validators(): + """ + Return whether or not validators are run. + """ + return _run_validators diff --git a/Lib/site-packages/attr/_funcs.py b/Lib/site-packages/attr/_funcs.py new file mode 100644 index 0000000..798043a --- /dev/null +++ b/Lib/site-packages/attr/_funcs.py @@ -0,0 +1,212 @@ +from __future__ import absolute_import, division, print_function + +import copy + +from ._compat import iteritems +from ._make import NOTHING, _obj_setattr, fields +from .exceptions import AttrsAttributeNotFoundError + + +def asdict(inst, recurse=True, filter=None, dict_factory=dict, + retain_collection_types=False): + """ + Return the ``attrs`` attribute values of *inst* as a dict. + + Optionally recurse into other ``attrs``-decorated classes. + + :param inst: Instance of an ``attrs``-decorated class. + :param bool recurse: Recurse into classes that are also + ``attrs``-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the :class:`attr.Attribute` as the first argument and the + value as the second argument. + :param callable dict_factory: A callable to produce dictionaries from. For + example, to produce ordered dictionaries instead of normal Python + dictionaries, pass in ``collections.OrderedDict``. + :param bool retain_collection_types: Do not convert to ``list`` when + encountering an attribute whose type is ``tuple`` or ``set``. Only + meaningful if ``recurse`` is ``True``. + + :rtype: return type of *dict_factory* + + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 16.0.0 *dict_factory* + .. versionadded:: 16.1.0 *retain_collection_types* + """ + attrs = fields(inst.__class__) + rv = dict_factory() + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + if recurse is True: + if has(v.__class__): + rv[a.name] = asdict(v, recurse=True, filter=filter, + dict_factory=dict_factory) + elif isinstance(v, (tuple, list, set)): + cf = v.__class__ if retain_collection_types is True else list + rv[a.name] = cf([ + asdict(i, recurse=True, filter=filter, + dict_factory=dict_factory) + if has(i.__class__) else i + for i in v + ]) + elif isinstance(v, dict): + df = dict_factory + rv[a.name] = df(( + asdict(kk, dict_factory=df) if has(kk.__class__) else kk, + asdict(vv, dict_factory=df) if has(vv.__class__) else vv) + for kk, vv in iteritems(v)) + else: + rv[a.name] = v + else: + rv[a.name] = v + return rv + + +def astuple(inst, recurse=True, filter=None, tuple_factory=tuple, + retain_collection_types=False): + """ + Return the ``attrs`` attribute values of *inst* as a tuple. + + Optionally recurse into other ``attrs``-decorated classes. + + :param inst: Instance of an ``attrs``-decorated class. + :param bool recurse: Recurse into classes that are also + ``attrs``-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the :class:`attr.Attribute` as the first argument and the + value as the second argument. + :param callable tuple_factory: A callable to produce tuples from. For + example, to produce lists instead of tuples. + :param bool retain_collection_types: Do not convert to ``list`` + or ``dict`` when encountering an attribute which type is + ``tuple``, ``dict`` or ``set``. Only meaningful if ``recurse`` is + ``True``. + + :rtype: return type of *tuple_factory* + + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 16.2.0 + """ + attrs = fields(inst.__class__) + rv = [] + retain = retain_collection_types # Very long. :/ + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + if recurse is True: + if has(v.__class__): + rv.append(astuple(v, recurse=True, filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain)) + elif isinstance(v, (tuple, list, set)): + cf = v.__class__ if retain is True else list + rv.append(cf([ + astuple(j, recurse=True, filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain) + if has(j.__class__) else j + for j in v + ])) + elif isinstance(v, dict): + df = v.__class__ if retain is True else dict + rv.append(df( + ( + astuple( + kk, + tuple_factory=tuple_factory, + retain_collection_types=retain + ) if has(kk.__class__) else kk, + astuple( + vv, + tuple_factory=tuple_factory, + retain_collection_types=retain + ) if has(vv.__class__) else vv + ) + for kk, vv in iteritems(v))) + else: + rv.append(v) + else: + rv.append(v) + return rv if tuple_factory is list else tuple_factory(rv) + + +def has(cls): + """ + Check whether *cls* is a class with ``attrs`` attributes. + + :param type cls: Class to introspect. + :raise TypeError: If *cls* is not a class. + + :rtype: :class:`bool` + """ + return getattr(cls, "__attrs_attrs__", None) is not None + + +def assoc(inst, **changes): + """ + Copy *inst* and apply *changes*. + + :param inst: Instance of a class with ``attrs`` attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't + be found on *cls*. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. deprecated:: 17.1.0 + Use :func:`evolve` instead. + """ + import warnings + warnings.warn("assoc is deprecated and will be removed after 2018/01.", + DeprecationWarning, stacklevel=2) + new = copy.copy(inst) + attrs = fields(inst.__class__) + for k, v in iteritems(changes): + a = getattr(attrs, k, NOTHING) + if a is NOTHING: + raise AttrsAttributeNotFoundError( + "{k} is not an attrs attribute on {cl}." + .format(k=k, cl=new.__class__) + ) + _obj_setattr(new, k, v) + return new + + +def evolve(inst, **changes): + """ + Create a new instance, based on *inst* with *changes* applied. + + :param inst: Instance of a class with ``attrs`` attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise TypeError: If *attr_name* couldn't be found in the class + ``__init__``. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 17.1.0 + """ + cls = inst.__class__ + attrs = fields(cls) + for a in attrs: + if not a.init: + continue + attr_name = a.name # To deal with private attributes. + init_name = attr_name if attr_name[0] != "_" else attr_name[1:] + if init_name not in changes: + changes[init_name] = getattr(inst, attr_name) + return cls(**changes) diff --git a/Lib/site-packages/attr/_make.py b/Lib/site-packages/attr/_make.py new file mode 100644 index 0000000..fc44611 --- /dev/null +++ b/Lib/site-packages/attr/_make.py @@ -0,0 +1,1689 @@ +from __future__ import absolute_import, division, print_function + +import hashlib +import linecache +import sys +import threading +import warnings + +from operator import itemgetter + +from . import _config +from ._compat import ( + PY2, isclass, iteritems, metadata_proxy, ordered_dict, set_closure_cell +) +from .exceptions import ( + DefaultAlreadySetError, FrozenInstanceError, NotAnAttrsClassError, + UnannotatedAttributeError +) + + +# This is used at least twice, so cache it here. +_obj_setattr = object.__setattr__ +_init_converter_pat = "__attr_converter_{}" +_init_factory_pat = "__attr_factory_{}" +_tuple_property_pat = " {attr_name} = property(itemgetter({index}))" +_classvar_prefixes = ("typing.ClassVar", "t.ClassVar", "ClassVar") + +_empty_metadata_singleton = metadata_proxy({}) + + +class _Nothing(object): + """ + Sentinel class to indicate the lack of a value when ``None`` is ambiguous. + + All instances of `_Nothing` are equal. + """ + def __copy__(self): + return self + + def __deepcopy__(self, _): + return self + + def __eq__(self, other): + return other.__class__ == _Nothing + + def __ne__(self, other): + return not self == other + + def __repr__(self): + return "NOTHING" + + def __hash__(self): + return 0xc0ffee + + +NOTHING = _Nothing() +""" +Sentinel to indicate the lack of a value when ``None`` is ambiguous. +""" + + +def attrib(default=NOTHING, validator=None, + repr=True, cmp=True, hash=None, init=True, + convert=None, metadata=None, type=None, converter=None, + factory=None): + """ + Create a new attribute on a class. + + .. warning:: + + Does *not* do anything unless the class is also decorated with + :func:`attr.s`! + + :param default: A value that is used if an ``attrs``-generated ``__init__`` + is used and no value is passed while instantiating or the attribute is + excluded using ``init=False``. + + If the value is an instance of :class:`Factory`, its callable will be + used to construct a new value (useful for mutable data types like lists + or dicts). + + If a default is not set (or set manually to ``attr.NOTHING``), a value + *must* be supplied when instantiating; otherwise a :exc:`TypeError` + will be raised. + + The default can also be set using decorator notation as shown below. + + :type default: Any value. + + :param callable factory: Syntactic sugar for + ``default=attr.Factory(callable)``. + + :param validator: :func:`callable` that is called by ``attrs``-generated + ``__init__`` methods after the instance has been initialized. They + receive the initialized instance, the :class:`Attribute`, and the + passed value. + + The return value is *not* inspected so the validator has to throw an + exception itself. + + If a ``list`` is passed, its items are treated as validators and must + all pass. + + Validators can be globally disabled and re-enabled using + :func:`get_run_validators`. + + The validator can also be set using decorator notation as shown below. + + :type validator: ``callable`` or a ``list`` of ``callable``\\ s. + + :param bool repr: Include this attribute in the generated ``__repr__`` + method. + :param bool cmp: Include this attribute in the generated comparison methods + (``__eq__`` et al). + :param hash: Include this attribute in the generated ``__hash__`` + method. If ``None`` (default), mirror *cmp*'s value. This is the + correct behavior according the Python spec. Setting this value to + anything else than ``None`` is *discouraged*. + :type hash: ``bool`` or ``None`` + :param bool init: Include this attribute in the generated ``__init__`` + method. It is possible to set this to ``False`` and set a default + value. In that case this attributed is unconditionally initialized + with the specified default value or factory. + :param callable converter: :func:`callable` that is called by + ``attrs``-generated ``__init__`` methods to converter attribute's value + to the desired format. It is given the passed-in value, and the + returned value will be used as the new value of the attribute. The + value is converted before being passed to the validator, if any. + :param metadata: An arbitrary mapping, to be used by third-party + components. See :ref:`extending_metadata`. + :param type: The type of the attribute. In Python 3.6 or greater, the + preferred method to specify the type is using a variable annotation + (see `PEP 526 `_). + This argument is provided for backward compatibility. + Regardless of the approach used, the type will be stored on + ``Attribute.type``. + + .. versionadded:: 15.2.0 *convert* + .. versionadded:: 16.3.0 *metadata* + .. versionchanged:: 17.1.0 *validator* can be a ``list`` now. + .. versionchanged:: 17.1.0 + *hash* is ``None`` and therefore mirrors *cmp* by default. + .. versionadded:: 17.3.0 *type* + .. deprecated:: 17.4.0 *convert* + .. versionadded:: 17.4.0 *converter* as a replacement for the deprecated + *convert* to achieve consistency with other noun-based arguments. + .. versionadded:: 18.1.0 + ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``. + """ + if hash is not None and hash is not True and hash is not False: + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + + if convert is not None: + if converter is not None: + raise RuntimeError( + "Can't pass both `convert` and `converter`. " + "Please use `converter` only." + ) + warnings.warn( + "The `convert` argument is deprecated in favor of `converter`. " + "It will be removed after 2019/01.", + DeprecationWarning, stacklevel=2 + ) + converter = convert + + if factory is not None: + if default is not NOTHING: + raise ValueError( + "The `default` and `factory` arguments are mutually " + "exclusive." + ) + if not callable(factory): + raise ValueError( + "The `factory` argument must be a callable." + ) + default = Factory(factory) + + if metadata is None: + metadata = {} + + return _CountingAttr( + default=default, + validator=validator, + repr=repr, + cmp=cmp, + hash=hash, + init=init, + converter=converter, + metadata=metadata, + type=type, + ) + + +def _make_attr_tuple_class(cls_name, attr_names): + """ + Create a tuple subclass to hold `Attribute`s for an `attrs` class. + + The subclass is a bare tuple with properties for names. + + class MyClassAttributes(tuple): + __slots__ = () + x = property(itemgetter(0)) + """ + attr_class_name = "{}Attributes".format(cls_name) + attr_class_template = [ + "class {}(tuple):".format(attr_class_name), + " __slots__ = ()", + ] + if attr_names: + for i, attr_name in enumerate(attr_names): + attr_class_template.append(_tuple_property_pat.format( + index=i, + attr_name=attr_name, + )) + else: + attr_class_template.append(" pass") + globs = {"itemgetter": itemgetter} + eval(compile("\n".join(attr_class_template), "", "exec"), globs) + return globs[attr_class_name] + + +# Tuple class for extracted attributes from a class definition. +# `super_attrs` is a subset of `attrs`. +_Attributes = _make_attr_tuple_class("_Attributes", [ + "attrs", # all attributes to build dunder methods for + "super_attrs", # attributes that have been inherited + "super_attrs_map", # map inherited attributes to their originating classes +]) + + +def _is_class_var(annot): + """ + Check whether *annot* is a typing.ClassVar. + + The string comparison hack is used to avoid evaluating all string + annotations which would put attrs-based classes at a performance + disadvantage compared to plain old classes. + """ + return str(annot).startswith(_classvar_prefixes) + + +def _get_annotations(cls): + """ + Get annotations for *cls*. + """ + anns = getattr(cls, "__annotations__", None) + if anns is None: + return {} + + # Verify that the annotations aren't merely inherited. + for super_cls in cls.__mro__[1:]: + if anns is getattr(super_cls, "__annotations__", None): + return {} + + return anns + + +def _counter_getter(e): + """ + Key function for sorting to avoid re-creating a lambda for every class. + """ + return e[1].counter + + +def _transform_attrs(cls, these, auto_attribs): + """ + Transform all `_CountingAttr`s on a class into `Attribute`s. + + If *these* is passed, use that and don't look for them on the class. + + Return an `_Attributes`. + """ + cd = cls.__dict__ + anns = _get_annotations(cls) + + if these is not None: + ca_list = [ + (name, ca) + for name, ca + in iteritems(these) + ] + + if not isinstance(these, ordered_dict): + ca_list.sort(key=_counter_getter) + elif auto_attribs is True: + ca_names = { + name + for name, attr + in cd.items() + if isinstance(attr, _CountingAttr) + } + ca_list = [] + annot_names = set() + for attr_name, type in anns.items(): + if _is_class_var(type): + continue + annot_names.add(attr_name) + a = cd.get(attr_name, NOTHING) + if not isinstance(a, _CountingAttr): + if a is NOTHING: + a = attrib() + else: + a = attrib(default=a) + ca_list.append((attr_name, a)) + + unannotated = ca_names - annot_names + if len(unannotated) > 0: + raise UnannotatedAttributeError( + "The following `attr.ib`s lack a type annotation: " + + ", ".join(sorted( + unannotated, + key=lambda n: cd.get(n).counter + )) + "." + ) + else: + ca_list = sorted(( + (name, attr) + for name, attr + in cd.items() + if isinstance(attr, _CountingAttr) + ), key=lambda e: e[1].counter) + + own_attrs = [ + Attribute.from_counting_attr( + name=attr_name, + ca=ca, + type=anns.get(attr_name), + ) + for attr_name, ca + in ca_list + ] + + super_attrs = [] + super_attr_map = {} # A dictionary of superattrs to their classes. + taken_attr_names = {a.name: a for a in own_attrs} + + # Traverse the MRO and collect attributes. + for super_cls in cls.__mro__[1:-1]: + sub_attrs = getattr(super_cls, "__attrs_attrs__", None) + if sub_attrs is not None: + for a in sub_attrs: + prev_a = taken_attr_names.get(a.name) + # Only add an attribute if it hasn't been defined before. This + # allows for overwriting attribute definitions by subclassing. + if prev_a is None: + super_attrs.append(a) + taken_attr_names[a.name] = a + super_attr_map[a.name] = super_cls + + attr_names = [a.name for a in super_attrs + own_attrs] + + AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) + + attrs = AttrsClass( + super_attrs + [ + Attribute.from_counting_attr( + name=attr_name, + ca=ca, + type=anns.get(attr_name) + ) + for attr_name, ca + in ca_list + ] + ) + + had_default = False + for a in attrs: + if had_default is True and a.default is NOTHING and a.init is True: + raise ValueError( + "No mandatory attributes allowed after an attribute with a " + "default value or factory. Attribute in question: {a!r}" + .format(a=a) + ) + elif had_default is False and \ + a.default is not NOTHING and \ + a.init is not False: + had_default = True + + return _Attributes((attrs, super_attrs, super_attr_map)) + + +def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + raise FrozenInstanceError() + + +def _frozen_delattrs(self, name): + """ + Attached to frozen classes as __delattr__. + """ + raise FrozenInstanceError() + + +class _ClassBuilder(object): + """ + Iteratively build *one* class. + """ + __slots__ = ( + "_cls", "_cls_dict", "_attrs", "_super_names", "_attr_names", "_slots", + "_frozen", "_has_post_init", "_delete_attribs", "_super_attr_map", + ) + + def __init__(self, cls, these, slots, frozen, auto_attribs): + attrs, super_attrs, super_map = _transform_attrs( + cls, these, auto_attribs + ) + + self._cls = cls + self._cls_dict = dict(cls.__dict__) if slots else {} + self._attrs = attrs + self._super_names = set(a.name for a in super_attrs) + self._super_attr_map = super_map + self._attr_names = tuple(a.name for a in attrs) + self._slots = slots + self._frozen = frozen or _has_frozen_superclass(cls) + self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) + self._delete_attribs = not bool(these) + + self._cls_dict["__attrs_attrs__"] = self._attrs + + if frozen: + self._cls_dict["__setattr__"] = _frozen_setattrs + self._cls_dict["__delattr__"] = _frozen_delattrs + + def __repr__(self): + return "<_ClassBuilder(cls={cls})>".format(cls=self._cls.__name__) + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used anymore after calling this method. + """ + if self._slots is True: + return self._create_slots_class() + else: + return self._patch_original_class() + + def _patch_original_class(self): + """ + Apply accumulated methods and return the class. + """ + cls = self._cls + super_names = self._super_names + + # Clean class of attribute definitions (`attr.ib()`s). + if self._delete_attribs: + for name in self._attr_names: + if name not in super_names and \ + getattr(cls, name, None) is not None: + delattr(cls, name) + + # Attach our dunder methods. + for name, value in self._cls_dict.items(): + setattr(cls, name, value) + + return cls + + def _create_slots_class(self): + """ + Build and return a new class with a `__slots__` attribute. + """ + super_names = self._super_names + cd = { + k: v + for k, v in iteritems(self._cls_dict) + if k not in tuple(self._attr_names) + ("__dict__",) + } + + # We only add the names of attributes that aren't inherited. + # Settings __slots__ to inherited attributes wastes memory. + cd["__slots__"] = tuple( + name + for name in self._attr_names + if name not in super_names + ) + + qualname = getattr(self._cls, "__qualname__", None) + if qualname is not None: + cd["__qualname__"] = qualname + + # __weakref__ is not writable. + state_attr_names = tuple( + an for an in self._attr_names if an != "__weakref__" + ) + + def slots_getstate(self): + """ + Automatically created by attrs. + """ + return tuple( + getattr(self, name) + for name in state_attr_names + ) + + def slots_setstate(self, state): + """ + Automatically created by attrs. + """ + __bound_setattr = _obj_setattr.__get__(self, Attribute) + for name, value in zip(state_attr_names, state): + __bound_setattr(name, value) + + # slots and frozen require __getstate__/__setstate__ to work + cd["__getstate__"] = slots_getstate + cd["__setstate__"] = slots_setstate + + # Create new class based on old class and our methods. + cls = type(self._cls)( + self._cls.__name__, + self._cls.__bases__, + cd, + ) + + # The following is a fix for + # https://github.com/python-attrs/attrs/issues/102. On Python 3, + # if a method mentions `__class__` or uses the no-arg super(), the + # compiler will bake a reference to the class in the method itself + # as `method.__closure__`. Since we replace the class with a + # clone, we rewrite these references so it keeps working. + for item in cls.__dict__.values(): + if isinstance(item, (classmethod, staticmethod)): + # Class- and staticmethods hide their functions inside. + # These might need to be rewritten as well. + closure_cells = getattr(item.__func__, "__closure__", None) + else: + closure_cells = getattr(item, "__closure__", None) + + if not closure_cells: # Catch None or the empty list. + continue + for cell in closure_cells: + if cell.cell_contents is self._cls: + set_closure_cell(cell, cls) + + return cls + + def add_repr(self, ns): + self._cls_dict["__repr__"] = self._add_method_dunders( + _make_repr(self._attrs, ns=ns) + ) + return self + + def add_str(self): + repr = self._cls_dict.get("__repr__") + if repr is None: + raise ValueError( + "__str__ can only be generated if a __repr__ exists." + ) + + def __str__(self): + return self.__repr__() + + self._cls_dict["__str__"] = self._add_method_dunders(__str__) + return self + + def make_unhashable(self): + self._cls_dict["__hash__"] = None + return self + + def add_hash(self): + self._cls_dict["__hash__"] = self._add_method_dunders( + _make_hash(self._attrs) + ) + + return self + + def add_init(self): + self._cls_dict["__init__"] = self._add_method_dunders( + _make_init( + self._attrs, + self._has_post_init, + self._frozen, + self._slots, + self._super_attr_map, + ) + ) + + return self + + def add_cmp(self): + cd = self._cls_dict + + cd["__eq__"], cd["__ne__"], cd["__lt__"], cd["__le__"], cd["__gt__"], \ + cd["__ge__"] = ( + self._add_method_dunders(meth) + for meth in _make_cmp(self._attrs) + ) + + return self + + def _add_method_dunders(self, method): + """ + Add __module__ and __qualname__ to a *method* if possible. + """ + try: + method.__module__ = self._cls.__module__ + except AttributeError: + pass + + try: + method.__qualname__ = ".".join( + (self._cls.__qualname__, method.__name__,) + ) + except AttributeError: + pass + + return method + + +def attrs(maybe_cls=None, these=None, repr_ns=None, + repr=True, cmp=True, hash=None, init=True, + slots=False, frozen=False, str=False, auto_attribs=False): + r""" + A class decorator that adds `dunder + `_\ -methods according to the + specified attributes using :func:`attr.ib` or the *these* argument. + + :param these: A dictionary of name to :func:`attr.ib` mappings. This is + useful to avoid the definition of your attributes within the class body + because you can't (e.g. if you want to add ``__repr__`` methods to + Django models) or don't want to. + + If *these* is not ``None``, ``attrs`` will *not* search the class body + for attributes and will *not* remove any attributes from it. + + If *these* is an ordered dict (:class:`dict` on Python 3.6+, + :class:`collections.OrderedDict` otherwise), the order is deduced from + the order of the attributes inside *these*. Otherwise the order + of the definition of the attributes is used. + + :type these: :class:`dict` of :class:`str` to :func:`attr.ib` + + :param str repr_ns: When using nested classes, there's no way in Python 2 + to automatically detect that. Therefore it's possible to set the + namespace explicitly for a more meaningful ``repr`` output. + :param bool repr: Create a ``__repr__`` method with a human readable + representation of ``attrs`` attributes.. + :param bool str: Create a ``__str__`` method that is identical to + ``__repr__``. This is usually not necessary except for + :class:`Exception`\ s. + :param bool cmp: Create ``__eq__``, ``__ne__``, ``__lt__``, ``__le__``, + ``__gt__``, and ``__ge__`` methods that compare the class as if it were + a tuple of its ``attrs`` attributes. But the attributes are *only* + compared, if the type of both classes is *identical*! + :param hash: If ``None`` (default), the ``__hash__`` method is generated + according how *cmp* and *frozen* are set. + + 1. If *both* are True, ``attrs`` will generate a ``__hash__`` for you. + 2. If *cmp* is True and *frozen* is False, ``__hash__`` will be set to + None, marking it unhashable (which it is). + 3. If *cmp* is False, ``__hash__`` will be left untouched meaning the + ``__hash__`` method of the superclass will be used (if superclass is + ``object``, this means it will fall back to id-based hashing.). + + Although not recommended, you can decide for yourself and force + ``attrs`` to create one (e.g. if the class is immutable even though you + didn't freeze it programmatically) by passing ``True`` or not. Both of + these cases are rather special and should be used carefully. + + See the `Python documentation \ + `_ + and the `GitHub issue that led to the default behavior \ + `_ for more details. + :type hash: ``bool`` or ``None`` + :param bool init: Create a ``__init__`` method that initializes the + ``attrs`` attributes. Leading underscores are stripped for the + argument name. If a ``__attrs_post_init__`` method exists on the + class, it will be called after the class is fully initialized. + :param bool slots: Create a slots_-style class that's more + memory-efficient. See :ref:`slots` for further ramifications. + :param bool frozen: Make instances immutable after initialization. If + someone attempts to modify a frozen instance, + :exc:`attr.exceptions.FrozenInstanceError` is raised. + + Please note: + + 1. This is achieved by installing a custom ``__setattr__`` method + on your class so you can't implement an own one. + + 2. True immutability is impossible in Python. + + 3. This *does* have a minor a runtime performance :ref:`impact + ` when initializing new instances. In other words: + ``__init__`` is slightly slower with ``frozen=True``. + + 4. If a class is frozen, you cannot modify ``self`` in + ``__attrs_post_init__`` or a self-written ``__init__``. You can + circumvent that limitation by using + ``object.__setattr__(self, "attribute_name", value)``. + + .. _slots: https://docs.python.org/3/reference/datamodel.html#slots + :param bool auto_attribs: If True, collect `PEP 526`_-annotated attributes + (Python 3.6 and later only) from the class body. + + In this case, you **must** annotate every field. If ``attrs`` + encounters a field that is set to an :func:`attr.ib` but lacks a type + annotation, an :exc:`attr.exceptions.UnannotatedAttributeError` is + raised. Use ``field_name: typing.Any = attr.ib(...)`` if you don't + want to set a type. + + If you assign a value to those attributes (e.g. ``x: int = 42``), that + value becomes the default value like if it were passed using + ``attr.ib(default=42)``. Passing an instance of :class:`Factory` also + works as expected. + + Attributes annotated as :data:`typing.ClassVar` are **ignored**. + + .. _`PEP 526`: https://www.python.org/dev/peps/pep-0526/ + + .. versionadded:: 16.0.0 *slots* + .. versionadded:: 16.1.0 *frozen* + .. versionadded:: 16.3.0 *str* + .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``. + .. versionchanged:: 17.1.0 + *hash* supports ``None`` as value which is also the default now. + .. versionadded:: 17.3.0 *auto_attribs* + .. versionchanged:: 18.1.0 + If *these* is passed, no attributes are deleted from the class body. + .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained. + """ + def wrap(cls): + if getattr(cls, "__class__", None) is None: + raise TypeError("attrs only works with new-style classes.") + + builder = _ClassBuilder(cls, these, slots, frozen, auto_attribs) + + if repr is True: + builder.add_repr(repr_ns) + if str is True: + builder.add_str() + if cmp is True: + builder.add_cmp() + + if hash is not True and hash is not False and hash is not None: + # Can't use `hash in` because 1 == True for example. + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + elif hash is False or (hash is None and cmp is False): + pass + elif hash is True or (hash is None and cmp is True and frozen is True): + builder.add_hash() + else: + builder.make_unhashable() + + if init is True: + builder.add_init() + + return builder.build_class() + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but ``None`` if used as `@attrs()`. + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +_attrs = attrs +""" +Internal alias so we can use it in functions that take an argument called +*attrs*. +""" + + +if PY2: + def _has_frozen_superclass(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return ( + getattr( + cls.__setattr__, "__module__", None + ) == _frozen_setattrs.__module__ and + cls.__setattr__.__name__ == _frozen_setattrs.__name__ + ) +else: + def _has_frozen_superclass(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return cls.__setattr__ == _frozen_setattrs + + +def _attrs_to_tuple(obj, attrs): + """ + Create a tuple of all values of *obj*'s *attrs*. + """ + return tuple(getattr(obj, a.name) for a in attrs) + + +def _make_hash(attrs): + attrs = tuple( + a + for a in attrs + if a.hash is True or (a.hash is None and a.cmp is True) + ) + + # We cache the generated hash methods for the same kinds of attributes. + sha1 = hashlib.sha1() + sha1.update(repr(attrs).encode("utf-8")) + unique_filename = "" % (sha1.hexdigest(),) + type_hash = hash(unique_filename) + lines = [ + "def __hash__(self):", + " return hash((", + " %d," % (type_hash,), + ] + for a in attrs: + lines.append(" self.%s," % (a.name)) + + lines.append(" ))") + + script = "\n".join(lines) + globs = {} + locs = {} + bytecode = compile(script, unique_filename, "exec") + eval(bytecode, globs, locs) + + # In order of debuggers like PDB being able to step through the code, + # we add a fake linecache entry. + linecache.cache[unique_filename] = ( + len(script), + None, + script.splitlines(True), + unique_filename, + ) + + return locs["__hash__"] + + +def _add_hash(cls, attrs): + """ + Add a hash method to *cls*. + """ + cls.__hash__ = _make_hash(attrs) + return cls + + +def __ne__(self, other): + """ + Check equality and either forward a NotImplemented or return the result + negated. + """ + result = self.__eq__(other) + if result is NotImplemented: + return NotImplemented + + return not result + + +def _make_cmp(attrs): + attrs = [a for a in attrs if a.cmp] + + # We cache the generated eq methods for the same kinds of attributes. + sha1 = hashlib.sha1() + sha1.update(repr(attrs).encode("utf-8")) + unique_filename = "" % (sha1.hexdigest(),) + lines = [ + "def __eq__(self, other):", + " if other.__class__ is not self.__class__:", + " return NotImplemented", + ] + # We can't just do a big self.x = other.x and... clause due to + # irregularities like nan == nan is false but (nan,) == (nan,) is true. + if attrs: + lines.append(" return (") + others = [ + " ) == (", + ] + for a in attrs: + lines.append(" self.%s," % (a.name,)) + others.append(" other.%s," % (a.name,)) + + lines += others + [" )"] + else: + lines.append(" return True") + + script = "\n".join(lines) + globs = {} + locs = {} + bytecode = compile(script, unique_filename, "exec") + eval(bytecode, globs, locs) + + # In order of debuggers like PDB being able to step through the code, + # we add a fake linecache entry. + linecache.cache[unique_filename] = ( + len(script), + None, + script.splitlines(True), + unique_filename, + ) + eq = locs["__eq__"] + ne = __ne__ + + def attrs_to_tuple(obj): + """ + Save us some typing. + """ + return _attrs_to_tuple(obj, attrs) + + def __lt__(self, other): + """ + Automatically created by attrs. + """ + if isinstance(other, self.__class__): + return attrs_to_tuple(self) < attrs_to_tuple(other) + else: + return NotImplemented + + def __le__(self, other): + """ + Automatically created by attrs. + """ + if isinstance(other, self.__class__): + return attrs_to_tuple(self) <= attrs_to_tuple(other) + else: + return NotImplemented + + def __gt__(self, other): + """ + Automatically created by attrs. + """ + if isinstance(other, self.__class__): + return attrs_to_tuple(self) > attrs_to_tuple(other) + else: + return NotImplemented + + def __ge__(self, other): + """ + Automatically created by attrs. + """ + if isinstance(other, self.__class__): + return attrs_to_tuple(self) >= attrs_to_tuple(other) + else: + return NotImplemented + + return eq, ne, __lt__, __le__, __gt__, __ge__ + + +def _add_cmp(cls, attrs=None): + """ + Add comparison methods to *cls*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__eq__, cls.__ne__, cls.__lt__, cls.__le__, cls.__gt__, cls.__ge__ = \ + _make_cmp(attrs) + + return cls + + +_already_repring = threading.local() + + +def _make_repr(attrs, ns): + """ + Make a repr method for *attr_names* adding *ns* to the full name. + """ + attr_names = tuple( + a.name + for a in attrs + if a.repr + ) + + def __repr__(self): + """ + Automatically created by attrs. + """ + try: + working_set = _already_repring.working_set + except AttributeError: + working_set = set() + _already_repring.working_set = working_set + + if id(self) in working_set: + return "..." + real_cls = self.__class__ + if ns is None: + qualname = getattr(real_cls, "__qualname__", None) + if qualname is not None: + class_name = qualname.rsplit(">.", 1)[-1] + else: + class_name = real_cls.__name__ + else: + class_name = ns + "." + real_cls.__name__ + + # Since 'self' remains on the stack (i.e.: strongly referenced) for the + # duration of this call, it's safe to depend on id(...) stability, and + # not need to track the instance and therefore worry about properties + # like weakref- or hash-ability. + working_set.add(id(self)) + try: + result = [class_name, "("] + first = True + for name in attr_names: + if first: + first = False + else: + result.append(", ") + result.extend((name, "=", repr(getattr(self, name, NOTHING)))) + return "".join(result) + ")" + finally: + working_set.remove(id(self)) + return __repr__ + + +def _add_repr(cls, ns=None, attrs=None): + """ + Add a repr method to *cls*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__repr__ = _make_repr(attrs, ns) + return cls + + +def _make_init(attrs, post_init, frozen, slots, super_attr_map): + attrs = [ + a + for a in attrs + if a.init or a.default is not NOTHING + ] + + # We cache the generated init methods for the same kinds of attributes. + sha1 = hashlib.sha1() + sha1.update(repr(attrs).encode("utf-8")) + unique_filename = "".format( + sha1.hexdigest() + ) + + script, globs, annotations = _attrs_to_init_script( + attrs, + frozen, + slots, + post_init, + super_attr_map, + ) + locs = {} + bytecode = compile(script, unique_filename, "exec") + attr_dict = dict((a.name, a) for a in attrs) + globs.update({ + "NOTHING": NOTHING, + "attr_dict": attr_dict, + }) + if frozen is True: + # Save the lookup overhead in __init__ if we need to circumvent + # immutability. + globs["_cached_setattr"] = _obj_setattr + eval(bytecode, globs, locs) + + # In order of debuggers like PDB being able to step through the code, + # we add a fake linecache entry. + linecache.cache[unique_filename] = ( + len(script), + None, + script.splitlines(True), + unique_filename, + ) + + __init__ = locs["__init__"] + __init__.__annotations__ = annotations + return __init__ + + +def _add_init(cls, frozen): + """ + Add a __init__ method to *cls*. If *frozen* is True, make it immutable. + """ + cls.__init__ = _make_init( + cls.__attrs_attrs__, + getattr(cls, "__attrs_post_init__", False), + frozen, + _is_slot_cls(cls), + {}, + ) + return cls + + +def fields(cls): + """ + Return the tuple of ``attrs`` attributes for a class. + + The tuple also allows accessing the fields by their names (see below for + examples). + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + :rtype: tuple (with name accessors) of :class:`attr.Attribute` + + .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields + by name. + """ + if not isclass(cls): + raise TypeError("Passed object must be a class.") + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + raise NotAnAttrsClassError( + "{cls!r} is not an attrs-decorated class.".format(cls=cls) + ) + return attrs + + +def fields_dict(cls): + """ + Return an ordered dictionary of ``attrs`` attributes for a class, whose + keys are the attribute names. + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + :rtype: an ordered dict where keys are attribute names and values are + :class:`attr.Attribute`\\ s. This will be a :class:`dict` if it's + naturally ordered like on Python 3.6+ or an + :class:`~collections.OrderedDict` otherwise. + + .. versionadded:: 18.1.0 + """ + if not isclass(cls): + raise TypeError("Passed object must be a class.") + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + raise NotAnAttrsClassError( + "{cls!r} is not an attrs-decorated class.".format(cls=cls) + ) + return ordered_dict(((a.name, a) for a in attrs)) + + +def validate(inst): + """ + Validate all attributes on *inst* that have a validator. + + Leaves all exceptions through. + + :param inst: Instance of a class with ``attrs`` attributes. + """ + if _config._run_validators is False: + return + + for a in fields(inst.__class__): + v = a.validator + if v is not None: + v(inst, a, getattr(inst, a.name)) + + +def _is_slot_cls(cls): + return "__slots__" in cls.__dict__ + + +def _is_slot_attr(a_name, super_attr_map): + """ + Check if the attribute name comes from a slot class. + """ + return a_name in super_attr_map and _is_slot_cls(super_attr_map[a_name]) + + +def _attrs_to_init_script(attrs, frozen, slots, post_init, super_attr_map): + """ + Return a script of an initializer for *attrs* and a dict of globals. + + The globals are expected by the generated script. + + If *frozen* is True, we cannot set the attributes directly so we use + a cached ``object.__setattr__``. + """ + lines = [] + any_slot_ancestors = any( + _is_slot_attr(a.name, super_attr_map) + for a in attrs + ) + if frozen is True: + if slots is True: + lines.append( + # Circumvent the __setattr__ descriptor to save one lookup per + # assignment. + "_setattr = _cached_setattr.__get__(self, self.__class__)" + ) + + def fmt_setter(attr_name, value_var): + return "_setattr('%(attr_name)s', %(value_var)s)" % { + "attr_name": attr_name, + "value_var": value_var, + } + + def fmt_setter_with_converter(attr_name, value_var): + conv_name = _init_converter_pat.format(attr_name) + return "_setattr('%(attr_name)s', %(conv)s(%(value_var)s))" % { + "attr_name": attr_name, + "value_var": value_var, + "conv": conv_name, + } + else: + # Dict frozen classes assign directly to __dict__. + # But only if the attribute doesn't come from an ancestor slot + # class. + lines.append( + "_inst_dict = self.__dict__" + ) + if any_slot_ancestors: + lines.append( + # Circumvent the __setattr__ descriptor to save one lookup + # per assignment. + "_setattr = _cached_setattr.__get__(self, self.__class__)" + ) + + def fmt_setter(attr_name, value_var): + if _is_slot_attr(attr_name, super_attr_map): + res = "_setattr('%(attr_name)s', %(value_var)s)" % { + "attr_name": attr_name, + "value_var": value_var, + } + else: + res = "_inst_dict['%(attr_name)s'] = %(value_var)s" % { + "attr_name": attr_name, + "value_var": value_var, + } + return res + + def fmt_setter_with_converter(attr_name, value_var): + conv_name = _init_converter_pat.format(attr_name) + if _is_slot_attr(attr_name, super_attr_map): + tmpl = "_setattr('%(attr_name)s', %(c)s(%(value_var)s))" + else: + tmpl = "_inst_dict['%(attr_name)s'] = %(c)s(%(value_var)s)" + return tmpl % { + "attr_name": attr_name, + "value_var": value_var, + "c": conv_name, + } + else: + # Not frozen. + def fmt_setter(attr_name, value): + return "self.%(attr_name)s = %(value)s" % { + "attr_name": attr_name, + "value": value, + } + + def fmt_setter_with_converter(attr_name, value_var): + conv_name = _init_converter_pat.format(attr_name) + return "self.%(attr_name)s = %(conv)s(%(value_var)s)" % { + "attr_name": attr_name, + "value_var": value_var, + "conv": conv_name, + } + + args = [] + attrs_to_validate = [] + + # This is a dictionary of names to validator and converter callables. + # Injecting this into __init__ globals lets us avoid lookups. + names_for_globals = {} + annotations = {'return': None} + + for a in attrs: + if a.validator: + attrs_to_validate.append(a) + attr_name = a.name + arg_name = a.name.lstrip("_") + has_factory = isinstance(a.default, Factory) + if has_factory and a.default.takes_self: + maybe_self = "self" + else: + maybe_self = "" + if a.init is False: + if has_factory: + init_factory_name = _init_factory_pat.format(a.name) + if a.converter is not None: + lines.append(fmt_setter_with_converter( + attr_name, + init_factory_name + "({0})".format(maybe_self))) + conv_name = _init_converter_pat.format(a.name) + names_for_globals[conv_name] = a.converter + else: + lines.append(fmt_setter( + attr_name, + init_factory_name + "({0})".format(maybe_self) + )) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.converter is not None: + lines.append(fmt_setter_with_converter( + attr_name, + "attr_dict['{attr_name}'].default" + .format(attr_name=attr_name) + )) + conv_name = _init_converter_pat.format(a.name) + names_for_globals[conv_name] = a.converter + else: + lines.append(fmt_setter( + attr_name, + "attr_dict['{attr_name}'].default" + .format(attr_name=attr_name) + )) + elif a.default is not NOTHING and not has_factory: + args.append( + "{arg_name}=attr_dict['{attr_name}'].default".format( + arg_name=arg_name, + attr_name=attr_name, + ) + ) + if a.converter is not None: + lines.append(fmt_setter_with_converter(attr_name, arg_name)) + names_for_globals[_init_converter_pat.format(a.name)] = ( + a.converter + ) + else: + lines.append(fmt_setter(attr_name, arg_name)) + elif has_factory: + args.append("{arg_name}=NOTHING".format(arg_name=arg_name)) + lines.append("if {arg_name} is not NOTHING:" + .format(arg_name=arg_name)) + init_factory_name = _init_factory_pat.format(a.name) + if a.converter is not None: + lines.append(" " + fmt_setter_with_converter( + attr_name, arg_name + )) + lines.append("else:") + lines.append(" " + fmt_setter_with_converter( + attr_name, + init_factory_name + "({0})".format(maybe_self) + )) + names_for_globals[_init_converter_pat.format(a.name)] = ( + a.converter + ) + else: + lines.append(" " + fmt_setter(attr_name, arg_name)) + lines.append("else:") + lines.append(" " + fmt_setter( + attr_name, + init_factory_name + "({0})".format(maybe_self) + )) + names_for_globals[init_factory_name] = a.default.factory + else: + args.append(arg_name) + if a.converter is not None: + lines.append(fmt_setter_with_converter(attr_name, arg_name)) + names_for_globals[_init_converter_pat.format(a.name)] = ( + a.converter + ) + else: + lines.append(fmt_setter(attr_name, arg_name)) + + if a.init is True and a.converter is None and a.type is not None: + annotations[arg_name] = a.type + + if attrs_to_validate: # we can skip this if there are no validators. + names_for_globals["_config"] = _config + lines.append("if _config._run_validators is True:") + for a in attrs_to_validate: + val_name = "__attr_validator_{}".format(a.name) + attr_name = "__attr_{}".format(a.name) + lines.append(" {}(self, {}, self.{})".format( + val_name, attr_name, a.name)) + names_for_globals[val_name] = a.validator + names_for_globals[attr_name] = a + if post_init: + lines.append("self.__attrs_post_init__()") + + return """\ +def __init__(self, {args}): + {lines} +""".format( + args=", ".join(args), + lines="\n ".join(lines) if lines else "pass", + ), names_for_globals, annotations + + +class Attribute(object): + """ + *Read-only* representation of an attribute. + + :attribute name: The name of the attribute. + + Plus *all* arguments of :func:`attr.ib`. + + For the version history of the fields, see :func:`attr.ib`. + """ + __slots__ = ( + "name", "default", "validator", "repr", "cmp", "hash", "init", + "metadata", "type", "converter", + ) + + def __init__(self, name, default, validator, repr, cmp, hash, init, + convert=None, metadata=None, type=None, converter=None): + # Cache this descriptor here to speed things up later. + bound_setattr = _obj_setattr.__get__(self, Attribute) + + # Despite the big red warning, people *do* instantiate `Attribute` + # themselves. + if convert is not None: + if converter is not None: + raise RuntimeError( + "Can't pass both `convert` and `converter`. " + "Please use `converter` only." + ) + warnings.warn( + "The `convert` argument is deprecated in favor of `converter`." + " It will be removed after 2019/01.", + DeprecationWarning, stacklevel=2 + ) + converter = convert + + bound_setattr("name", name) + bound_setattr("default", default) + bound_setattr("validator", validator) + bound_setattr("repr", repr) + bound_setattr("cmp", cmp) + bound_setattr("hash", hash) + bound_setattr("init", init) + bound_setattr("converter", converter) + bound_setattr("metadata", ( + metadata_proxy(metadata) if metadata + else _empty_metadata_singleton + )) + bound_setattr("type", type) + + def __setattr__(self, name, value): + raise FrozenInstanceError() + + @property + def convert(self): + warnings.warn( + "The `convert` attribute is deprecated in favor of `converter`. " + "It will be removed after 2019/01.", + DeprecationWarning, stacklevel=2, + ) + return self.converter + + @classmethod + def from_counting_attr(cls, name, ca, type=None): + # type holds the annotated value. deal with conflicts: + if type is None: + type = ca.type + elif ca.type is not None: + raise ValueError( + "Type annotation and type argument cannot both be present" + ) + inst_dict = { + k: getattr(ca, k) + for k + in Attribute.__slots__ + if k not in ( + "name", "validator", "default", "type", "convert", + ) # exclude methods and deprecated alias + } + return cls( + name=name, validator=ca._validator, default=ca._default, type=type, + **inst_dict + ) + + # Don't use _add_pickle since fields(Attribute) doesn't work + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple(getattr(self, name) if name != "metadata" + else dict(self.metadata) + for name in self.__slots__) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + bound_setattr = _obj_setattr.__get__(self, Attribute) + for name, value in zip(self.__slots__, state): + if name != "metadata": + bound_setattr(name, value) + else: + bound_setattr(name, metadata_proxy(value) if value else + _empty_metadata_singleton) + + +_a = [ + Attribute(name=name, default=NOTHING, validator=None, + repr=True, cmp=True, hash=(name != "metadata"), init=True) + for name in Attribute.__slots__ + if name != "convert" # XXX: remove once `convert` is gone +] + +Attribute = _add_hash( + _add_cmp(_add_repr(Attribute, attrs=_a), attrs=_a), + attrs=[a for a in _a if a.hash] +) + + +class _CountingAttr(object): + """ + Intermediate representation of attributes that uses a counter to preserve + the order in which the attributes have been defined. + + *Internal* data structure of the attrs library. Running into is most + likely the result of a bug like a forgotten `@attr.s` decorator. + """ + __slots__ = ("counter", "_default", "repr", "cmp", "hash", "init", + "metadata", "_validator", "converter", "type") + __attrs_attrs__ = tuple( + Attribute(name=name, default=NOTHING, validator=None, + repr=True, cmp=True, hash=True, init=True) + for name + in ("counter", "_default", "repr", "cmp", "hash", "init",) + ) + ( + Attribute(name="metadata", default=None, validator=None, + repr=True, cmp=True, hash=False, init=True), + ) + cls_counter = 0 + + def __init__(self, default, validator, repr, cmp, hash, init, converter, + metadata, type): + _CountingAttr.cls_counter += 1 + self.counter = _CountingAttr.cls_counter + self._default = default + # If validator is a list/tuple, wrap it using helper validator. + if validator and isinstance(validator, (list, tuple)): + self._validator = and_(*validator) + else: + self._validator = validator + self.repr = repr + self.cmp = cmp + self.hash = hash + self.init = init + self.converter = converter + self.metadata = metadata + self.type = type + + def validator(self, meth): + """ + Decorator that adds *meth* to the list of validators. + + Returns *meth* unchanged. + + .. versionadded:: 17.1.0 + """ + if self._validator is None: + self._validator = meth + else: + self._validator = and_(self._validator, meth) + return meth + + def default(self, meth): + """ + Decorator that allows to set the default for an attribute. + + Returns *meth* unchanged. + + :raises DefaultAlreadySetError: If default has been set before. + + .. versionadded:: 17.1.0 + """ + if self._default is not NOTHING: + raise DefaultAlreadySetError() + + self._default = Factory(meth, takes_self=True) + + return meth + + +_CountingAttr = _add_cmp(_add_repr(_CountingAttr)) + + +@attrs(slots=True, init=False, hash=True) +class Factory(object): + """ + Stores a factory callable. + + If passed as the default value to :func:`attr.ib`, the factory is used to + generate a new value. + + :param callable factory: A callable that takes either none or exactly one + mandatory positional argument depending on *takes_self*. + :param bool takes_self: Pass the partially initialized instance that is + being initialized as a positional argument. + + .. versionadded:: 17.1.0 *takes_self* + """ + factory = attrib() + takes_self = attrib() + + def __init__(self, factory, takes_self=False): + """ + `Factory` is part of the default machinery so if we want a default + value here, we have to implement it ourselves. + """ + self.factory = factory + self.takes_self = takes_self + + +def make_class(name, attrs, bases=(object,), **attributes_arguments): + """ + A quick way to create a new class called *name* with *attrs*. + + :param name: The name for the new class. + :type name: str + + :param attrs: A list of names or a dictionary of mappings of names to + attributes. + + If *attrs* is a list or an ordered dict (:class:`dict` on Python 3.6+, + :class:`collections.OrderedDict` otherwise), the order is deduced from + the order of the names or attributes inside *attrs*. Otherwise the + order of the definition of the attributes is used. + :type attrs: :class:`list` or :class:`dict` + + :param tuple bases: Classes that the new class will subclass. + + :param attributes_arguments: Passed unmodified to :func:`attr.s`. + + :return: A new class with *attrs*. + :rtype: type + + .. versionadded:: 17.1.0 *bases* + .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. + """ + if isinstance(attrs, dict): + cls_dict = attrs + elif isinstance(attrs, (list, tuple)): + cls_dict = dict((a, attrib()) for a in attrs) + else: + raise TypeError("attrs argument must be a dict or a list.") + + post_init = cls_dict.pop("__attrs_post_init__", None) + type_ = type( + name, + bases, + {} if post_init is None else {"__attrs_post_init__": post_init} + ) + # For pickling to work, the __module__ variable needs to be set to the + # frame where the class is created. Bypass this step in environments where + # sys._getframe is not defined (Jython for example) or sys._getframe is not + # defined for arguments greater than 0 (IronPython). + try: + type_.__module__ = sys._getframe(1).f_globals.get( + "__name__", "__main__", + ) + except (AttributeError, ValueError): + pass + + return _attrs(these=cls_dict, **attributes_arguments)(type_) + + +# These are required by within this module so we define them here and merely +# import into .validators. + + +@attrs(slots=True, hash=True) +class _AndValidator(object): + """ + Compose many validators to a single one. + """ + _validators = attrib() + + def __call__(self, inst, attr, value): + for v in self._validators: + v(inst, attr, value) + + +def and_(*validators): + """ + A validator that composes multiple validators into one. + + When called on a value, it runs all wrapped validators. + + :param validators: Arbitrary number of validators. + :type validators: callables + + .. versionadded:: 17.1.0 + """ + vals = [] + for validator in validators: + vals.extend( + validator._validators if isinstance(validator, _AndValidator) + else [validator] + ) + + return _AndValidator(tuple(vals)) diff --git a/Lib/site-packages/attr/converters.py b/Lib/site-packages/attr/converters.py new file mode 100644 index 0000000..3b3bac9 --- /dev/null +++ b/Lib/site-packages/attr/converters.py @@ -0,0 +1,24 @@ +""" +Commonly useful converters. +""" + +from __future__ import absolute_import, division, print_function + + +def optional(converter): + """ + A converter that allows an attribute to be optional. An optional attribute + is one which can be set to ``None``. + + :param callable converter: the converter that is used for non-``None`` + values. + + .. versionadded:: 17.1.0 + """ + + def optional_converter(val): + if val is None: + return None + return converter(val) + + return optional_converter diff --git a/Lib/site-packages/attr/exceptions.py b/Lib/site-packages/attr/exceptions.py new file mode 100644 index 0000000..f949f3c --- /dev/null +++ b/Lib/site-packages/attr/exceptions.py @@ -0,0 +1,48 @@ +from __future__ import absolute_import, division, print_function + + +class FrozenInstanceError(AttributeError): + """ + A frozen/immutable instance has been attempted to be modified. + + It mirrors the behavior of ``namedtuples`` by using the same error message + and subclassing :exc:`AttributeError`. + + .. versionadded:: 16.1.0 + """ + msg = "can't set attribute" + args = [msg] + + +class AttrsAttributeNotFoundError(ValueError): + """ + An ``attrs`` function couldn't find an attribute that the user asked for. + + .. versionadded:: 16.2.0 + """ + + +class NotAnAttrsClassError(ValueError): + """ + A non-``attrs`` class has been passed into an ``attrs`` function. + + .. versionadded:: 16.2.0 + """ + + +class DefaultAlreadySetError(RuntimeError): + """ + A default has been set using ``attr.ib()`` and is attempted to be reset + using the decorator. + + .. versionadded:: 17.1.0 + """ + + +class UnannotatedAttributeError(RuntimeError): + """ + A class with ``auto_attribs=True`` has an ``attr.ib()`` without a type + annotation. + + .. versionadded:: 17.3.0 + """ diff --git a/Lib/site-packages/attr/filters.py b/Lib/site-packages/attr/filters.py new file mode 100644 index 0000000..f1c69b8 --- /dev/null +++ b/Lib/site-packages/attr/filters.py @@ -0,0 +1,52 @@ +""" +Commonly useful filters for :func:`attr.asdict`. +""" + +from __future__ import absolute_import, division, print_function + +from ._compat import isclass +from ._make import Attribute + + +def _split_what(what): + """ + Returns a tuple of `frozenset`s of classes and attributes. + """ + return ( + frozenset(cls for cls in what if isclass(cls)), + frozenset(cls for cls in what if isinstance(cls, Attribute)), + ) + + +def include(*what): + """ + Whitelist *what*. + + :param what: What to whitelist. + :type what: :class:`list` of :class:`type` or :class:`attr.Attribute`\\ s + + :rtype: :class:`callable` + """ + cls, attrs = _split_what(what) + + def include_(attribute, value): + return value.__class__ in cls or attribute in attrs + + return include_ + + +def exclude(*what): + """ + Blacklist *what*. + + :param what: What to blacklist. + :type what: :class:`list` of classes or :class:`attr.Attribute`\\ s. + + :rtype: :class:`callable` + """ + cls, attrs = _split_what(what) + + def exclude_(attribute, value): + return value.__class__ not in cls and attribute not in attrs + + return exclude_ diff --git a/Lib/site-packages/attr/validators.py b/Lib/site-packages/attr/validators.py new file mode 100644 index 0000000..f8892fc --- /dev/null +++ b/Lib/site-packages/attr/validators.py @@ -0,0 +1,166 @@ +""" +Commonly useful validators. +""" + +from __future__ import absolute_import, division, print_function + +from ._make import _AndValidator, and_, attrib, attrs + + +__all__ = [ + "and_", + "in_", + "instance_of", + "optional", + "provides", +] + + +@attrs(repr=False, slots=True, hash=True) +class _InstanceOfValidator(object): + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not isinstance(value, self.type): + raise TypeError( + "'{name}' must be {type!r} (got {value!r} that is a " + "{actual!r})." + .format(name=attr.name, type=self.type, + actual=value.__class__, value=value), + attr, self.type, value, + ) + + def __repr__(self): + return ( + "" + .format(type=self.type) + ) + + +def instance_of(type): + """ + A validator that raises a :exc:`TypeError` if the initializer is called + with a wrong type for this particular attribute (checks are performed using + :func:`isinstance` therefore it's also valid to pass a tuple of types). + + :param type: The type to check for. + :type type: type or tuple of types + + :raises TypeError: With a human readable error message, the attribute + (of type :class:`attr.Attribute`), the expected type, and the value it + got. + """ + return _InstanceOfValidator(type) + + +@attrs(repr=False, slots=True, hash=True) +class _ProvidesValidator(object): + interface = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.interface.providedBy(value): + raise TypeError( + "'{name}' must provide {interface!r} which {value!r} " + "doesn't." + .format(name=attr.name, interface=self.interface, value=value), + attr, self.interface, value, + ) + + def __repr__(self): + return ( + "" + .format(interface=self.interface) + ) + + +def provides(interface): + """ + A validator that raises a :exc:`TypeError` if the initializer is called + with an object that does not provide the requested *interface* (checks are + performed using ``interface.providedBy(value)`` (see `zope.interface + `_). + + :param zope.interface.Interface interface: The interface to check for. + + :raises TypeError: With a human readable error message, the attribute + (of type :class:`attr.Attribute`), the expected interface, and the + value it got. + """ + return _ProvidesValidator(interface) + + +@attrs(repr=False, slots=True, hash=True) +class _OptionalValidator(object): + validator = attrib() + + def __call__(self, inst, attr, value): + if value is None: + return + + self.validator(inst, attr, value) + + def __repr__(self): + return ( + "" + .format(what=repr(self.validator)) + ) + + +def optional(validator): + """ + A validator that makes an attribute optional. An optional attribute is one + which can be set to ``None`` in addition to satisfying the requirements of + the sub-validator. + + :param validator: A validator (or a list of validators) that is used for + non-``None`` values. + :type validator: callable or :class:`list` of callables. + + .. versionadded:: 15.1.0 + .. versionchanged:: 17.1.0 *validator* can be a list of validators. + """ + if isinstance(validator, list): + return _OptionalValidator(_AndValidator(validator)) + return _OptionalValidator(validator) + + +@attrs(repr=False, slots=True, hash=True) +class _InValidator(object): + options = attrib() + + def __call__(self, inst, attr, value): + if value not in self.options: + raise ValueError( + "'{name}' must be in {options!r} (got {value!r})" + .format(name=attr.name, options=self.options, value=value) + ) + + def __repr__(self): + return ( + "" + .format(options=self.options) + ) + + +def in_(options): + """ + A validator that raises a :exc:`ValueError` if the initializer is called + with a value that does not belong in the options provided. The check is + performed using ``value in options``. + + :param options: Allowed options. + :type options: list, tuple, :class:`enum.Enum`, ... + + :raises ValueError: With a human readable error message, the attribute (of + type :class:`attr.Attribute`), the expected options, and the value it + got. + + .. versionadded:: 17.1.0 + """ + return _InValidator(options) diff --git a/Lib/site-packages/attrs-18.1.0.dist-info/INSTALLER b/Lib/site-packages/attrs-18.1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/attrs-18.1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/attrs-18.1.0.dist-info/LICENSE.txt b/Lib/site-packages/attrs-18.1.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..7ae3df9 --- /dev/null +++ b/Lib/site-packages/attrs-18.1.0.dist-info/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Hynek Schlawack + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Lib/site-packages/attrs-18.1.0.dist-info/METADATA b/Lib/site-packages/attrs-18.1.0.dist-info/METADATA new file mode 100644 index 0000000..efe670a --- /dev/null +++ b/Lib/site-packages/attrs-18.1.0.dist-info/METADATA @@ -0,0 +1,261 @@ +Metadata-Version: 2.1 +Name: attrs +Version: 18.1.0 +Summary: Classes Without Boilerplate +Home-page: http://www.attrs.org/ +Author: Hynek Schlawack +Author-email: hs@ox.cx +Maintainer: Hynek Schlawack +Maintainer-email: hs@ox.cx +License: MIT +Keywords: class,attribute,boilerplate +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Provides-Extra: tests +Provides-Extra: docs +Provides-Extra: dev +Provides-Extra: dev +Requires-Dist: coverage; extra == 'dev' +Requires-Dist: hypothesis; extra == 'dev' +Requires-Dist: pympler; extra == 'dev' +Requires-Dist: pytest; extra == 'dev' +Requires-Dist: six; extra == 'dev' +Requires-Dist: zope.interface; extra == 'dev' +Requires-Dist: sphinx; extra == 'dev' +Requires-Dist: zope.interface; extra == 'dev' +Provides-Extra: docs +Requires-Dist: sphinx; extra == 'docs' +Requires-Dist: zope.interface; extra == 'docs' +Provides-Extra: tests +Requires-Dist: coverage; extra == 'tests' +Requires-Dist: hypothesis; extra == 'tests' +Requires-Dist: pympler; extra == 'tests' +Requires-Dist: pytest; extra == 'tests' +Requires-Dist: six; extra == 'tests' +Requires-Dist: zope.interface; extra == 'tests' + +.. image:: http://www.attrs.org/en/latest/_static/attrs_logo.png + :alt: attrs Logo + +====================================== +``attrs``: Classes Without Boilerplate +====================================== + +.. image:: https://readthedocs.org/projects/attrs/badge/?version=stable + :target: http://www.attrs.org/en/stable/?badge=stable + :alt: Documentation Status + +.. image:: https://travis-ci.org/python-attrs/attrs.svg?branch=master + :target: https://travis-ci.org/python-attrs/attrs + :alt: CI Status + +.. image:: https://codecov.io/github/python-attrs/attrs/branch/master/graph/badge.svg + :target: https://codecov.io/github/python-attrs/attrs + :alt: Test Coverage + +.. teaser-begin + +``attrs`` is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka `dunder `_ methods). + +Its main goal is to help you to write **concise** and **correct** software without slowing down your code. + +.. -spiel-end- + +For that, it gives you a class decorator and a way to declaratively define the attributes on that class: + +.. -code-begin- + +.. code-block:: pycon + + >>> import attr + + >>> @attr.s + ... class SomeClass(object): + ... a_number = attr.ib(default=42) + ... list_of_numbers = attr.ib(default=attr.Factory(list)) + ... + ... def hard_math(self, another_number): + ... return self.a_number + sum(self.list_of_numbers) * another_number + + + >>> sc = SomeClass(1, [1, 2, 3]) + >>> sc + SomeClass(a_number=1, list_of_numbers=[1, 2, 3]) + + >>> sc.hard_math(3) + 19 + >>> sc == SomeClass(1, [1, 2, 3]) + True + >>> sc != SomeClass(2, [3, 2, 1]) + True + + >>> attr.asdict(sc) + {'a_number': 1, 'list_of_numbers': [1, 2, 3]} + + >>> SomeClass() + SomeClass(a_number=42, list_of_numbers=[]) + + >>> C = attr.make_class("C", ["a", "b"]) + >>> C("foo", "bar") + C(a='foo', b='bar') + + +After *declaring* your attributes ``attrs`` gives you: + +- a concise and explicit overview of the class's attributes, +- a nice human-readable ``__repr__``, +- a complete set of comparison methods, +- an initializer, +- and much more, + +*without* writing dull boilerplate code again and again and *without* runtime performance penalties. + +This gives you the power to use actual classes with actual types in your code instead of confusing ``tuple``\ s or `confusingly behaving `_ ``namedtuple``\ s. +Which in turn encourages you to write *small classes* that do `one thing well `_. +Never again violate the `single responsibility principle `_ just because implementing ``__init__`` et al is a painful drag. + + +.. -testimonials- + +Testimonials +============ + +**Amber Hawkie Brown**, Twisted Release Manager and Computer Owl: + + Writing a fully-functional class using attrs takes me less time than writing this testimonial. + + +**Glyph Lefkowitz**, creator of `Twisted `_, `Automat `_, and other open source software, in `The One Python Library Everyone Needs `_: + + I’m looking forward to is being able to program in Python-with-attrs everywhere. + It exerts a subtle, but positive, design influence in all the codebases I’ve see it used in. + + +**Kenneth Reitz**, author of `requests `_, Python Overlord at Heroku, `on paper no less `_: + + attrs—classes for humans. I like it. + + +**Åukasz Langa**, prolific CPython core developer and Production Engineer at Facebook: + + I'm increasingly digging your attr.ocity. Good job! + + +.. -end- + +.. -project-information- + +Getting Help +============ + +Please use the ``python-attrs`` tag on `StackOverflow `_ to get help. + +Answering questions of your fellow developers is also great way to help the project! + + +Project Information +=================== + +``attrs`` is released under the `MIT `_ license, +its documentation lives at `Read the Docs `_, +the code on `GitHub `_, +and the latest release on `PyPI `_. +It’s rigorously tested on Python 2.7, 3.4+, and PyPy. + +We collect information on **third-party extensions** in our `wiki `_. +Feel free to browse and add your own! + +If you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide `_ to get you started! + + +Release Information +=================== + +18.1.0 (2018-05-03) +------------------- + +Changes +^^^^^^^ + +- ``x=X(); x.cycle = x; repr(x)`` will no longer raise a ``RecursionError``, and will instead show as ``X(x=...)``. + + `#95 `_ +- ``attr.ib(factory=f)`` is now syntactic sugar for the common case of ``attr.ib(default=attr.Factory(f))``. + + `#178 `_, + `#356 `_ +- Added ``attr.field_dict()`` to return an ordered dictionary of ``attrs`` attributes for a class, whose keys are the attribute names. + + `#290 `_, + `#349 `_ +- The order of attributes that are passed into ``attr.make_class()`` or the ``these`` argument of ``@attr.s()`` is now retained if the dictionary is ordered (i.e. ``dict`` on Python 3.6 and later, ``collections.OrderedDict`` otherwise). + + Before, the order was always determined by the order in which the attributes have been defined which may not be desirable when creating classes programatically. + + `#300 `_, + `#339 `_, + `#343 `_ +- In slotted classes, ``__getstate__`` and ``__setstate__`` now ignore the ``__weakref__`` attribute. + + `#311 `_, + `#326 `_ +- Setting the cell type is now completely best effort. + This fixes ``attrs`` on Jython. + + We cannot make any guarantees regarding Jython though, because our test suite cannot run due to dependency incompatabilities. + + `#321 `_, + `#334 `_ +- If ``attr.s`` is passed a *these* argument, it will not attempt to remove attributes with the same name from the class body anymore. + + `#322 `_, + `#323 `_ +- The hash of ``attr.NOTHING`` is now vegan and faster on 32bit Python builds. + + `#331 `_, + `#332 `_ +- The overhead of instantiating frozen dict classes is virtually eliminated. + `#336 `_ +- Generated ``__init__`` methods now have an ``__annotations__`` attribute derived from the types of the fields. + + `#363 `_ +- We have restructured the documentation a bit to account for ``attrs``' growth in scope. + Instead of putting everything into the `examples `_ page, we have started to extract narrative chapters. + + So far, we've added chapters on `initialization `_ and `hashing `_. + + Expect more to come! + + `#369 `_, + `#370 `_ + +`Full changelog `_. + +Credits +======= + +``attrs`` is written and maintained by `Hynek Schlawack `_. + +The development is kindly supported by `Variomedia AG `_. + +A full list of contributors can be found in `GitHub's overview `_. + +It’s the spiritual successor of `characteristic `_ and aspires to fix some of it clunkiness and unfortunate decisions. +Both were inspired by Twisted’s `FancyEqMixin `_ but both are implemented using class decorators because `sub-classing is bad for you `_, m’kay? + + diff --git a/Lib/site-packages/attrs-18.1.0.dist-info/RECORD b/Lib/site-packages/attrs-18.1.0.dist-info/RECORD new file mode 100644 index 0000000..a5542bf --- /dev/null +++ b/Lib/site-packages/attrs-18.1.0.dist-info/RECORD @@ -0,0 +1,24 @@ +attr/__init__.py,sha256=JHeEKVqs4kM5-rDJXZ7xV_Kjq6X14tm6hjNeh-mkvB8,1196 +attr/_compat.py,sha256=87nka-93oZB_uU5qDcEombhD52qNH_JzwaHRKqCcnuc,4490 +attr/_config.py,sha256=_KvW0mQdH2PYjHc0YfIUaV_o2pVfM7ziMEYTxwmEhOA,514 +attr/_funcs.py,sha256=anaGKByzPuMXjHLiLW5QW0qJvAXSCT1LNzThi-hLbHs,7894 +attr/_make.py,sha256=M2XZcksor99iTixAlYnfC-Eahv7l34zb4lIuOgc4SBI,55996 +attr/converters.py,sha256=a_84JgIJ_5G41lXBomMU9QaUkBc1fIG7nPdHlM8-mvY,531 +attr/exceptions.py,sha256=CzPHJV28pjDPg9q31bLaKoWY90C4IW2GUv21CoEy_g8,1105 +attr/filters.py,sha256=s6NrcRWJKlCQauPEH0S4lmgFwlCdUQcHKcNkDHpptN4,1153 +attr/validators.py,sha256=ejKCIhnlQZ_zlXqGexV9Zzp2Pjb_XbVUFWxgFrUJLRk,4960 +attrs-18.1.0.dist-info/LICENSE.txt,sha256=v2WaKLSSQGAvVrvfSQy-LsUJsVuY-Z17GaUsdA4yeGM,1082 +attrs-18.1.0.dist-info/METADATA,sha256=3m0oD5T1WZGLkWFo12OZO6ZJ2lIask9-6gCUdVUJzgI,10847 +attrs-18.1.0.dist-info/RECORD,, +attrs-18.1.0.dist-info/WHEEL,sha256=J3CsTk7Mf2JNUyhImI-mjX-fmI4oDjyiXgWT4qgZiCE,110 +attrs-18.1.0.dist-info/top_level.txt,sha256=tlRYMddkRlKPqJ96wP2_j9uEsmcNHgD2SbuWd4CzGVU,5 +attrs-18.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +attr/__pycache__/converters.cpython-37.pyc,, +attr/__pycache__/exceptions.cpython-37.pyc,, +attr/__pycache__/filters.cpython-37.pyc,, +attr/__pycache__/validators.cpython-37.pyc,, +attr/__pycache__/_compat.cpython-37.pyc,, +attr/__pycache__/_config.cpython-37.pyc,, +attr/__pycache__/_funcs.cpython-37.pyc,, +attr/__pycache__/_make.cpython-37.pyc,, +attr/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/attrs-18.1.0.dist-info/WHEEL b/Lib/site-packages/attrs-18.1.0.dist-info/WHEEL new file mode 100644 index 0000000..f21b51c --- /dev/null +++ b/Lib/site-packages/attrs-18.1.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/attrs-18.1.0.dist-info/top_level.txt b/Lib/site-packages/attrs-18.1.0.dist-info/top_level.txt new file mode 100644 index 0000000..66a062d --- /dev/null +++ b/Lib/site-packages/attrs-18.1.0.dist-info/top_level.txt @@ -0,0 +1 @@ +attr diff --git a/Lib/site-packages/click-6.7.dist-info/DESCRIPTION.rst b/Lib/site-packages/click-6.7.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..e118723 --- /dev/null +++ b/Lib/site-packages/click-6.7.dist-info/DESCRIPTION.rst @@ -0,0 +1,3 @@ +UNKNOWN + + diff --git a/Lib/site-packages/click-6.7.dist-info/INSTALLER b/Lib/site-packages/click-6.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/click-6.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/click-6.7.dist-info/METADATA b/Lib/site-packages/click-6.7.dist-info/METADATA new file mode 100644 index 0000000..1f10885 --- /dev/null +++ b/Lib/site-packages/click-6.7.dist-info/METADATA @@ -0,0 +1,16 @@ +Metadata-Version: 2.0 +Name: click +Version: 6.7 +Summary: A simple wrapper around optparse for powerful command line utilities. +Home-page: http://github.com/mitsuhiko/click +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: UNKNOWN +Platform: UNKNOWN +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 + +UNKNOWN + + diff --git a/Lib/site-packages/click-6.7.dist-info/RECORD b/Lib/site-packages/click-6.7.dist-info/RECORD new file mode 100644 index 0000000..cdb44da --- /dev/null +++ b/Lib/site-packages/click-6.7.dist-info/RECORD @@ -0,0 +1,41 @@ +click/__init__.py,sha256=k8R00cFKWI8dhDVKQeLBlAdNh1CxerMEDRiGnr32gdw,2858 +click/_bashcomplete.py,sha256=82rMiibtEurdwBq60NHXVCBuGXJHDpblFO9o2YxJDF0,2423 +click/_compat.py,sha256=j59MpzxYGE-fTGj0A5sg8UI8GhHod1XMojiCA0jvbL0,21011 +click/_termui_impl.py,sha256=Ol1JJhvBRw3l8j1WIU0tOWjQtxxmwGE44lFDbzDqzoA,16395 +click/_textwrap.py,sha256=gwS4m7bdQiJnzaDG8osFcRb-5vn4t4l2qSCy-5csCEc,1198 +click/_unicodefun.py,sha256=A3UOzJw6lEZyol2SBg3fNXgweTutaOzkJ61OB7vik3Y,4204 +click/_winconsole.py,sha256=MzG46DEYPoRyx4SO7EIhFuFZHESgooAfJLIukbB6p5c,7790 +click/core.py,sha256=M0nJ6Kkye7XZXYG7HCbkJWSfy14WHV6bQmGLACrOhKw,70254 +click/decorators.py,sha256=y7CX2needh8iRWafj-QS_hGQFsN24eyXAhx5Y2ATwas,10941 +click/exceptions.py,sha256=rOa0pP3PbSy0_AAPOW9irBEM8AJ3BySN-4z2VUwFVo4,6788 +click/formatting.py,sha256=eh-cypTUAhpI3HD-K4ZpR3vCiURIO62xXvKkR3tNUTM,8889 +click/globals.py,sha256=PAgnKvGxq4YuEIldw3lgYOGBLYwsyxnm1IByBX3BFXo,1515 +click/parser.py,sha256=i01xgYuIA6AwQWEXjshwHSwnTR3gUep4FxJIfyW4ta4,15510 +click/termui.py,sha256=Bp99MSWQtyoWe1_7HggDmA77n--3KLxu7NsZMFMaCUo,21008 +click/testing.py,sha256=kJ9mjtJgwNAlkgKcFf9-ISxufmaPDbbuOHVC9WIvKdY,11002 +click/types.py,sha256=ZGb2lmFs5Vwd9loTRIMbGcqhPVOql8mGoBhWBRT6V4E,18864 +click/utils.py,sha256=1jalPlkUU28JReTEQeeSFtbJd-SirYWBNfjtELBKzT4,14916 +click-6.7.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 +click-6.7.dist-info/METADATA,sha256=l6lAyogIUXiHKUK_rWguef-EMcvO5C6bXzFCNCcblbQ,424 +click-6.7.dist-info/RECORD,, +click-6.7.dist-info/WHEEL,sha256=5wvfB7GvgZAbKBSE9uX9Zbi6LCL-_KgezgHblXhCRnM,113 +click-6.7.dist-info/metadata.json,sha256=qg0uO6amNHkIkOxnmWX7Xa_DNQMQ62Q6drivuP9Gh1c,571 +click-6.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click-6.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click/__pycache__/core.cpython-37.pyc,, +click/__pycache__/decorators.cpython-37.pyc,, +click/__pycache__/exceptions.cpython-37.pyc,, +click/__pycache__/formatting.cpython-37.pyc,, +click/__pycache__/globals.cpython-37.pyc,, +click/__pycache__/parser.cpython-37.pyc,, +click/__pycache__/termui.cpython-37.pyc,, +click/__pycache__/testing.cpython-37.pyc,, +click/__pycache__/types.cpython-37.pyc,, +click/__pycache__/utils.cpython-37.pyc,, +click/__pycache__/_bashcomplete.cpython-37.pyc,, +click/__pycache__/_compat.cpython-37.pyc,, +click/__pycache__/_termui_impl.cpython-37.pyc,, +click/__pycache__/_textwrap.cpython-37.pyc,, +click/__pycache__/_unicodefun.cpython-37.pyc,, +click/__pycache__/_winconsole.cpython-37.pyc,, +click/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/click-6.7.dist-info/WHEEL b/Lib/site-packages/click-6.7.dist-info/WHEEL new file mode 100644 index 0000000..7bf9daa --- /dev/null +++ b/Lib/site-packages/click-6.7.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0.a0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/click-6.7.dist-info/metadata.json b/Lib/site-packages/click-6.7.dist-info/metadata.json new file mode 100644 index 0000000..0a4cfb1 --- /dev/null +++ b/Lib/site-packages/click-6.7.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3"], "extensions": {"python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "http://github.com/mitsuhiko/click"}}}, "generator": "bdist_wheel (0.30.0.a0)", "metadata_version": "2.0", "name": "click", "summary": "A simple wrapper around optparse for powerful command line utilities.", "version": "6.7"} \ No newline at end of file diff --git a/Lib/site-packages/click-6.7.dist-info/top_level.txt b/Lib/site-packages/click-6.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/Lib/site-packages/click-6.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/Lib/site-packages/click/__init__.py b/Lib/site-packages/click/__init__.py new file mode 100644 index 0000000..971e55d --- /dev/null +++ b/Lib/site-packages/click/__init__.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +""" + click + ~~~~~ + + Click is a simple Python module that wraps the stdlib's optparse to make + writing command line scripts fun. Unlike other modules, it's based around + a simple API that does not come with too much magic and is composable. + + In case optparse ever gets removed from the stdlib, it will be shipped by + this module. + + :copyright: (c) 2014 by Armin Ronacher. + :license: BSD, see LICENSE for more details. +""" + +# Core classes +from .core import Context, BaseCommand, Command, MultiCommand, Group, \ + CommandCollection, Parameter, Option, Argument + +# Globals +from .globals import get_current_context + +# Decorators +from .decorators import pass_context, pass_obj, make_pass_decorator, \ + command, group, argument, option, confirmation_option, \ + password_option, version_option, help_option + +# Types +from .types import ParamType, File, Path, Choice, IntRange, Tuple, \ + STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED + +# Utilities +from .utils import echo, get_binary_stream, get_text_stream, open_file, \ + format_filename, get_app_dir, get_os_args + +# Terminal functions +from .termui import prompt, confirm, get_terminal_size, echo_via_pager, \ + progressbar, clear, style, unstyle, secho, edit, launch, getchar, \ + pause + +# Exceptions +from .exceptions import ClickException, UsageError, BadParameter, \ + FileError, Abort, NoSuchOption, BadOptionUsage, BadArgumentUsage, \ + MissingParameter + +# Formatting +from .formatting import HelpFormatter, wrap_text + +# Parsing +from .parser import OptionParser + + +__all__ = [ + # Core classes + 'Context', 'BaseCommand', 'Command', 'MultiCommand', 'Group', + 'CommandCollection', 'Parameter', 'Option', 'Argument', + + # Globals + 'get_current_context', + + # Decorators + 'pass_context', 'pass_obj', 'make_pass_decorator', 'command', 'group', + 'argument', 'option', 'confirmation_option', 'password_option', + 'version_option', 'help_option', + + # Types + 'ParamType', 'File', 'Path', 'Choice', 'IntRange', 'Tuple', 'STRING', + 'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED', + + # Utilities + 'echo', 'get_binary_stream', 'get_text_stream', 'open_file', + 'format_filename', 'get_app_dir', 'get_os_args', + + # Terminal functions + 'prompt', 'confirm', 'get_terminal_size', 'echo_via_pager', + 'progressbar', 'clear', 'style', 'unstyle', 'secho', 'edit', 'launch', + 'getchar', 'pause', + + # Exceptions + 'ClickException', 'UsageError', 'BadParameter', 'FileError', + 'Abort', 'NoSuchOption', 'BadOptionUsage', 'BadArgumentUsage', + 'MissingParameter', + + # Formatting + 'HelpFormatter', 'wrap_text', + + # Parsing + 'OptionParser', +] + + +# Controls if click should emit the warning about the use of unicode +# literals. +disable_unicode_literals_warning = False + + +__version__ = '6.7' diff --git a/Lib/site-packages/click/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/click/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2654b19577e509f121705727681e6012b61eef92 GIT binary patch literal 2720 zcmbuBTT>g$5r8FhMG^uGzTd_+HV6X-i~(bek%YkbV4w`7Dif-$0`m*aRt-oObtfs=9)Z_1l^OWwlU@;2U)cak+Z?=Iex_wc^Fj}PPn zd?+8{Bl!p)%f~3Bz$fwvK9x`LnS6#*atfcz=gGRf_X4NoG|tEwtjQYA%2|9VU*epc z!+ANM=oGvKd?jDuqFlr!xrEDd8DGoSxFT2ZjeLWvauwI)8m`NAd@JALhTOn+@?EmF z=xySA`5w3A7JiT)a9eI;UDmN78`zXh+>txjlC4B{*xSWDxrZO+$3!l9`}j$IqH!52 zFalK=g)tb18!!Qra1(C9ZMXw>;U3(F2k;Oc!DA5c1fIe(n1bi<0;XXGYA_2gVGibD z0bao(EWt9oh81`NtFQ*^@D?`U9c;pT*n$tR4RvTh6Lz2lyRZizVIMxhPo28_2@d1| ze3qZ#@FZ0`vj0JaE(v-Z&vm{gqrdV~N`_6I6s{Jw&@P6a6316@H}C}p&?71C+OfEd z>`>EC2_1vywx_iS!Z@@eO$vcP`>RTfT}E!~`W@i}h_(;HbA4LkL~a;sanbV^ggEm( z_p1^C8H)x!^qg>GGTFAZ0%1o%&xgd^_mJwx`~5&5P+Isw%pR1ubmK1hrvQ3Rm!jyn zj$pU68+soG+HQMlp})_4UpQp{N8IWg1<+9xSfnucMxHOC0DrYfj*47(o@mo1x^5Vf zPWvi}Ebfwzeuf72H=H26irh{&-VifRO)M`it&p~;N9g+EOW@lM?RX(sy+JuwzE&He zak4Wfv{K?=zu7uGX^D$~vl1x*Dz;ruFO>dGk85c&K^d`}UKEjN zIem|{vZ;i&*4MHrCQ{J;vzg%1TZstD2_icVB2#b%G37c*6h(Vr-{h%lIEV?deBnlD zvt$h>N7>9}5W)3Cl`5ovrBLoFFC4tARR%jby$Y4d?z$fF*p9m<-|PmIUQ^un<1e<~ zQ6_iVqrNuzlhZHzhkGWoe|Tzgy9Y=0QrNlPEJ}owSvhi zryH1Y&PUtz?dZzVainZCqddixxSkjeLgiZ*9KtBok9L&^KBd`|S=kOl3*4wL1lpo} z=-PP(RW6bp^mXVOS``)Q{^bEZ>~*A?oiFjw5Ag&t=o2Fa*n6?kB+a% zccJI^2RWUDo>kz+Chyrj-|3nH1>$sBJG6URQA1Uequ=`3QT?Kn&NR7bMG=*-(y-x2 zqYQI;`!90!b`Zs;au}S@nHw}vm9+cA#Dp0m`MReDGoM|p>1OzDvo>T#K2kY%lYDVE z4)Z0G@ z7?X^fj9ZM`j600GjC+jxj0cQ|j7N;e48eH9c*=Ojm|{Fp{E_@oAG!$oea>~_^4OkdSyF(Te88-p?>Ye}%X2AyO1^bzM?P6F zWy`w0BCWrrq64lq<3GpEjq@`)Ir_YH_=i7=rM2^V81C4yeSQ!)ws(H2Fgy?4aNeaW zgS^dqf9b~d)zZaz@;}0WmgV|xY*`E8l__razjj-Elr%S9HZzy4WL9$P*{SSiZZ0>L jspLxOVrD2qOlLFIbSYCz=jm4^sYr7}nQSJX&u0D$Rml3& literal 0 HcmV?d00001 diff --git a/Lib/site-packages/click/__pycache__/_bashcomplete.cpython-37.pyc b/Lib/site-packages/click/__pycache__/_bashcomplete.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07d55f4fdc9ae03c2902647214d8dbce4c22aee7 GIT binary patch literal 2370 zcmZuy%Wf1$6s_vV%(y)sY{!^KA~Hfoag#X0$|4F0D8zt71U3SLLt|()U2VJVp6+o~ zjWMQYWkgDmV_vd!o8HYn5STN{$z=b93%<9;I%^Ai{=5*Y^HDfocb?QOA(+C={Yr#;$_dHSG z=fSXOh@oFu&=j5+Mn58&Vg!9lw8Sa&r^KijLq96`L*|da!@X?&9Y^c)%1Pq20{y7! zW~mM%xf&`h(|pyps^-03rqj8i(}{9X)fT!sE%Kdzy-U+^(dlN1PQsO59{XzAZ@>21 zD02(oG!Oe%)E>69s4Fl`x9g-t(D?hdZtCk_r#r2*iCm7&&~g0X%4) zd{r>|Ap-CD_r6omz*CH9pq_S1-MOBwcH;dw=8Y6)3-den~Fdsgg zdvNFeV&zf*bbY%T>dIo(xL!4n9sq=cdc0z$|6+0+zP^7ncXj!ZN~Bu8HUIcYd-mJq z8{O{BNJq2%%Vx68H66X0U0IH^G~PI9!xxcSJG|%X?yKtb zYJz7ELJc^C1Ft6u;wBo#C%DCHs7)>>V8_G)mD)iyZ0x`&**Y*UErASsYxnJKQQGSq z)jGqZ);30tc6TkQkLUXi&FYtjxWIiueJF_q}P~CRGOv4LpPEN`6VduhvyW$c0jxg*E znonqL7_Tg{EnKa)KgWckV~mgT^MH7qH@L$ua(MxBu|q2;4OF@{Mpb{J(I&i0Yu5&V zfCX@!CAd}@;Iri#AcE)-SbKb*skQCJ(pk6G?VIe`bibyZvPMLxpEs|TF2Jv?L*h8V zHsc13H?JNUS1&(oKVY4FngFx2Iz^!++?IE@okxrl|RQ#q+lIv){as2yy) zj8lrZU?2z7SPt@`#XXY`<3yO{!IIP1aimkEQAC-^4EhJsO!IZ*#W}XiNui7da$woW z7i0!e)puSsORGc{^j&~|)?wP&@Z?<%K=E(n^xY>cw|-&U7qm<2Ryw7->wthJCm7 zdTc)exT?i33kd>T)0?oDQ`jWGpoSFdWXy}=P-BwoSW=`U3_!L3AxR4$wI+DelCzjU zihFt-RRbgmKBfMKCC?L}BsIGhIV~&*g)MBXe5EadW*0NU0SxYZRZ~Sz#>ryPIE;nc zzHR(5dS-6)onz1B7%mE0hnperkm?T|YMzwQdpK|)mJN8~AW#qz-(c1slV75%Ec_+7 zJ)LICTx=pAQa(W6i3^#S;5JDhTXcfdrkiGo9ELS`D23sG3{Gm+a+6`osuJWx8%y*D|xs(jZD)o`L-3fi& zS|3wBp2k&H<=(bRThxfk<36EARRQ;{YD|seKKY`hwy24>Ej1C?i`&-R(ssPrswVMf zGT4FVok8x4wmuu&RoWHYUD_SoQ@SU(JGiUnl=i4?YCFdGSa5IYKD9&bM7=08--Vg) zUn&UP50oCbV72ymR`B4py#6oS;-A_jJ@>wDwelA&b+_7$zI)X@Y7g!YsgJ39ao?xz zQ$^e#R`;t1aNn;Q>Or;lZM!t3n(867548iTr5;xMQF}y9sRL+ru=Nd@7jy)?yMk%L zTeC}hf*C;hh|K$tI%ptQ(*|nQRv%Y~Fv`bOM?I<@L+y}yTs?vD9#x-EPvZWVdP+Tw z`{U{v^(^jBsOQvS+&`f{sgB_Oq|V3)C&pJS{+ZI4%LYS>XQa)6{%VE zBIbQcb=6DiWz?Pyo(UXvdd>NwqYnkn;u=P2si0m}uQg6IPnJ$%H7=-&Xg7*zf0lZudni@Yk%;i|VGjq~1iI=hbIa8Dkx5 zO{mLeR8=6<jX6ZL9TZ?`IX>3s*E zV)sV9_5NAZmUrEA>5cvSpMUm}T6u2jz|{UXD$~oyrb};5RXIlQ$4>R&NBTM?o`aRoklGx*AX7wF+vLZX@cw`9Yf`!vYG+&dHyLQg6d^)#h9Lcqh{pTo0hK1T5Eq(=B_^ zQT8?GyyaPu3l_CEVNrMk*5ne?<-Nxjg6g%fSg#c;#jEw}L95t9@2zRAe(YD4@~Un>qE%t zalGG$D?w*FR>`yFZ540RA5l7rD|{M7U{N4K7y>1*3peoeUgate^^D3WA9p_ya@j=4 z<RiuVN@oH04+nYd7% zt>5f+&YL}&O*UTa)Z6jcz)p^H<#N4MkILn#Ozee0qbB4qi#>^X;|w;gt_;(rh);)b zg#s{^dHMc39hRBi3{^SR=)`-vyP<0ca*@5}gp-jYOMhaiuwt#dw{Q@^%(r8&d)Vub zrL5e!2tq7o)_t6FkmVLONt9j8t@|X&Et~~1ypcFx$I%5lYE=U;zevY9?AI$xQ4q$N zTB92-#3LtfR)Y>1Z|oax5NB@adK74GWPKkB?2!9$i|w1kM3};BE_%qFV%d|nV;4XQ zANzj!-aC>*hEHkXqGx&__Tb^>&K3KF_2&4h0}5Cx&MhqLTmFS~ac#|Mr(6S6hI}lH zJ>G`Ei}Ny*G&qJX$x`L*ZAMv9ECGstfvI zf@}-O!%$|+Wfe5a<&y+a7)L_J<>DQ|Ou7uf$W0|&gI&sk40F9cMSgaDU}9VH3&_-2vk^X zwslaf>2@<=zGTRiR_`HS#1Gs;)kT$QG?t3>W~V_lBbq4|kA=msTU|JaJ`h8-`pxNX zr%2I5sniOpK^Q{)!JINq*lq^JYF$^mO>>098F`-`9U{+bW7Q!b%Y6rhtDc-*!_`uC zMntnL&1-0rs2j^W`nl%jY>UTL=A-{=uPN*Io#cjK*Ww%)XN@x|b@@o2f6$f9!j zb$stlziVjvv{8yNXHS{Mvv@ENK-gGoE*J(Cpb>rViZD^IL`TmM!ga_~vPh|WratA& z#TjTY>d~pp2H5%u3>xS7o?IaISnKf`FRU*Iv0WR&M?Z-^mvALI%{X-$&jTx5o*ckP zW=qd3S1uI-vv?T51ymJW_JF#OYD*IWJJdO{!$c%d{W)s*4mAa+KUDNGa|Zs(l}4b+ zyk_U8ygm%cunj*ld|gw$8b;|kyt|4^lxYh*JqNCC^cmkC+9yPdlMP@-%~keE1C{R! zvu6{2Kf8HpNyX%#nyK){V)Y6KR%QKhtcRQT;Wa> zgA_1y!14~Bm)@iUbVyhDG)DPAI_xwnZ1(FdD7xu7Q}oX!*!HQpz%vYjYs3>v+_#CT z#{}16FA5rs55@C&!1cqphE{r~$nhZzd(+KL<@KZJqaS1OIEt83tX(aag{SCG@I8-( z=0?(_rRGF^+iZi~ljokrC0Yayj+1loH=4`m#)KcI^yFqv`5g&M1)*o%+3^Uq7F^8` z5^j@C9p?@=D$OgZa^wq~4VR@)pcoiGPsc{Y?4I1A7O+AgXeF2+xX9YlV1sn2LD(8ZN;q z9ch5YkhAqvmsLAqA%m*R#6_@7GRw$Y%-nM9-po^e?9)_D6j)&T~egFDfps^oa2k8Jf~+=@a0)SHR{X zm((_248^_p9x4uHIEGaFMhIU@D{MpKG-j}|YtLXzaV0=#Z)Ke}oW6&}kQOq|p%SkI z7VleVlBnO5b})2b!S00Ad;c9GwOsynr`9cnHsbGzhWm ze{max7YQLxFn_$Ki%+g^`0JXZcY%{Tk-G*@$Sr5pupMVkQ^$nv@*r+;#+a=zsHiZD zXAEwv%=Jp6dz;}mF3gICNz^WP>wk^@A&GCITsPx@%J2> zBM*$nU4EQjdP*{#kv+cQ#2y7zocRDzC1d{sN5C~Wb_OqG>+DPkR~!AMI7C5SSuUr1i8p52i6W<80!}8a|v`%XCy2CPw`-(Eo(ysd+4ZwF=%0K$_~D)U}qz zsT~kb(W9OQoD_D69+i9*ZJN4s@-@+>jW(I!VsvVK1Y_z?qJXaD7*ke^dgDIRm-%^! z!}KE|t_b}vXccZpVL_Q5$De~8>4~c4+xiOLr~8PcPY(-aHwmv`YH1(_?gHZIMc zo~dvMEo_B-pbrsrSp;uxR+JUOOnQkOfVvRhg~MkU=526Ex6~l%{~aAe3P39ZXq|#L zX={b2|3z3yihfvil`n?qI|!?xa29)R7}lU4R_@6RF4@vt3QC~V1v>%yfp&1XK7Op{ zUWIMmtcMUbwffbr4iw$W^(gFfyN1PM=Z~K{mAG6rM+J@V#?9bhZ)SbNyKV#*xB9>Y zJBb6=-|}@0Wf}n>-07Y;iU+eNWEZ$nH#@>xfev@g(Fa$&6^D1@NS5fp;T6{?PKmL& zAtmQ$!5(P9!cFE(}g?R!Q} zussjfvZHBirg##^6wk|eNcTR>;8nNvbQ1a4%avQR!@Y7ML|0gWBV9is&#pv8T){V| zKgD-Rgk)Yhh>!@C*dFWc;+%-I$(Un8vI|VI(T%+JN~5AK7=F}8ov{H%HM~oAmuqcZ z4L}dAgKDC3m@%eFj9r+Dg30$l45wgwSq4SCjOZW>`1b#UEOH_@$ig!52#x&WPqd16fACx1njqg>zk49nBz#5ygJ8IR=r{XVEJl zRuraOZ0`C02?9@j1O%W$5(8N|YC}d9T|^Cvl)vdJX_^a-|7*aZSq=g&8ma+YH;Bm) zx##gNybWsMsQBXIO1aB^JbYg^NS`V%wgyk=hpF;nN-S>xWDJZ{clm(3QORQ0yL{OUv0s$oB8+luR&{o7Pc==Vch zlae<<#)vLI&Ms6K;lUTex|hWuPKevvf#|BS+YGM`p%ahM;^f#e_)iltDgwf=9C(0n zadf9%1^ol^7W#;{`CIWNzIEvvtQ=TUh^B2**0npw##=Ax0s{Q4-f4w!)To^#1r^;fe=nBiX|&gV1B zLg4dObFD%&vR>djn6bHNY$dmn#e%v9lBq3o-?gV>`$lYEnT3M56=V|s#C&X5mj4p@ zBteV0C=^JDDFrv{VZ=vTvl1bKzzVyaPFqKTI#|3CR4d&O;%lK26>qe=4QQsV>+Qz% z!1TswA#xvzm#gj0(&gzk@-`|AOUdv>_(?Gk!%ZB1rg#R;CAq-N)`ED{%}S$q`NrjG zdg?HyLaeH@1h_iLXsJgGZq;P=hr{9x0*8 z<>^jE!#GDH0E{G@ikewIcr0o+>(!#P2#f6&MrYngF$5Mt@kTvbNI{tq!*Y2GB2*RW zH7&i6!{Vwsc4bEgh^!G% zj?zJ<5|46*#5VW}&mgToi)u3dz+z14GHGVq-s$FGMEcMc<)RvH^zb1~@oZFDq7oU=U9KMU9W4jvYI965!~lOz%eLOzfUS7>+yo)>RDgLlXi zO(R2Dcr*^1$dK__L^-q=VXHN`?}fZQZ_GS`HlHW3pFtUbLZ{y=y-r7$Q z0VS20+%nvuLUh_>l$o1EnTbXMhbF;?fnW^kJLw|W%Xjrp*%yIMy%=b_vD)0cVlCKn zGVtar9gmce_yq!#%m3Cl)sDfbk`@C8BgK#;0)BMeKo3y%dsyA%Kw!?Fz*pQz&}73S z;qGR&94&Q%c!V`^fW}UAWe9)fW0l6c7!OIsUpy(Rzgm3cWor~PJ&FI#Itf!I%=Oul85GlEG1!5FfA%UuU1!!-g z2gZ3QP4$kn%z%Ks@Xjw{h=F~b5_ccIBuR-as`yBCoQUZ7}L{Y^hKfX(W zr4Gmxi-tvun!ap9A?b)5rv?*XgLpf%M~Yr3j{%}#yNC-6&jZ3MnERk^w9+jhQV2d-?bP0RisNUW=Q#VcnKA@+Fc5BHKxI1@}9{w1@BL%gyTt3NMkOx>0wZbNmebdX%zbDe~3qnToF zG?*o&+uf@R&>*p6E6s{zG8L0w1xjN*47>2HLiJ^aD?)saKZeE<;42Qpp1QUlXMV}zd;bFvEp&N8BOO;UnIT`UqXs@0O>rMn#{)dORpJ6%Ky zDbc#Ulni135)Jo8MXMwwtA_~l*%1rIxl6Y#4+&Rv8&`8LS2Oo6=u4hzsQRwWBnI31 zY%htWr(wh+0(}`^Vpux_GxEyk9mBid{h52>d@Sf3K=NKUw5qZxe_VrN1dwCItq@suq3yI6zGwwT*x z(WaCJYR*W+7W+H{tN90221SDw>w~rWOl=hQPKr45p;@XnfYd~5NU28>QS)0{}8nlF}~&~ z$8m|WWn5V%9}fBC;E9G+)6|3lLGS*C_fk9@eEGV}X^K#gYLkI!vVlfuba4Yx{mtP? z$Vr7f51_IH_1L5gfrm02xW}A9{+Ek(0}9T`kwZ z@8d$kd*sQiI2Swi_%$G5h%vWp|4H3ApUeBq{|b?DMO7h}Vdo8g#3w902?BrSw{X*c z!s1U^2-9%&AG5ykNnqG@r=htt=~0>(*MEl2Dcw<*t$iGKX+-YOqYKZU9un*ur-eKG z2FJ$z`x)@l994$dDAFUd^brO;|3L%(P;WpGQ&5rV*#+9}TzWw($G?F$_#ZMlLc2NL zMQJ|TMn8rnd=~$8B>CS0r#QdRY6og@_6GiE7ZgHS!ngpNGKBjHdJtsK6Ks%!*%{%X zNd>y1qmXW%l6&FQTxrXRle5QOJw0DOe&+P6ugsl~vy3Og%c6gtlh8LS;U^PirLr&o zS3xqwW50c65urB89*ncyR-G=~ctoOiw4976Aog$SO6zJ+ z%F9i@NIsuF&8f)$;?Yy|phaRIn_RFteml$J9E*7twCRlxiY{)+JwfURRY9a5a|#o1 zyuy!)MZkgw-^3pmSgW((_A)M=4r^qZ`b#XnfP#@H@hGkF4W*w5EfE*OL`7bgMwvX7 zs8uGC@l`hcEf(KoK^7(lL;nhEzl@@EyLJqvqcomGJ&lGCmI_HO74?Pw{{$v`TMlOK zFq~ufF9Ju%{KLOOk$A1ZJqs@UR<`HnT_pOCL;2CAMR`b(boxtTqYjf}?n@BvO3& z+)LXcsLqYttt*|0_12e;8e} z-|xF5Ey)h0d+xdCb-(+a@BN)~Oc(JY->mIZsdY>Dlv~WHba8*vRUT?%#r-Oy#%~+NnfDqht0rz6 zYQjITWfy1FQ8lTiZkxq}YFh2Xh(ju;_Tzq7&8P#oAHj@Sbr3TS%8ZB9W9qOvf*B91 zht$Iu@ra+*Kb7yu7xU^7l}Fp7%~@$VT0AQE$BK`sN8=u4T`>xemtO^9ygYuDdbP4X zUkZKQ=u}J9M!PP}AG`18N&C`THOMzws#Ev#l~yw>SDQhev;2mSr?A?>^GZwS!!Zd%^=i102Po}&x#FvMwI&w62VJ?T@~tK&#&5yoa*%KOzVg+4{4J*{t@ehl zuC9fr^2aKL{KHPSPDYb>V%P}%gt546mGQr z$iDpQ$tYP3%3-(>jkVf-6Qi_WZbTmL)pn`e462b!be8IVGn!iU!_u-JgeAXOX{l;+ zHL_p6v`{c3$FHolaL)=ZFWjv7ZK5l(n&Dk@JTkp*YW(m=oaRhpwi+dI3ykcx* zdM3wgT7was|0_F3^sF$k?gqEQBx*qzes#%jw6C_S?c=g^y?(rYZ7nQs zJiT&N7;;eVWXt*XMwHnJ>ciZpJPO0IOxK(?Ei;S1B<>lxyC_}LG4(?jQ{lkjZyc2~ zxPot>@D0dC12XaLDy=+77F&&}45Wyo##I*ggql#3xF^+=n#MilyK0}x-Nx1y)2Q!P zGg9|ZKcHr%KBf+;Ll~P8X=N102hu7#kWdqlM@P{=33>K7?o(<`J%RhQdYd|i`#x1r zPvV~Q_Xl6|bH$mD%i>1EL7^~O<-^|B~4y(|dVLTwx*%#mT3?U`hN9x#mOFAmy29Zo2F%Y4lY zCwmt9&2Wn2FmtNM`O`9vFzi!&&aHwGOZ&r_{>(O*5%mMOW);8Tpp=IcTMtY9h}0hn zAMP17Z_CWE=MibkD+7#_ScnYak?zA)$dvLjWH}`EfT18kDRisaR~HM9M(LGmyBZtsO$r$b^GvMO& zCKO0y^Hp~F`fB7*y+jExum%|QGNmTKOQR^oW8IZ%vl^^{)zgjg%~Jf@6rlEjgD6w! zXpM&w;nqpMI9(0E@=8IxcqLh}UTyk?iO323`UKkAhjv~` zb8<8y2^rDN?O>_-;VVXZfzs5%B@8r;iZBC+s&8(CpL!%IYhkHi>0d%;Gy!BOUzgeg zHZ7R?EZX;eO1cE)1w55XSJ4{~uLhuU&F=o)&JNlL&Tg=PqDL410lv ztq=m`H2{m!*)rQllyw+XyG7I2URcE({C@Jh=H3<(`WJDFY}kDIU917xRyh>jeK5!n zE|sv2p)u83N$A+_#7=GyoFtIr`lKU(jjj z52B{0P`m|T(dk-`vcO_gE>ETNWag5Oyq2arWM zTSMFmS}CIhw|a>+k%dI?TflBZAouP8n}I>I8>#3YK}T_sz$JU%M1@GzHA1J%1IDHa zg=@_iqIj)`?mgRVA3WRWckpZvo}G0^U+tNj36+3Z;J{3N~S2VtqP2r&NCK9VgYPQPItgs?w;*R*;paIO#*ICu8wshEXc;;Zvy~N`V+* zu?A6Mt<}*%IkJ|hFu#@ z-m9g*0M(ezh`VSe2Cn56#d+H$Gt)KCjN2!}g)on)E9C1m+Nz)7;)G*?N8z@@$%j@X8fZjyl#Jv&E2ge_Nt z9a;n7k)?oR5+|+3@1Ql6!8*+q)LgAl!fvfOoY!0oVJF5j+gh2jF4yv4i`x1dGS-2F z8SBGdt-)HYc{yVnWDk+(93X^PXUjZos6;>8bGA*q7w^;G>skE?Xs*d^jE2lN^$!Ov zQ-catunl3677oWYmXPFV%VW#xo>e9m znCJkfUIiIbT15^xYb~-XtsqtkPOVjKM#*v;&biVh4AC?XVna@N`J;RkL+&}&-o`>q zIvRXYQi~@)V0Hnkm=>#fxf%vVkLGl2!0Kg;M<1&W-!LXXa^o+H~#?fu z6o_0xOhyBOf&nohbxS{v?X*`x;>y{yn%@Hph_=w5M0;Y>fsBQl1;5|ur?$xoiO@xx zxdk#jX!H`Z#+J32gk$C)67X8j?x#af2n99BW1}`kA_iHa4)=>CSt79sC$2U|0@J_C z8lLaXm3M8rc&m#yl5IHB4ZhD>FO4_-t2lmRoYQl6yf4*DlPTGvQeY&QL7OgJ#oG9~ zEd)-taUAX*+rTz8ICjc?-4SDHq7RlC7^vx(kYS}t6bJSfWPQ0_3aVZI;*!v}&I7wc zk{&q(h~d-=)5Robz&l%{qp$e!k-xD095Xi&kVDc{s}#||A@yJ!PhN@(gd zE#hIT5MFYqb1*6u_sk-i#R(_%J5ZC!#dsK~*C@qcq2IpGJb*8|?n@WLk-;PiLs&lvv^hZIF>AN0H5$JQ zT_clV2J^wKK$h^u!226IU6$79kDZc%-oM6%Jq~QL(^d!={1jaQH^RV{cBgl4T|8hU zY^dwGYa(n2LhO7>Gy|p_u!%?u^n)Eo{g&V>i8K}&Oric33O*V8hIcVy^YA&X)0- z`Kr;Je1&Z(6=N5x$!A#uY2ga1M@|zFWPK9v*8IR|{7TqrUjieFsjowJoM#cB7!ru3 zukYCg-9h)8xB_A{wizud1JDO8#|)^WJGpaL_};?!f_?f^FbbkEpm=pHYy|$iIXB_jZqiL= zD4kLR| za5f}IqL$=VD{I?oKcnovyG`|I>tdMJ3n8M8a6aOZV>{~cEC-fRVm+y^?^-b({2Jbv z>5r@AwyD3sHB@S_Mm9_+7lHNfgo*xyN@Kopl|>*Z8@tk?AF8XhU+HpUXPqgLm!v%Kp9{pfMT1r|X^Vo;>eYs>;vbSSyG5 zh99oA)G!1Bt0vzruOgR$=)P`sR@aa|x*5(F6PM4v_rl_W=)=fCNZ|to3!&*wW4V~{ z8|6w+v|GW+Zccx6cHD^Ue!pc*a-Y{5b`s63=|M$B_7HMW<1&} zA-+GTyNr|4aAQUXfyjX2ohY?dX3j_Jk8wWoJB_vkKvRu%enT6P(0VKIqhzNE6}nzX zA(%-4!1y3OR1!(Ww7jiUX(;_^wp%MILPQhl7HqhK_(}IsLIzKRPJ^fLY(S?@L(9&9 zt{Ha8K-0$8EQA0A0Yrjj9$}BAzliY_o3rpE&5!7Q2J6K};HEvKe0nc^$*XQ#H0dbz zVEZ$*<08eAQ0756)}WtT3#}*j#Z9{L;2n_1V>p3a~A7u>2WKMzp z){{X`jq|Q=v9)IfpAKPs!LS4O)Y9;sV8+!rFZ;T)nF5ujY8mvp8%J5|!xMs^;i`#k z_!xQ(o4b zIx-iL%}O8w4j%b92ihR=D5ZVLt`_!zXgkY*tpd(LETUQo^%jQd+Z+qerj2YY=JTdM z!45GmsVk$zWu`MD=kle?7c@Nwd4c|b%#`eU z5^guj)ez><=Qz+NrAvhTceorqpQ490WLcShEqdhd(n`I&8boFVQQtv|bPp@&Ph#Rc z8Q~dJ3_#_b9CNZ?gD0ipX5q zyFtH>=8tlNa;O-R$>7#_*qTGwghQ6*h|vbvc;NK{E{TN!;Tgn*1`(`2Ofn)U4perZ zyTU^Y8^8jRw)qbIY$CK^l=fhJU7-k-M*=*Uzt%>-FU_Lh=hRt^@}pWH1ke zG4u8DH_GSjHhlGK7+2@V&~r9OS*EmA_&EI0B0hsltddb$HUn{(khCm>BvPV|a#b4l z1eEp|?n(Ki@hEvgRl}BESi0-Xhd09t%^?1Gw{Qt!s0G9}MP?lqswv4(i(!`%f@VSK4+VsS5I9tT$oW~UrvHou*-(F*#h|$NJ$JROP}e%6uWi?{F9UbQ^AUoAHH(xflX+lzWXK$=kD{J|=Ab-!cfSvKg)3JeJU9Td{BUsr2>>?#& zu}CvPbp0?TWv}}i`UYEN_-?F49*-8pJJBQZ7{Q{$L_Zk5GDwJ8+k*y2VrOcA%zJZ2 zHY$-$(JScuJyal?jJm`mMKm!mW9j+Ot~sKmX$8_(6}{MW6ol8tdwNza1%C^uUO`}; zLQ6TX+l=Ok^$NkIOvD@4!ZgA-Kr-`Q(4;4!Aw9T1ZU{ZFg4@~q`t2n?atiacnX_T7}KIC z{sI%@B}TgvIdTF>+=p#;f0e~JiYWEc6;Ve8HzslsRI-lj6g8jz8VVeMV6G6SaQw); z&)iCL_evD0pW+6R`3!6p^$UD0NC6(%hyxmv5NqAZ!6uHTjrMStz4bp>X0(T98>bHF za3XSH_7T_JHUrd@Em3-_X7Nlw4QJL~w_w-Xn@;zuV2(wV#NLr5Y?a!^eC)F;ElH{# zFjfjm$cDEdVK{`tV#hSu_h|cssT$+SP&o{^!Il!`gZE_hH}CcJcpC1T+|O_V6yq_Z z*M;rInDV9z#zXinUJuT%+n-YK764HS-vHJH1k)p>M$t4D(?o2*FrLv(5m7CDoUGf{ z{z~;GBynd2_inlqt{i{Q@u0fewZ^?}LLT)WVOC`6<-)#LpTRm%VvFn7(G$xq;nFww z_!SnUmMFQRXvf6rP3#q?%>Xe^|1_9I(|^UW6o8QvTRhMQDoQG3bdU`f6_}1miB^of zU4KD_i=9p#sQ-k|X)XsR0a{ih!ycjF@RPqxYC4J0pe86rc?=m|#n9E?#Y$g_=Wf#b z#VQCW<88UqVgwj8#Zd@QDdO0e(gd7nL?-V^+L}i?R2Bw@s+&ZH~k0pEHAVoD-ZA zTun0I+{c@U0nS$Y{ssSC^wPoSnm|&iIhRr_dLrI?Zbx zC{l2#jY0aK(71z?NJY_jX)s8n<=>E=vS>F*x1euIN#uhcA#0Ve#{6lVj40QG=jM0K z1HYB^4J7ja7E|Hgyi6CTn;t~~BJ&0U@ARDES#(&jNE`(3?&ur&H z#UxPzmr1nLzi_fs)^LIxiG5I6>3?H!kBJ5I?hvQnCDJcqgb0;1?F?EMyoi1a!h=>v zY!i zfL?=j0y?wd!P<9C2a5j>Fg|iGymT>E$!26#*7klzt`y=#ZNTGbIH6VwTR6m1`Con# z#SXPD0o4DF`Uof+541H!D18`}P@>vQcxD0KGBE_lKz6-XIrydxUEFm&{aCmX@_3J#?uphPNb#Z!hVVO>0500 zI1BP7lszO{vlXSlOpPjHe(A6>*oer+0>xzDgV=7wy!v;X_jwld1vwVI+_YkP>4ht2 z&o7?6w4h&Nzt{~4NFI1rq(jZU6fYXClx!#s0I>>+87AAX5G~w5|B&sw`Brvs9DZGJ z44rffz;@8^v?rKq*@h($G5olEf$h#@=-%) zrPY9e6URi!B0`TbwkYpo=a))7jslQ!BG_0s{w`mFv!cVZ=Ybg1`X4y9$zp-UL!6Mr z0cwa{iKt6>Q9>%>){Ap2HiXEL7+?RvnWS3%V;29-;vQB;CQ0O;juQ{h5iCiIQ)tD1 oPl56?Hu1znxnsMz$zL_f-VyhNJK?4#Kj6L7O<}aD-OJvr6>Nzj@9X*G-a_Tk4vkZ52?vQc~O;B zyx{|<&948z>Nnattz@=8FAklLvbmKeFSPHsnl60rI9K()AGj*bv^09R_JK)Vorr8+ zdttTv4eS^j`0Kl;52rsktT%l=dG*t$_a98Ztg2^eold_kv(!vq>RC0d^6Fk*xH>iF zo;ljD)6@IA)6C@A;Yvyx(lKJXU7h-yaz8DU!F#X%NuN-q>wt}T$RakxXMj(@&OTln z$M$=f8K*2*%cH3HvYJo+(S zvLCxauu07QC@=ClPmRnArHk6%bn_jjkLIYaOmSd|=RWKrl5uGiy4JIj+hlt$vxT`6 zA5w)OB4yK6S+ckrC;(vz*$5xb2B@EHt;4dO@-HGGW)Xc`%6@~&9^!HG5Q)o{>;lf& zGx+81lrO|0K$M8Y_;wuzb{kIuPkb3Py(ZXfNqICzeE1Tr7xV^-i6we^Hi$#Np^N!U z+qBk1D3jO3HD_;QfW1S4=Hi2cGB4t=gDD_Bcy8Z#k*gEr9%k50iX|4Tp>eIlQzMm2OAL6$ktiDJl-|1>n*8i3B(W9=PF9=E3 I@|O+8Kk5BYtpET3 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/click/__pycache__/_unicodefun.cpython-37.pyc b/Lib/site-packages/click/__pycache__/_unicodefun.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ab3d88defdd93023c618aee5d12396c9b6c27ed GIT binary patch literal 3205 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/click/__pycache__/exceptions.cpython-37.pyc b/Lib/site-packages/click/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8213f2138ee310296ae3f51c9d29c6ec7fa22fde GIT binary patch literal 7731 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/click/__pycache__/formatting.cpython-37.pyc b/Lib/site-packages/click/__pycache__/formatting.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be33cc1ab42a9e5d14e4a63b19301d81b21f8f02 GIT binary patch literal 8545 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 rSlTk=N%PIU6@5gm>W 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 YxcZ=s^U9m$`N}c;K36%D&s9$S4|8c!v;Y7A literal 0 HcmV?d00001 diff --git a/Lib/site-packages/click/__pycache__/testing.cpython-37.pyc b/Lib/site-packages/click/__pycache__/testing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5986befa22b1533b06c7a009597e625edaae5dcd GIT binary patch literal 10236 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/click/__pycache__/utils.cpython-37.pyc b/Lib/site-packages/click/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e675f6d7ad58c1934b93f12b56d461778ea4a91 GIT binary patch literal 14098 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/click/_bashcomplete.py b/Lib/site-packages/click/_bashcomplete.py new file mode 100644 index 0000000..d9d26d2 --- /dev/null +++ b/Lib/site-packages/click/_bashcomplete.py @@ -0,0 +1,83 @@ +import os +import re +from .utils import echo +from .parser import split_arg_string +from .core import MultiCommand, Option + + +COMPLETION_SCRIPT = ''' +%(complete_func)s() { + COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + %(autocomplete_var)s=complete $1 ) ) + return 0 +} + +complete -F %(complete_func)s -o default %(script_names)s +''' + +_invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]') + + +def get_completion_script(prog_name, complete_var): + cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_')) + return (COMPLETION_SCRIPT % { + 'complete_func': '_%s_completion' % cf_name, + 'script_names': prog_name, + 'autocomplete_var': complete_var, + }).strip() + ';' + + +def resolve_ctx(cli, prog_name, args): + ctx = cli.make_context(prog_name, args, resilient_parsing=True) + while ctx.protected_args + ctx.args and isinstance(ctx.command, MultiCommand): + a = ctx.protected_args + ctx.args + cmd = ctx.command.get_command(ctx, a[0]) + if cmd is None: + return None + ctx = cmd.make_context(a[0], a[1:], parent=ctx, resilient_parsing=True) + return ctx + + +def get_choices(cli, prog_name, args, incomplete): + ctx = resolve_ctx(cli, prog_name, args) + if ctx is None: + return + + choices = [] + if incomplete and not incomplete[:1].isalnum(): + for param in ctx.command.params: + if not isinstance(param, Option): + continue + choices.extend(param.opts) + choices.extend(param.secondary_opts) + elif isinstance(ctx.command, MultiCommand): + choices.extend(ctx.command.list_commands(ctx)) + + for item in choices: + if item.startswith(incomplete): + yield item + + +def do_complete(cli, prog_name): + cwords = split_arg_string(os.environ['COMP_WORDS']) + cword = int(os.environ['COMP_CWORD']) + args = cwords[1:cword] + try: + incomplete = cwords[cword] + except IndexError: + incomplete = '' + + for item in get_choices(cli, prog_name, args, incomplete): + echo(item) + + return True + + +def bashcomplete(cli, prog_name, complete_var, complete_instr): + if complete_instr == 'source': + echo(get_completion_script(prog_name, complete_var)) + return True + elif complete_instr == 'complete': + return do_complete(cli, prog_name) + return False diff --git a/Lib/site-packages/click/_compat.py b/Lib/site-packages/click/_compat.py new file mode 100644 index 0000000..2b43412 --- /dev/null +++ b/Lib/site-packages/click/_compat.py @@ -0,0 +1,648 @@ +import re +import io +import os +import sys +import codecs +from weakref import WeakKeyDictionary + + +PY2 = sys.version_info[0] == 2 +WIN = sys.platform.startswith('win') +DEFAULT_COLUMNS = 80 + + +_ansi_re = re.compile('\033\[((?:\d|;)*)([a-zA-Z])') + + +def get_filesystem_encoding(): + return sys.getfilesystemencoding() or sys.getdefaultencoding() + + +def _make_text_stream(stream, encoding, errors): + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = 'replace' + return _NonClosingTextIOWrapper(stream, encoding, errors, + line_buffering=True) + + +def is_ascii_encoding(encoding): + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == 'ascii' + except LookupError: + return False + + +def get_best_encoding(stream): + """Returns the default stream encoding if not found.""" + rv = getattr(stream, 'encoding', None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return 'utf-8' + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + + def __init__(self, stream, encoding, errors, **extra): + self._stream = stream = _FixupStream(stream) + io.TextIOWrapper.__init__(self, stream, encoding, errors, **extra) + + # The io module is a place where the Python 3 text behavior + # was forced upon Python 2, so we need to unbreak + # it to look like Python 2. + if PY2: + def write(self, x): + if isinstance(x, str) or is_bytes(x): + try: + self.flush() + except Exception: + pass + return self.buffer.write(str(x)) + return io.TextIOWrapper.write(self, x) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def __del__(self): + try: + self.detach() + except Exception: + pass + + def isatty(self): + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream(object): + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + """ + + def __init__(self, stream): + self._stream = stream + + def __getattr__(self, name): + return getattr(self._stream, name) + + def read1(self, size): + f = getattr(self._stream, 'read1', None) + if f is not None: + return f(size) + # We only dispatch to readline instead of read in Python 2 as we + # do not want cause problems with the different implementation + # of line buffering. + if PY2: + return self._stream.readline(size) + return self._stream.read(size) + + def readable(self): + x = getattr(self._stream, 'readable', None) + if x is not None: + return x() + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self): + x = getattr(self._stream, 'writable', None) + if x is not None: + return x() + try: + self._stream.write('') + except Exception: + try: + self._stream.write(b'') + except Exception: + return False + return True + + def seekable(self): + x = getattr(self._stream, 'seekable', None) + if x is not None: + return x() + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +if PY2: + text_type = unicode + bytes = str + raw_input = raw_input + string_types = (str, unicode) + iteritems = lambda x: x.iteritems() + range_type = xrange + + def is_bytes(x): + return isinstance(x, (buffer, bytearray)) + + _identifier_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') + + # For Windows, we need to force stdout/stdin/stderr to binary if it's + # fetched for that. This obviously is not the most correct way to do + # it as it changes global state. Unfortunately, there does not seem to + # be a clear better way to do it as just reopening the file in binary + # mode does not change anything. + # + # An option would be to do what Python 3 does and to open the file as + # binary only, patch it back to the system, and then use a wrapper + # stream that converts newlines. It's not quite clear what's the + # correct option here. + # + # This code also lives in _winconsole for the fallback to the console + # emulation stream. + # + # There are also Windows environments where the `msvcrt` module is not + # available (which is why we use try-catch instead of the WIN variable + # here), such as the Google App Engine development server on Windows. In + # those cases there is just nothing we can do. + try: + import msvcrt + except ImportError: + set_binary_mode = lambda x: x + else: + def set_binary_mode(f): + try: + fileno = f.fileno() + except Exception: + pass + else: + msvcrt.setmode(fileno, os.O_BINARY) + return f + + def isidentifier(x): + return _identifier_re.search(x) is not None + + def get_binary_stdin(): + return set_binary_mode(sys.stdin) + + def get_binary_stdout(): + return set_binary_mode(sys.stdout) + + def get_binary_stderr(): + return set_binary_mode(sys.stderr) + + def get_text_stdin(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stdin, encoding, errors) + + def get_text_stdout(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stdout, encoding, errors) + + def get_text_stderr(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stderr, encoding, errors) + + def filename_to_ui(value): + if isinstance(value, bytes): + value = value.decode(get_filesystem_encoding(), 'replace') + return value +else: + import io + text_type = str + raw_input = input + string_types = (str,) + range_type = range + isidentifier = lambda x: x.isidentifier() + iteritems = lambda x: iter(x.items()) + + def is_bytes(x): + return isinstance(x, (bytes, memoryview, bytearray)) + + def _is_binary_reader(stream, default=False): + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + def _is_binary_writer(stream, default=False): + try: + stream.write(b'') + except Exception: + try: + stream.write('') + return False + except Exception: + pass + return default + return True + + def _find_binary_reader(stream): + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return stream + + buf = getattr(stream, 'buffer', None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return buf + + def _find_binary_writer(stream): + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detatching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return stream + + buf = getattr(stream, 'buffer', None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return buf + + def _stream_is_misconfigured(stream): + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, 'encoding', None) or 'ascii') + + def _is_compatible_text_stream(stream, encoding, errors): + stream_encoding = getattr(stream, 'encoding', None) + stream_errors = getattr(stream, 'errors', None) + + # Perfect match. + if stream_encoding == encoding and stream_errors == errors: + return True + + # Otherwise, it's only a compatible stream if we did not ask for + # an encoding. + if encoding is None: + return stream_encoding is not None + + return False + + def _force_correct_text_reader(text_reader, encoding, errors): + if _is_binary_reader(text_reader, False): + binary_reader = text_reader + else: + # If there is no target encoding set, we need to verify that the + # reader is not actually misconfigured. + if encoding is None and not _stream_is_misconfigured(text_reader): + return text_reader + + if _is_compatible_text_stream(text_reader, encoding, errors): + return text_reader + + # If the reader has no encoding, we try to find the underlying + # binary reader for it. If that fails because the environment is + # misconfigured, we silently go with the same reader because this + # is too common to happen. In that case, mojibake is better than + # exceptions. + binary_reader = _find_binary_reader(text_reader) + if binary_reader is None: + return text_reader + + # At this point, we default the errors to replace instead of strict + # because nobody handles those errors anyways and at this point + # we're so fundamentally fucked that nothing can repair it. + if errors is None: + errors = 'replace' + return _make_text_stream(binary_reader, encoding, errors) + + def _force_correct_text_writer(text_writer, encoding, errors): + if _is_binary_writer(text_writer, False): + binary_writer = text_writer + else: + # If there is no target encoding set, we need to verify that the + # writer is not actually misconfigured. + if encoding is None and not _stream_is_misconfigured(text_writer): + return text_writer + + if _is_compatible_text_stream(text_writer, encoding, errors): + return text_writer + + # If the writer has no encoding, we try to find the underlying + # binary writer for it. If that fails because the environment is + # misconfigured, we silently go with the same writer because this + # is too common to happen. In that case, mojibake is better than + # exceptions. + binary_writer = _find_binary_writer(text_writer) + if binary_writer is None: + return text_writer + + # At this point, we default the errors to replace instead of strict + # because nobody handles those errors anyways and at this point + # we're so fundamentally fucked that nothing can repair it. + if errors is None: + errors = 'replace' + return _make_text_stream(binary_writer, encoding, errors) + + def get_binary_stdin(): + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError('Was not able to determine binary ' + 'stream for sys.stdin.') + return reader + + def get_binary_stdout(): + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError('Was not able to determine binary ' + 'stream for sys.stdout.') + return writer + + def get_binary_stderr(): + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError('Was not able to determine binary ' + 'stream for sys.stderr.') + return writer + + def get_text_stdin(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors) + + def get_text_stdout(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors) + + def get_text_stderr(encoding=None, errors=None): + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors) + + def filename_to_ui(value): + if isinstance(value, bytes): + value = value.decode(get_filesystem_encoding(), 'replace') + else: + value = value.encode('utf-8', 'surrogateescape') \ + .decode('utf-8', 'replace') + return value + + +def get_streerror(e, default=None): + if hasattr(e, 'strerror'): + msg = e.strerror + else: + if default is not None: + msg = default + else: + msg = str(e) + if isinstance(msg, bytes): + msg = msg.decode('utf-8', 'replace') + return msg + + +def open_stream(filename, mode='r', encoding=None, errors='strict', + atomic=False): + # Standard streams first. These are simple because they don't need + # special handling for the atomic flag. It's entirely ignored. + if filename == '-': + if 'w' in mode: + if 'b' in mode: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if 'b' in mode: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + if encoding is None: + return open(filename, mode), True + return io.open(filename, mode, encoding=encoding, errors=errors), True + + # Some usability stuff for atomic writes + if 'a' in mode: + raise ValueError( + 'Appending to an existing file is not supported, because that ' + 'would involve an expensive `copy`-operation to a temporary ' + 'file. Open the file in normal `w`-mode and copy explicitly ' + 'if that\'s what you\'re after.' + ) + if 'x' in mode: + raise ValueError('Use the `overwrite`-parameter instead.') + if 'w' not in mode: + raise ValueError('Atomic writes only make sense with `w`-mode.') + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import tempfile + fd, tmp_filename = tempfile.mkstemp(dir=os.path.dirname(filename), + prefix='.__atomic-write') + + if encoding is not None: + f = io.open(fd, mode, encoding=encoding, errors=errors) + else: + f = os.fdopen(fd, mode) + + return _AtomicFile(f, tmp_filename, filename), True + + +# Used in a destructor call, needs extra protection from interpreter cleanup. +if hasattr(os, 'replace'): + _replace = os.replace + _can_replace = True +else: + _replace = os.rename + _can_replace = not WIN + + +class _AtomicFile(object): + + def __init__(self, f, tmp_filename, real_filename): + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self): + return self._real_filename + + def close(self, delete=False): + if self.closed: + return + self._f.close() + if not _can_replace: + try: + os.remove(self._real_filename) + except OSError: + pass + _replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name): + return getattr(self._f, name) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + self.close(delete=exc_type is not None) + + def __repr__(self): + return repr(self._f) + + +auto_wrap_for_ansi = None +colorama = None +get_winterm_size = None + + +def strip_ansi(value): + return _ansi_re.sub('', value) + + +def should_strip_ansi(stream=None, color=None): + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) + return not color + + +# If we're on Windows, we provide transparent integration through +# colorama. This will make ANSI colors through the echo function +# work automatically. +if WIN: + # Windows has a smaller terminal + DEFAULT_COLUMNS = 79 + + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding(): + import locale + return locale.getpreferredencoding() + + if PY2: + def raw_input(prompt=''): + sys.stderr.flush() + if prompt: + stdout = _default_text_stdout() + stdout.write(prompt) + stdin = _default_text_stdin() + return stdin.readline().rstrip('\r\n') + + try: + import colorama + except ImportError: + pass + else: + _ansi_stream_wrappers = WeakKeyDictionary() + + def auto_wrap_for_ansi(stream, color=None): + """This function wraps a stream so that calls through colorama + are issued to the win32 console API to recolor on demand. It + also ensures to reset the colors if a write call is interrupted + to not destroy the console afterwards. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + if cached is not None: + return cached + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = ansi_wrapper.stream + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + return rv + + def get_winterm_size(): + win = colorama.win32.GetConsoleScreenBufferInfo( + colorama.win32.STDOUT).srWindow + return win.Right - win.Left, win.Bottom - win.Top +else: + def _get_argv_encoding(): + return getattr(sys.stdin, 'encoding', None) or get_filesystem_encoding() + + _get_windows_console_stream = lambda *x: None + + +def term_len(x): + return len(strip_ansi(x)) + + +def isatty(stream): + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func(src_func, wrapper_func): + cache = WeakKeyDictionary() + def func(): + stream = src_func() + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + return func + + +_default_text_stdin = _make_cached_stream_func( + lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func( + lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func( + lambda: sys.stderr, get_text_stderr) + + +binary_streams = { + 'stdin': get_binary_stdin, + 'stdout': get_binary_stdout, + 'stderr': get_binary_stderr, +} + +text_streams = { + 'stdin': get_text_stdin, + 'stdout': get_text_stdout, + 'stderr': get_text_stderr, +} diff --git a/Lib/site-packages/click/_termui_impl.py b/Lib/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..7cfd3d5 --- /dev/null +++ b/Lib/site-packages/click/_termui_impl.py @@ -0,0 +1,547 @@ +""" + click._termui_impl + ~~~~~~~~~~~~~~~~~~ + + This module contains implementations for the termui module. To keep the + import time of Click down, some infrequently used functionality is placed + in this module and only imported as needed. + + :copyright: (c) 2014 by Armin Ronacher. + :license: BSD, see LICENSE for more details. +""" +import os +import sys +import time +import math +from ._compat import _default_text_stdout, range_type, PY2, isatty, \ + open_stream, strip_ansi, term_len, get_best_encoding, WIN +from .utils import echo +from .exceptions import ClickException + + +if os.name == 'nt': + BEFORE_BAR = '\r' + AFTER_BAR = '\n' +else: + BEFORE_BAR = '\r\033[?25l' + AFTER_BAR = '\033[?25h\n' + + +def _length_hint(obj): + """Returns the length hint of an object.""" + try: + return len(obj) + except (AttributeError, TypeError): + try: + get_hint = type(obj).__length_hint__ + except AttributeError: + return None + try: + hint = get_hint(obj) + except TypeError: + return None + if hint is NotImplemented or \ + not isinstance(hint, (int, long)) or \ + hint < 0: + return None + return hint + + +class ProgressBar(object): + + def __init__(self, iterable, length=None, fill_char='#', empty_char=' ', + bar_template='%(bar)s', info_sep=' ', show_eta=True, + show_percent=None, show_pos=False, item_show_func=None, + label=None, file=None, color=None, width=30): + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label = label or '' + if file is None: + file = _default_text_stdout() + self.file = file + self.color = color + self.width = width + self.autowidth = width == 0 + + if length is None: + length = _length_hint(iterable) + if iterable is None: + if length is None: + raise TypeError('iterable or length is required') + iterable = range_type(length) + self.iter = iter(iterable) + self.length = length + self.length_known = length is not None + self.pos = 0 + self.avg = [] + self.start = self.last_eta = time.time() + self.eta_known = False + self.finished = False + self.max_width = None + self.entered = False + self.current_item = None + self.is_hidden = not isatty(self.file) + self._last_line = None + + def __enter__(self): + self.entered = True + self.render_progress() + return self + + def __exit__(self, exc_type, exc_value, tb): + self.render_finish() + + def __iter__(self): + if not self.entered: + raise RuntimeError('You need to use progress bars in a with block.') + self.render_progress() + return self + + def render_finish(self): + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self): + if self.finished: + return 1.0 + return min(self.pos / (float(self.length) or 1), 1.0) + + @property + def time_per_iteration(self): + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self): + if self.length_known and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self): + if self.eta_known: + t = self.eta + 1 + seconds = t % 60 + t /= 60 + minutes = t % 60 + t /= 60 + hours = t % 24 + t /= 24 + if t > 0: + days = t + return '%dd %02d:%02d:%02d' % (days, hours, minutes, seconds) + else: + return '%02d:%02d:%02d' % (hours, minutes, seconds) + return '' + + def format_pos(self): + pos = str(self.pos) + if self.length_known: + pos += '/%s' % self.length + return pos + + def format_pct(self): + return ('% 4d%%' % int(self.pct * 100))[1:] + + def format_progress_line(self): + show_percent = self.show_percent + + info_bits = [] + if self.length_known: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + if show_percent is None: + show_percent = not self.show_pos + else: + if self.finished: + bar = self.fill_char * self.width + else: + bar = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + bar[int((math.cos(self.pos * self.time_per_iteration) + / 2.0 + 0.5) * self.width)] = self.fill_char + bar = ''.join(bar) + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return (self.bar_template % { + 'label': self.label, + 'bar': bar, + 'info': self.info_sep.join(info_bits) + }).rstrip() + + def render_progress(self): + from .termui import get_terminal_size + nl = False + + if self.is_hidden: + buf = [self.label] + nl = True + else: + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, get_terminal_size()[0] - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(' ' * self.max_width) + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + buf.append(line) + + buf.append(' ' * (clear_width - line_len)) + line = ''.join(buf) + + # Render the line only if it changed. + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=nl) + self.file.flush() + + def make_step(self, n_steps): + self.pos += n_steps + if self.length_known and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + self.avg = self.avg[-6:] + [-(self.start - time.time()) / (self.pos)] + + self.eta_known = self.length_known + + def update(self, n_steps): + self.make_step(n_steps) + self.render_progress() + + def finish(self): + self.eta_known = 0 + self.current_item = None + self.finished = True + + def next(self): + if self.is_hidden: + return next(self.iter) + try: + rv = next(self.iter) + self.current_item = rv + except StopIteration: + self.finish() + self.render_progress() + raise StopIteration() + else: + self.update(1) + return rv + + if not PY2: + __next__ = next + del next + + +def pager(text, color=None): + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, text, color) + pager_cmd = (os.environ.get('PAGER', None) or '').strip() + if pager_cmd: + if WIN: + return _tempfilepager(text, pager_cmd, color) + return _pipepager(text, pager_cmd, color) + if os.environ.get('TERM') in ('dumb', 'emacs'): + return _nullpager(stdout, text, color) + if WIN or sys.platform.startswith('os2'): + return _tempfilepager(text, 'more <', color) + if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0: + return _pipepager(text, 'less', color) + + import tempfile + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0: + return _pipepager(text, 'more', color) + return _nullpager(stdout, text, color) + finally: + os.unlink(filename) + + +def _pipepager(text, cmd, color): + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit('/', 1)[-1].split() + if color is None and cmd_detail[0] == 'less': + less_flags = os.environ.get('LESS', '') + ' '.join(cmd_detail[1:]) + if not less_flags: + env['LESS'] = '-R' + color = True + elif 'r' in less_flags or 'R' in less_flags: + color = True + + if not color: + text = strip_ansi(text) + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + env=env) + encoding = get_best_encoding(c.stdin) + try: + c.stdin.write(text.encode(encoding, 'replace')) + c.stdin.close() + except (IOError, KeyboardInterrupt): + pass + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager(text, cmd, color): + """Page through text by invoking a program on a temporary file.""" + import tempfile + filename = tempfile.mktemp() + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, 'wb')[0] as f: + f.write(text.encode(encoding)) + try: + os.system(cmd + ' "' + filename + '"') + finally: + os.unlink(filename) + + +def _nullpager(stream, text, color): + """Simply print unformatted text. This is the ultimate fallback.""" + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor(object): + + def __init__(self, editor=None, env=None, require_save=True, + extension='.txt'): + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self): + if self.editor is not None: + return self.editor + for key in 'VISUAL', 'EDITOR': + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return 'notepad' + for editor in 'vim', 'nano': + if os.system('which %s >/dev/null 2>&1' % editor) == 0: + return editor + return 'vi' + + def edit_file(self, filename): + import subprocess + editor = self.get_editor() + if self.env: + environ = os.environ.copy() + environ.update(self.env) + else: + environ = None + try: + c = subprocess.Popen('%s "%s"' % (editor, filename), + env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException('%s: Editing failed!' % editor) + except OSError as e: + raise ClickException('%s: Editing failed: %s' % (editor, e)) + + def edit(self, text): + import tempfile + + text = text or '' + if text and not text.endswith('\n'): + text += '\n' + + fd, name = tempfile.mkstemp(prefix='editor-', suffix=self.extension) + try: + if WIN: + encoding = 'utf-8-sig' + text = text.replace('\n', '\r\n') + else: + encoding = 'utf-8' + text = text.encode(encoding) + + f = os.fdopen(fd, 'wb') + f.write(text) + f.close() + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save \ + and os.path.getmtime(name) == timestamp: + return None + + f = open(name, 'rb') + try: + rv = f.read() + finally: + f.close() + return rv.decode('utf-8-sig').replace('\r\n', '\n') + finally: + os.unlink(name) + + +def open_url(url, wait=False, locate=False): + import subprocess + + def _unquote_file(url): + try: + import urllib + except ImportError: + import urllib + if url.startswith('file://'): + url = urllib.unquote(url[7:]) + return url + + if sys.platform == 'darwin': + args = ['open'] + if wait: + args.append('-W') + if locate: + args.append('-R') + args.append(_unquote_file(url)) + null = open('/dev/null', 'w') + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url) + args = 'explorer /select,"%s"' % _unquote_file( + url.replace('"', '')) + else: + args = 'start %s "" "%s"' % ( + wait and '/WAIT' or '', url.replace('"', '')) + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or '.' + else: + url = _unquote_file(url) + c = subprocess.Popen(['xdg-open', url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(('http://', 'https://')) and not locate and not wait: + import webbrowser + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch): + if ch == '\x03': + raise KeyboardInterrupt() + if ch == '\x04': + raise EOFError() + + +if WIN: + import msvcrt + + def getchar(echo): + rv = msvcrt.getch() + if echo: + msvcrt.putchar(rv) + _translate_ch_to_exc(rv) + if PY2: + enc = getattr(sys.stdin, 'encoding', None) + if enc is not None: + rv = rv.decode(enc, 'replace') + else: + rv = rv.decode('cp1252', 'replace') + return rv +else: + import tty + import termios + + def getchar(echo): + if not isatty(sys.stdin): + f = open('/dev/tty') + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + try: + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(fd) + ch = os.read(fd, 32) + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + if f is not None: + f.close() + except termios.error: + pass + _translate_ch_to_exc(ch) + return ch.decode(get_best_encoding(sys.stdin), 'replace') diff --git a/Lib/site-packages/click/_textwrap.py b/Lib/site-packages/click/_textwrap.py new file mode 100644 index 0000000..7e77603 --- /dev/null +++ b/Lib/site-packages/click/_textwrap.py @@ -0,0 +1,38 @@ +import textwrap +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + + def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent): + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text): + rv = [] + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + if idx > 0: + indent = self.subsequent_indent + rv.append(indent + line) + return '\n'.join(rv) diff --git a/Lib/site-packages/click/_unicodefun.py b/Lib/site-packages/click/_unicodefun.py new file mode 100644 index 0000000..9e17a38 --- /dev/null +++ b/Lib/site-packages/click/_unicodefun.py @@ -0,0 +1,118 @@ +import os +import sys +import codecs + +from ._compat import PY2 + + +# If someone wants to vendor click, we want to ensure the +# correct package is discovered. Ideally we could use a +# relative import here but unfortunately Python does not +# support that. +click = sys.modules[__name__.rsplit('.', 1)[0]] + + +def _find_unicode_literals_frame(): + import __future__ + frm = sys._getframe(1) + idx = 1 + while frm is not None: + if frm.f_globals.get('__name__', '').startswith('click.'): + frm = frm.f_back + idx += 1 + elif frm.f_code.co_flags & __future__.unicode_literals.compiler_flag: + return idx + else: + break + return 0 + + +def _check_for_unicode_literals(): + if not __debug__: + return + if not PY2 or click.disable_unicode_literals_warning: + return + bad_frame = _find_unicode_literals_frame() + if bad_frame <= 0: + return + from warnings import warn + warn(Warning('Click detected the use of the unicode_literals ' + '__future__ import. This is heavily discouraged ' + 'because it can introduce subtle bugs in your ' + 'code. You should instead use explicit u"" literals ' + 'for your unicode strings. For more information see ' + 'http://click.pocoo.org/python3/'), + stacklevel=bad_frame) + + +def _verify_python3_env(): + """Ensures that the environment is good for unicode on Python 3.""" + if PY2: + return + try: + import locale + fs_enc = codecs.lookup(locale.getpreferredencoding()).name + except Exception: + fs_enc = 'ascii' + if fs_enc != 'ascii': + return + + extra = '' + if os.name == 'posix': + import subprocess + rv = subprocess.Popen(['locale', '-a'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate()[0] + good_locales = set() + has_c_utf8 = False + + # Make sure we're operating on text here. + if isinstance(rv, bytes): + rv = rv.decode('ascii', 'replace') + + for line in rv.splitlines(): + locale = line.strip() + if locale.lower().endswith(('.utf-8', '.utf8')): + good_locales.add(locale) + if locale.lower() in ('c.utf8', 'c.utf-8'): + has_c_utf8 = True + + extra += '\n\n' + if not good_locales: + extra += ( + 'Additional information: on this system no suitable UTF-8\n' + 'locales were discovered. This most likely requires resolving\n' + 'by reconfiguring the locale system.' + ) + elif has_c_utf8: + extra += ( + 'This system supports the C.UTF-8 locale which is recommended.\n' + 'You might be able to resolve your issue by exporting the\n' + 'following environment variables:\n\n' + ' export LC_ALL=C.UTF-8\n' + ' export LANG=C.UTF-8' + ) + else: + extra += ( + 'This system lists a couple of UTF-8 supporting locales that\n' + 'you can pick from. The following suitable locales where\n' + 'discovered: %s' + ) % ', '.join(sorted(good_locales)) + + bad_locale = None + for locale in os.environ.get('LC_ALL'), os.environ.get('LANG'): + if locale and locale.lower().endswith(('.utf-8', '.utf8')): + bad_locale = locale + if locale is not None: + break + if bad_locale is not None: + extra += ( + '\n\nClick discovered that you exported a UTF-8 locale\n' + 'but the locale system could not pick up from it because\n' + 'it does not exist. The exported locale is "%s" but it\n' + 'is not supported' + ) % bad_locale + + raise RuntimeError('Click will abort further execution because Python 3 ' + 'was configured to use ASCII as encoding for the ' + 'environment. Consult http://click.pocoo.org/python3/' + 'for mitigation steps.' + extra) diff --git a/Lib/site-packages/click/_winconsole.py b/Lib/site-packages/click/_winconsole.py new file mode 100644 index 0000000..9aed942 --- /dev/null +++ b/Lib/site-packages/click/_winconsole.py @@ -0,0 +1,273 @@ +# -*- coding: utf-8 -*- +# This module is based on the excellent work by Adam BartoÅ¡ who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prmopt. + +import io +import os +import sys +import zlib +import time +import ctypes +import msvcrt +from click._compat import _NonClosingTextIOWrapper, text_type, PY2 +from ctypes import byref, POINTER, c_int, c_char, c_char_p, \ + c_void_p, py_object, c_ssize_t, c_ulong, windll, WINFUNCTYPE +try: + from ctypes import pythonapi + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release +except ImportError: + pythonapi = None +from ctypes.wintypes import LPWSTR, LPCWSTR + + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)( + ('GetCommandLineW', windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE( + POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ('CommandLineToArgvW', windll.shell32)) + + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b'\x1a' +MAX_BYTES_WRITTEN = 32767 + + +class Py_buffer(ctypes.Structure): + _fields_ = [ + ('buf', c_void_p), + ('obj', py_object), + ('len', c_ssize_t), + ('itemsize', c_ssize_t), + ('readonly', c_int), + ('ndim', c_int), + ('format', c_char_p), + ('shape', c_ssize_p), + ('strides', c_ssize_p), + ('suboffsets', c_ssize_p), + ('internal', c_void_p) + ] + + if PY2: + _fields_.insert(-1, ('smalltable', c_ssize_t * 2)) + + +# On PyPy we cannot get buffers so our ability to operate here is +# serverly limited. +if pythonapi is None: + get_buffer = None +else: + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + + def __init__(self, handle): + self.handle = handle + + def isatty(self): + io.RawIOBase.isatty(self) + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError('cannot read odd number of bytes from ' + 'UTF-16-LE encoded console') + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW(self.handle, buffer, code_units_to_be_read, + byref(code_units_read), None) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError('Windows error: %s' % GetLastError()) + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return 'ERROR_SUCCESS' + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return 'ERROR_NOT_ENOUGH_MEMORY' + return 'Windows error %s' % errno + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, + MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW(self.handle, buf, code_units_to_be_written, + byref(code_units_written), None) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream(object): + + def __init__(self, text_stream, byte_stream): + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self): + return self.buffer.name + + def write(self, x): + if isinstance(x, text_type): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def __getattr__(self, name): + return getattr(self._text_stream, name) + + def isatty(self): + return self.buffer.isatty() + + def __repr__(self): + return '' % ( + self.name, + self.encoding, + ) + + +def _get_text_stdin(buffer_stream): + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + 'utf-16-le', 'strict', line_buffering=True) + return ConsoleStream(text_stream, buffer_stream) + + +def _get_text_stdout(buffer_stream): + text_stream = _NonClosingTextIOWrapper( + _WindowsConsoleWriter(STDOUT_HANDLE), + 'utf-16-le', 'strict', line_buffering=True) + return ConsoleStream(text_stream, buffer_stream) + + +def _get_text_stderr(buffer_stream): + text_stream = _NonClosingTextIOWrapper( + _WindowsConsoleWriter(STDERR_HANDLE), + 'utf-16-le', 'strict', line_buffering=True) + return ConsoleStream(text_stream, buffer_stream) + + +if PY2: + def _hash_py_argv(): + return zlib.crc32('\x00'.join(sys.argv[1:])) + + _initial_argv_hash = _hash_py_argv() + + def _get_windows_argv(): + argc = c_int(0) + argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc)) + argv = [argv_unicode[i] for i in range(0, argc.value)] + + if not hasattr(sys, 'frozen'): + argv = argv[1:] + while len(argv) > 0: + arg = argv[0] + if not arg.startswith('-') or arg == '-': + break + argv = argv[1:] + if arg.startswith(('-c', '-m')): + break + + return argv[1:] + + +_stream_factories = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _get_windows_console_stream(f, encoding, errors): + if get_buffer is not None and \ + encoding in ('utf-16-le', None) \ + and errors in ('strict', None) and \ + hasattr(f, 'isatty') and f.isatty(): + func = _stream_factories.get(f.fileno()) + if func is not None: + if not PY2: + f = getattr(f, 'buffer') + if f is None: + return None + else: + # If we are on Python 2 we need to set the stream that we + # deal with to binary mode as otherwise the exercise if a + # bit moot. The same problems apply as for + # get_binary_stdin and friends from _compat. + msvcrt.setmode(f.fileno(), os.O_BINARY) + return func(f) diff --git a/Lib/site-packages/click/core.py b/Lib/site-packages/click/core.py new file mode 100644 index 0000000..7456451 --- /dev/null +++ b/Lib/site-packages/click/core.py @@ -0,0 +1,1744 @@ +import errno +import os +import sys +from contextlib import contextmanager +from itertools import repeat +from functools import update_wrapper + +from .types import convert_type, IntRange, BOOL +from .utils import make_str, make_default_short_help, echo, get_os_args +from .exceptions import ClickException, UsageError, BadParameter, Abort, \ + MissingParameter +from .termui import prompt, confirm +from .formatting import HelpFormatter, join_options +from .parser import OptionParser, split_opt +from .globals import push_context, pop_context + +from ._compat import PY2, isidentifier, iteritems +from ._unicodefun import _check_for_unicode_literals, _verify_python3_env + + +_missing = object() + + +SUBCOMMAND_METAVAR = 'COMMAND [ARGS]...' +SUBCOMMANDS_METAVAR = 'COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...' + + +def _bashcomplete(cmd, prog_name, complete_var=None): + """Internal handler for the bash completion support.""" + if complete_var is None: + complete_var = '_%s_COMPLETE' % (prog_name.replace('-', '_')).upper() + complete_instr = os.environ.get(complete_var) + if not complete_instr: + return + + from ._bashcomplete import bashcomplete + if bashcomplete(cmd, prog_name, complete_var, complete_instr): + sys.exit(1) + + +def _check_multicommand(base_command, cmd_name, cmd, register=False): + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = 'It is not possible to add multi commands as children to ' \ + 'another multi command that is in chain mode' + else: + hint = 'Found a multi command as subcommand to a multi command ' \ + 'that is in chain mode. This is not supported' + raise RuntimeError('%s. Command "%s" is set to chain and "%s" was ' + 'added as subcommand but it in itself is a ' + 'multi command. ("%s" is a %s within a chained ' + '%s named "%s"). This restriction was supposed to ' + 'be lifted in 6.0 but the fix was flawed. This ' + 'will be fixed in Click 7.0' % ( + hint, base_command.name, cmd_name, + cmd_name, cmd.__class__.__name__, + base_command.__class__.__name__, + base_command.name)) + + +def batch(iterable, batch_size): + return list(zip(*repeat(iter(iterable), batch_size))) + + +def invoke_param_callback(callback, ctx, param, value): + code = getattr(callback, '__code__', None) + args = getattr(code, 'co_argcount', 3) + + if args < 3: + # This will become a warning in Click 3.0: + from warnings import warn + warn(Warning('Invoked legacy parameter callback "%s". The new ' + 'signature for such callbacks starting with ' + 'click 2.0 is (ctx, param, value).' + % callback), stacklevel=3) + return callback(ctx, value) + return callback(ctx, param, value) + + +@contextmanager +def augment_usage_errors(ctx, param=None): + """Context manager that attaches extra information to exceptions that + fly. + """ + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing(invocation_order, declaration_order): + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + def sort_key(item): + try: + idx = invocation_order.index(item) + except ValueError: + idx = float('inf') + return (not item.is_eager, idx) + + return sorted(declaration_order, key=sort_key) + + +class Context(object): + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + .. versionadded:: 2.0 + Added the `resilient_parsing`, `help_option_names`, + `token_normalize_func` parameters. + + .. versionadded:: 3.0 + Added the `allow_extra_args` and `allow_interspersed_args` + parameters. + + .. versionadded:: 4.0 + Added the `color`, `ignore_unknown_options`, and + `max_content_width` parameters. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + """ + + def __init__(self, command, parent=None, info_name=None, obj=None, + auto_envvar_prefix=None, default_map=None, + terminal_width=None, max_content_width=None, + resilient_parsing=False, allow_extra_args=None, + allow_interspersed_args=None, + ignore_unknown_options=None, help_option_names=None, + token_normalize_func=None, color=None): + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: the parsed parameters except if the value is hidden in which + #: case it's not remembered. + self.params = {} + #: the leftover arguments. + self.args = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args = [] + if obj is None and parent is not None: + obj = parent.obj + #: the user object stored. + self.obj = obj + self._meta = getattr(parent, 'meta', {}) + + #: A dictionary (-like object) with defaults for parameters. + if default_map is None \ + and parent is not None \ + and parent.default_map is not None: + default_map = parent.default_map.get(info_name) + self.default_map = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`resultcallback`. + self.invoked_subcommand = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + #: The width of the terminal (None is autodetection). + self.terminal_width = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ['--help'] + + #: The names for the help options. + self.help_option_names = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures. + self.resilient_parsing = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if parent is not None \ + and parent.auto_envvar_prefix is not None and \ + self.info_name is not None: + auto_envvar_prefix = '%s_%s' % (parent.auto_envvar_prefix, + self.info_name.upper()) + else: + self.auto_envvar_prefix = auto_envvar_prefix.upper() + self.auto_envvar_prefix = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color = color + + self._close_callbacks = [] + self._depth = 0 + + def __enter__(self): + self._depth += 1 + push_context(self) + return self + + def __exit__(self, exc_type, exc_value, tb): + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup=True): + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self): + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utiltiies can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = __name__ + '.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self): + """Creates the formatter for the help and usage output.""" + return HelpFormatter(width=self.terminal_width, + max_width=self.max_content_width) + + def call_on_close(self, f): + """This decorator remembers a function as callback that should be + executed when the context tears down. This is most useful to bind + resource handling to the script execution. For instance, file objects + opened by the :class:`File` type will register their close callbacks + here. + + :param f: the function to execute on teardown. + """ + self._close_callbacks.append(f) + return f + + def close(self): + """Invokes all close callbacks.""" + for cb in self._close_callbacks: + cb() + self._close_callbacks = [] + + @property + def command_path(self): + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = '' + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + rv = self.parent.command_path + ' ' + rv + return rv.lstrip() + + def find_root(self): + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type): + """Finds the closest object of a given type.""" + node = self + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + node = node.parent + + def ensure_object(self, object_type): + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + def lookup_default(self, name): + """Looks up the default for a parameter name. This by default + looks into the :attr:`default_map` if available. + """ + if self.default_map is not None: + rv = self.default_map.get(name) + if callable(rv): + rv = rv() + return rv + + def fail(self, message): + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self): + """Aborts the script.""" + raise Abort() + + def exit(self, code=0): + """Exits the application with a given exit code.""" + sys.exit(code) + + def get_usage(self): + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self): + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def invoke(*args, **kwargs): + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + """ + self, callback = args[:2] + ctx = self + + # It's also possible to invoke another command which might or + # might not have a callback. In that case we also fill + # in defaults and make a new context for this command. + if isinstance(callback, Command): + other_cmd = callback + callback = other_cmd.callback + ctx = Context(other_cmd, info_name=other_cmd.name, parent=self) + if callback is None: + raise TypeError('The given command does not have a ' + 'callback that can be invoked.') + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.get_default(ctx) + + args = args[2:] + with augment_usage_errors(self): + with ctx: + return callback(*args, **kwargs) + + def forward(*args, **kwargs): + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + """ + self, cmd = args[:2] + + # It's also possible to invoke another command which might or + # might not have a callback. + if not isinstance(cmd, Command): + raise TypeError('Callback is not a command.') + + for param in self.params: + if param not in kwargs: + kwargs[param] = self.params[param] + + return self.invoke(cmd, **kwargs) + + +class BaseCommand(object): + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__(self, name, context_settings=None): + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + if context_settings is None: + context_settings = {} + #: an optional dictionary with defaults passed to the context. + self.context_settings = context_settings + + def get_usage(self, ctx): + raise NotImplementedError('Base commands cannot get usage') + + def get_help(self, ctx): + raise NotImplementedError('Base commands cannot get help') + + def make_context(self, info_name, args, parent=None, **extra): + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + :param info_name: the info name for this invokation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it it's + the name of the script. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + """ + for key, value in iteritems(self.context_settings): + if key not in extra: + extra[key] = value + ctx = Context(self, info_name=info_name, parent=parent, **extra) + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx, args): + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError('Base commands do not know how to parse ' + 'arguments.') + + def invoke(self, ctx): + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError('Base commands are not invokable by default') + + def main(self, args=None, prog_name=None, complete_var=None, + standalone_mode=True, **extra): + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + .. versionadded:: 3.0 + Added the `standalone_mode` flag to control the standalone mode. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + """ + # If we are in Python 3, we will verify that the environment is + # sane at this point of reject further execution to avoid a + # broken script. + if not PY2: + _verify_python3_env() + else: + _check_for_unicode_literals() + + if args is None: + args = get_os_args() + else: + args = list(args) + + if prog_name is None: + prog_name = make_str(os.path.basename( + sys.argv and sys.argv[0] or __file__)) + + # Hook for the Bash completion. This only activates if the Bash + # completion is actually enabled, otherwise this is quite a fast + # noop. + _bashcomplete(self, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + ctx.exit() + except (EOFError, KeyboardInterrupt): + echo(file=sys.stderr) + raise Abort() + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except IOError as e: + if e.errno == errno.EPIPE: + sys.exit(1) + else: + raise + except Abort: + if not standalone_mode: + raise + echo('Aborted!', file=sys.stderr) + sys.exit(1) + + def __call__(self, *args, **kwargs): + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + """ + + def __init__(self, name, context_settings=None, callback=None, + params=None, help=None, epilog=None, short_help=None, + options_metavar='[OPTIONS]', add_help_option=True): + BaseCommand.__init__(self, name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + if short_help is None and help: + short_help = make_default_short_help(help) + self.short_help = short_help + self.add_help_option = add_help_option + + def get_usage(self, ctx): + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip('\n') + + def get_params(self, ctx): + rv = self.params + help_option = self.get_help_option(ctx) + if help_option is not None: + rv = rv + [help_option] + return rv + + def format_usage(self, ctx, formatter): + """Writes the usage line into the formatter.""" + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, ' '.join(pieces)) + + def collect_usage_pieces(self, ctx): + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + return rv + + def get_help_option_names(self, ctx): + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return all_names + + def get_help_option(self, ctx): + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + if not help_options or not self.add_help_option: + return + + def show_help(ctx, param, value): + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + return Option(help_options, is_flag=True, + is_eager=True, expose_value=False, + callback=show_help, + help='Show this message and exit.') + + def make_parser(self, ctx): + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + parser.allow_interspersed_args = ctx.allow_interspersed_args + parser.ignore_unknown_options = ctx.ignore_unknown_options + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx): + """Formats the help into a string and returns it. This creates a + formatter and will call into the following formatting methods: + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip('\n') + + def format_help(self, ctx, formatter): + """Writes the help into the formatter if it exists. + + This calls into the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx, formatter): + """Writes the help text to the formatter if it exists.""" + if self.help: + formatter.write_paragraph() + with formatter.indentation(): + formatter.write_text(self.help) + + def format_options(self, ctx, formatter): + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section('Options'): + formatter.write_dl(opts) + + def format_epilog(self, ctx, formatter): + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + formatter.write_paragraph() + with formatter.indentation(): + formatter.write_text(self.epilog) + + def parse_args(self, ctx, args): + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing( + param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail('Got unexpected extra argument%s (%s)' + % (len(args) != 1 and 's' or '', + ' '.join(map(make_str, args)))) + + ctx.args = args + return args + + def invoke(self, ctx): + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: the result callback to attach to this multi + command. + """ + allow_extra_args = True + allow_interspersed_args = False + + def __init__(self, name=None, invoke_without_command=False, + no_args_is_help=None, subcommand_metavar=None, + chain=False, result_callback=None, **attrs): + Command.__init__(self, name, **attrs) + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + if subcommand_metavar is None: + if chain: + subcommand_metavar = SUBCOMMANDS_METAVAR + else: + subcommand_metavar = SUBCOMMAND_METAVAR + self.subcommand_metavar = subcommand_metavar + self.chain = chain + #: The result callback that is stored. This can be set or + #: overridden with the :func:`resultcallback` decorator. + self.result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError('Multi commands in chain mode cannot ' + 'have optional arguments.') + + def collect_usage_pieces(self, ctx): + rv = Command.collect_usage_pieces(self, ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx, formatter): + Command.format_options(self, ctx, formatter) + self.format_commands(ctx, formatter) + + def resultcallback(self, replace=False): + """Adds a result callback to the chain command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.resultcallback() + def process_result(result, input): + return result + input + + .. versionadded:: 3.0 + + :param replace: if set to `True` an already existing result + callback will be removed. + """ + def decorator(f): + old_callback = self.result_callback + if old_callback is None or replace: + self.result_callback = f + return f + def function(__value, *args, **kwargs): + return f(old_callback(__value, *args, **kwargs), + *args, **kwargs) + self.result_callback = rv = update_wrapper(function, f) + return rv + return decorator + + def format_commands(self, ctx, formatter): + """Extra format methods for multi methods that adds all the commands + after the options. + """ + rows = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + + help = cmd.short_help or '' + rows.append((subcommand, help)) + + if rows: + with formatter.section('Commands'): + formatter.write_dl(rows) + + def parse_args(self, ctx, args): + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = Command.parse_args(self, ctx, args) + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx): + def _process_result(value): + if self.result_callback is not None: + value = ctx.invoke(self.result_callback, value, + **ctx.params) + return value + + if not ctx.protected_args: + # If we are invoked without command the chain flag controls + # how this happens. If we are not in chain mode, the return + # value here is the return value of the command. + # If however we are in chain mode, the return value is the + # return value of the result processor invoked with an empty + # list (which means that no subcommand actually was executed). + if self.invoke_without_command: + if not self.chain: + return Command.invoke(self, ctx) + with ctx: + Command.invoke(self, ctx) + return _process_result([]) + ctx.fail('Missing command.') + + # Fetch args back out + args = ctx.protected_args + ctx.args + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + ctx.invoked_subcommand = cmd_name + Command.invoke(self, ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = args and '*' or None + Command.invoke(self, ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command(self, ctx, args): + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail('No such command "%s".' % original_cmd_name) + + return cmd_name, cmd, args[1:] + + def get_command(self, ctx, cmd_name): + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError() + + def list_commands(self, ctx): + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is the + most common way to implement nesting in Click. + + :param commands: a dictionary of commands. + """ + + def __init__(self, name=None, commands=None, **attrs): + MultiCommand.__init__(self, name, **attrs) + #: the registered subcommands by their exported names. + self.commands = commands or {} + + def add_command(self, cmd, name=None): + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError('Command has no name.') + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + def command(self, *args, **kwargs): + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` but + immediately registers the created command with this instance by + calling into :meth:`add_command`. + """ + def decorator(f): + cmd = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + return decorator + + def group(self, *args, **kwargs): + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` but + immediately registers the created command with this instance by + calling into :meth:`add_command`. + """ + def decorator(f): + cmd = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + return decorator + + def get_command(self, ctx, cmd_name): + return self.commands.get(cmd_name) + + def list_commands(self, ctx): + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + """ + + def __init__(self, name=None, sources=None, **attrs): + MultiCommand.__init__(self, name, **attrs) + #: The list of registered multi commands. + self.sources = sources or [] + + def add_source(self, multi_cmd): + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx, cmd_name): + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + return rv + + def list_commands(self, ctx): + rv = set() + for source in self.sources: + rv.update(source.list_commands(ctx)) + return sorted(rv) + + +class Parameter(object): + """A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. In Click 2.0, the old callback format will still work, + but it will raise a warning to give you change to migrate the + code easier. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The later is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: a callback that should be executed after the parameter + was matched. This is called as ``fn(ctx, param, + value)`` and needs to return the value. Before Click + 2.0, the signature was ``(ctx, value)``. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + """ + param_type_name = 'parameter' + + def __init__(self, param_decls=None, type=None, required=False, + default=None, callback=None, nargs=None, metavar=None, + expose_value=True, is_eager=False, envvar=None): + self.name, self.opts, self.secondary_opts = \ + self._parse_decls(param_decls or (), expose_value) + + self.type = convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = False + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + + @property + def human_readable_name(self): + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name + + def make_metavar(self): + if self.metavar is not None: + return self.metavar + metavar = self.type.get_metavar(self) + if metavar is None: + metavar = self.type.name.upper() + if self.nargs != 1: + metavar += '...' + return metavar + + def get_default(self, ctx): + """Given a context variable this calculates the default value.""" + # Otherwise go with the regular default. + if callable(self.default): + rv = self.default() + else: + rv = self.default + return self.type_cast_value(ctx, rv) + + def add_to_parser(self, parser, ctx): + pass + + def consume_value(self, ctx, opts): + value = opts.get(self.name) + if value is None: + value = ctx.lookup_default(self.name) + if value is None: + value = self.value_from_envvar(ctx) + return value + + def type_cast_value(self, ctx, value): + """Given a value this runs it properly through the type system. + This automatically handles things like `nargs` and `multiple` as + well as composite types. + """ + if self.type.is_composite: + if self.nargs <= 1: + raise TypeError('Attempted to invoke composite type ' + 'but nargs has been set to %s. This is ' + 'not supported; nargs needs to be set to ' + 'a fixed value > 1.' % self.nargs) + if self.multiple: + return tuple(self.type(x or (), self, ctx) for x in value or ()) + return self.type(value or (), self, ctx) + + def _convert(value, level): + if level == 0: + return self.type(value, self, ctx) + return tuple(_convert(x, level - 1) for x in value or ()) + return _convert(value, (self.nargs != 1) + bool(self.multiple)) + + def process_value(self, ctx, value): + """Given a value and context this runs the logic to convert the + value as necessary. + """ + # If the value we were given is None we do nothing. This way + # code that calls this can easily figure out if something was + # not provided. Otherwise it would be converted into an empty + # tuple for multiple invocations which is inconvenient. + if value is not None: + return self.type_cast_value(ctx, value) + + def value_is_missing(self, value): + if value is None: + return True + if (self.nargs != 1 or self.multiple) and value == (): + return True + return False + + def full_process_value(self, ctx, value): + value = self.process_value(ctx, value) + + if value is None: + value = self.get_default(ctx) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + return value + + def resolve_envvar_value(self, ctx): + if self.envvar is None: + return + if isinstance(self.envvar, (tuple, list)): + for envvar in self.envvar: + rv = os.environ.get(envvar) + if rv is not None: + return rv + else: + return os.environ.get(self.envvar) + + def value_from_envvar(self, ctx): + rv = self.resolve_envvar_value(ctx) + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + return rv + + def handle_parse_result(self, ctx, opts, args): + with augment_usage_errors(ctx, param=self): + value = self.consume_value(ctx, opts) + try: + value = self.full_process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + value = None + if self.callback is not None: + try: + value = invoke_param_callback( + self.callback, ctx, self, value) + except Exception: + if not ctx.resilient_parsing: + raise + + if self.expose_value: + ctx.params[self.name] = value + return value, args + + def get_help_record(self, ctx): + pass + + def get_usage_pieces(self, ctx): + return [] + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: controls if the default value should be shown on the + help page. Normally, defaults are not shown. + :param prompt: if set to `True` or a non empty string then the user will + be prompted for input if not set. If set to `True` the + prompt will be the option name capitalized. + :param confirmation_prompt: if set then the value will need to be confirmed + if it was prompted for. + :param hide_input: if this is `True` then the input on the prompt will be + hidden from the user. This is useful for password + input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + """ + param_type_name = 'option' + + def __init__(self, param_decls=None, show_default=False, + prompt=False, confirmation_prompt=False, + hide_input=False, is_flag=None, flag_value=None, + multiple=False, count=False, allow_from_autoenv=True, + type=None, help=None, **attrs): + default_is_missing = attrs.get('default', _missing) is _missing + Parameter.__init__(self, param_decls, type=type, **attrs) + + if prompt is True: + prompt_text = self.name.replace('_', ' ').capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.hide_input = hide_input + + # Flags + if is_flag is None: + if flag_value is not None: + is_flag = True + else: + is_flag = bool(self.secondary_opts) + if is_flag and default_is_missing: + self.default = False + if flag_value is None: + flag_value = not self.default + self.is_flag = is_flag + self.flag_value = flag_value + if self.is_flag and isinstance(self.flag_value, bool) \ + and type is None: + self.type = BOOL + self.is_bool_flag = True + else: + self.is_bool_flag = False + + # Counting + self.count = count + if count: + if type is None: + self.type = IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.multiple = multiple + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + + # Sanity check for stuff we don't support + if __debug__: + if self.nargs < 0: + raise TypeError('Options cannot have nargs < 0') + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError('Cannot prompt for flags that are not bools.') + if not self.is_bool_flag and self.secondary_opts: + raise TypeError('Got secondary option for non boolean flag.') + if self.is_bool_flag and self.hide_input \ + and self.prompt is not None: + raise TypeError('Hidden input does not work with boolean ' + 'flag prompts.') + if self.count: + if self.multiple: + raise TypeError('Options cannot be multiple and count ' + 'at the same time.') + elif self.is_flag: + raise TypeError('Options cannot be count and flags at ' + 'the same time.') + + def _parse_decls(self, decls, expose_value): + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if isidentifier(decl): + if name is not None: + raise TypeError('Name defined twice') + name = decl + else: + split_char = decl[:1] == '/' and ';' or '/' + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: len(x[0])) + name = possible_names[-1][1].replace('-', '_').lower() + if not isidentifier(name): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError('Could not determine name for option') + + if not opts and not secondary_opts: + raise TypeError('No options defined but a name was passed (%s). ' + 'Did you mean to declare an argument instead ' + 'of an option?' % name) + + return name, opts, secondary_opts + + def add_to_parser(self, parser, ctx): + kwargs = { + 'dest': self.name, + 'nargs': self.nargs, + 'obj': self, + } + + if self.multiple: + action = 'append' + elif self.count: + action = 'count' + else: + action = 'store' + + if self.is_flag: + kwargs.pop('nargs', None) + if self.is_bool_flag and self.secondary_opts: + parser.add_option(self.opts, action=action + '_const', + const=True, **kwargs) + parser.add_option(self.secondary_opts, action=action + + '_const', const=False, **kwargs) + else: + parser.add_option(self.opts, action=action + '_const', + const=self.flag_value, + **kwargs) + else: + kwargs['action'] = action + parser.add_option(self.opts, **kwargs) + + def get_help_record(self, ctx): + any_prefix_is_slash = [] + + def _write_opts(opts): + rv, any_slashes = join_options(opts) + if any_slashes: + any_prefix_is_slash[:] = [True] + if not self.is_flag and not self.count: + rv += ' ' + self.make_metavar() + return rv + + rv = [_write_opts(self.opts)] + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or '' + extra = [] + if self.default is not None and self.show_default: + extra.append('default: %s' % ( + ', '.join('%s' % d for d in self.default) + if isinstance(self.default, (list, tuple)) + else self.default, )) + if self.required: + extra.append('required') + if extra: + help = '%s[%s]' % (help and help + ' ' or '', '; '.join(extra)) + + return ((any_prefix_is_slash and '; ' or ' / ').join(rv), help) + + def get_default(self, ctx): + # If we're a non boolean flag out default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return param.flag_value + return None + return Parameter.get_default(self, ctx) + + def prompt_for_value(self, ctx): + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt(self.prompt, default=default, + hide_input=self.hide_input, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x)) + + def resolve_envvar_value(self, ctx): + rv = Parameter.resolve_envvar_value(self, ctx) + if rv is not None: + return rv + if self.allow_from_autoenv and \ + ctx.auto_envvar_prefix is not None: + envvar = '%s_%s' % (ctx.auto_envvar_prefix, self.name.upper()) + return os.environ.get(envvar) + + def value_from_envvar(self, ctx): + rv = self.resolve_envvar_value(ctx) + if rv is None: + return None + value_depth = (self.nargs != 1) + bool(self.multiple) + if value_depth > 0 and rv is not None: + rv = self.type.split_envvar_value(rv) + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + return rv + + def full_process_value(self, ctx, value): + if value is None and self.prompt is not None \ + and not ctx.resilient_parsing: + return self.prompt_for_value(ctx) + return Parameter.full_process_value(self, ctx, value) + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the parameter constructor. + """ + param_type_name = 'argument' + + def __init__(self, param_decls, required=None, **attrs): + if required is None: + if attrs.get('default') is not None: + required = False + else: + required = attrs.get('nargs', 1) > 0 + Parameter.__init__(self, param_decls, required=required, **attrs) + if self.default is not None and self.nargs < 0: + raise TypeError('nargs=-1 in combination with a default value ' + 'is not supported.') + + @property + def human_readable_name(self): + if self.metavar is not None: + return self.metavar + return self.name.upper() + + def make_metavar(self): + if self.metavar is not None: + return self.metavar + var = self.name.upper() + if not self.required: + var = '[%s]' % var + if self.nargs != 1: + var += '...' + return var + + def _parse_decls(self, decls, expose_value): + if not decls: + if not expose_value: + return None, [], [] + raise TypeError('Could not determine name for argument') + if len(decls) == 1: + name = arg = decls[0] + name = name.replace('-', '_').lower() + elif len(decls) == 2: + name, arg = decls + else: + raise TypeError('Arguments take exactly one or two ' + 'parameter declarations, got %d' % len(decls)) + return name, [arg], [] + + def get_usage_pieces(self, ctx): + return [self.make_metavar()] + + def add_to_parser(self, parser, ctx): + parser.add_argument(dest=self.name, nargs=self.nargs, + obj=self) + + +# Circular dependency between decorators and core +from .decorators import command, group diff --git a/Lib/site-packages/click/decorators.py b/Lib/site-packages/click/decorators.py new file mode 100644 index 0000000..9893452 --- /dev/null +++ b/Lib/site-packages/click/decorators.py @@ -0,0 +1,304 @@ +import sys +import inspect + +from functools import update_wrapper + +from ._compat import iteritems +from ._unicodefun import _check_for_unicode_literals +from .utils import echo +from .globals import get_current_context + + +def pass_context(f): + """Marks a callback as wanting to receive the current context + object as first argument. + """ + def new_func(*args, **kwargs): + return f(get_current_context(), *args, **kwargs) + return update_wrapper(new_func, f) + + +def pass_obj(f): + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + def new_func(*args, **kwargs): + return f(get_current_context().obj, *args, **kwargs) + return update_wrapper(new_func, f) + + +def make_pass_decorator(object_type, ensure=False): + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + def decorator(f): + def new_func(*args, **kwargs): + ctx = get_current_context() + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + if obj is None: + raise RuntimeError('Managed to invoke callback without a ' + 'context object of type %r existing' + % object_type.__name__) + return ctx.invoke(f, obj, *args[1:], **kwargs) + return update_wrapper(new_func, f) + return decorator + + +def _make_command(f, name, attrs, cls): + if isinstance(f, Command): + raise TypeError('Attempted to convert a callback into a ' + 'command twice.') + try: + params = f.__click_params__ + params.reverse() + del f.__click_params__ + except AttributeError: + params = [] + help = attrs.get('help') + if help is None: + help = inspect.getdoc(f) + if isinstance(help, bytes): + help = help.decode('utf-8') + else: + help = inspect.cleandoc(help) + attrs['help'] = help + _check_for_unicode_literals() + return cls(name=name or f.__name__.lower(), + callback=f, params=params, **attrs) + + +def command(name=None, cls=None, **attrs): + """Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function. If you + want to change that, you can pass the intended name as the first + argument. + + All keyword arguments are forwarded to the underlying command class. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + """ + if cls is None: + cls = Command + def decorator(f): + cmd = _make_command(f, name, attrs, cls) + cmd.__doc__ = f.__doc__ + return cmd + return decorator + + +def group(name=None, **attrs): + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + """ + attrs.setdefault('cls', Group) + return command(name, **attrs) + + +def _param_memo(f, param): + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, '__click_params__'): + f.__click_params__ = [] + f.__click_params__.append(param) + + +def argument(*param_decls, **attrs): + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + """ + def decorator(f): + ArgumentClass = attrs.pop('cls', Argument) + _param_memo(f, ArgumentClass(param_decls, **attrs)) + return f + return decorator + + +def option(*param_decls, **attrs): + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + """ + def decorator(f): + if 'help' in attrs: + attrs['help'] = inspect.cleandoc(attrs['help']) + OptionClass = attrs.pop('cls', Option) + _param_memo(f, OptionClass(param_decls, **attrs)) + return f + return decorator + + +def confirmation_option(*param_decls, **attrs): + """Shortcut for confirmation prompts that can be ignored by passing + ``--yes`` as parameter. + + This is equivalent to decorating a function with :func:`option` with + the following parameters:: + + def callback(ctx, param, value): + if not value: + ctx.abort() + + @click.command() + @click.option('--yes', is_flag=True, callback=callback, + expose_value=False, prompt='Do you want to continue?') + def dropdb(): + pass + """ + def decorator(f): + def callback(ctx, param, value): + if not value: + ctx.abort() + attrs.setdefault('is_flag', True) + attrs.setdefault('callback', callback) + attrs.setdefault('expose_value', False) + attrs.setdefault('prompt', 'Do you want to continue?') + attrs.setdefault('help', 'Confirm the action without prompting.') + return option(*(param_decls or ('--yes',)), **attrs)(f) + return decorator + + +def password_option(*param_decls, **attrs): + """Shortcut for password prompts. + + This is equivalent to decorating a function with :func:`option` with + the following parameters:: + + @click.command() + @click.option('--password', prompt=True, confirmation_prompt=True, + hide_input=True) + def changeadmin(password): + pass + """ + def decorator(f): + attrs.setdefault('prompt', True) + attrs.setdefault('confirmation_prompt', True) + attrs.setdefault('hide_input', True) + return option(*(param_decls or ('--password',)), **attrs)(f) + return decorator + + +def version_option(version=None, *param_decls, **attrs): + """Adds a ``--version`` option which immediately ends the program + printing out the version number. This is implemented as an eager + option that prints the version and exits the program in the callback. + + :param version: the version number to show. If not provided Click + attempts an auto discovery via setuptools. + :param prog_name: the name of the program (defaults to autodetection) + :param message: custom message to show instead of the default + (``'%(prog)s, version %(version)s'``) + :param others: everything else is forwarded to :func:`option`. + """ + if version is None: + module = sys._getframe(1).f_globals.get('__name__') + def decorator(f): + prog_name = attrs.pop('prog_name', None) + message = attrs.pop('message', '%(prog)s, version %(version)s') + + def callback(ctx, param, value): + if not value or ctx.resilient_parsing: + return + prog = prog_name + if prog is None: + prog = ctx.find_root().info_name + ver = version + if ver is None: + try: + import pkg_resources + except ImportError: + pass + else: + for dist in pkg_resources.working_set: + scripts = dist.get_entry_map().get('console_scripts') or {} + for script_name, entry_point in iteritems(scripts): + if entry_point.module_name == module: + ver = dist.version + break + if ver is None: + raise RuntimeError('Could not determine version') + echo(message % { + 'prog': prog, + 'version': ver, + }, color=ctx.color) + ctx.exit() + + attrs.setdefault('is_flag', True) + attrs.setdefault('expose_value', False) + attrs.setdefault('is_eager', True) + attrs.setdefault('help', 'Show the version and exit.') + attrs['callback'] = callback + return option(*(param_decls or ('--version',)), **attrs)(f) + return decorator + + +def help_option(*param_decls, **attrs): + """Adds a ``--help`` option which immediately ends the program + printing out the help page. This is usually unnecessary to add as + this is added by default to all commands unless suppressed. + + Like :func:`version_option`, this is implemented as eager option that + prints in the callback and exits. + + All arguments are forwarded to :func:`option`. + """ + def decorator(f): + def callback(ctx, param, value): + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + attrs.setdefault('is_flag', True) + attrs.setdefault('expose_value', False) + attrs.setdefault('help', 'Show this message and exit.') + attrs.setdefault('is_eager', True) + attrs['callback'] = callback + return option(*(param_decls or ('--help',)), **attrs)(f) + return decorator + + +# Circular dependencies between core and decorators +from .core import Command, Group, Argument, Option diff --git a/Lib/site-packages/click/exceptions.py b/Lib/site-packages/click/exceptions.py new file mode 100644 index 0000000..74a4542 --- /dev/null +++ b/Lib/site-packages/click/exceptions.py @@ -0,0 +1,201 @@ +from ._compat import PY2, filename_to_ui, get_text_stderr +from .utils import echo + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception + exit_code = 1 + + def __init__(self, message): + if PY2: + if message is not None: + message = message.encode('utf-8') + Exception.__init__(self, message) + self.message = message + + def format_message(self): + return self.message + + def show(self, file=None): + if file is None: + file = get_text_stderr() + echo('Error: %s' % self.format_message(), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + exit_code = 2 + + def __init__(self, message, ctx=None): + ClickException.__init__(self, message) + self.ctx = ctx + + def show(self, file=None): + if file is None: + file = get_text_stderr() + color = None + if self.ctx is not None: + color = self.ctx.color + echo(self.ctx.get_usage() + '\n', file=file, color=color) + echo('Error: %s' % self.format_message(), file=file, color=color) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__(self, message, ctx=None, param=None, + param_hint=None): + UsageError.__init__(self, message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self): + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.opts or [self.param.human_readable_name] + else: + return 'Invalid value: %s' % self.message + if isinstance(param_hint, (tuple, list)): + param_hint = ' / '.join('"%s"' % x for x in param_hint) + return 'Invalid value for %s: %s' % (param_hint, self.message) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__(self, message=None, ctx=None, param=None, + param_hint=None, param_type=None): + BadParameter.__init__(self, message, ctx, param, param_hint) + self.param_type = param_type + + def format_message(self): + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.opts or [self.param.human_readable_name] + else: + param_hint = None + if isinstance(param_hint, (tuple, list)): + param_hint = ' / '.join('"%s"' % x for x in param_hint) + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += '. ' + msg_extra + else: + msg = msg_extra + + return 'Missing %s%s%s%s' % ( + param_type, + param_hint and ' %s' % param_hint or '', + msg and '. ' or '.', + msg or '', + ) + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__(self, option_name, message=None, possibilities=None, + ctx=None): + if message is None: + message = 'no such option: %s' % option_name + UsageError.__init__(self, message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self): + bits = [self.message] + if self.possibilities: + if len(self.possibilities) == 1: + bits.append('Did you mean %s?' % self.possibilities[0]) + else: + possibilities = sorted(self.possibilities) + bits.append('(Possible options: %s)' % ', '.join(possibilities)) + return ' '.join(bits) + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + """ + + def __init__(self, message, ctx=None): + UsageError.__init__(self, message, ctx) + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + def __init__(self, message, ctx=None): + UsageError.__init__(self, message, ctx) + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename, hint=None): + ui_filename = filename_to_ui(filename) + if hint is None: + hint = 'unknown error' + ClickException.__init__(self, hint) + self.ui_filename = ui_filename + self.filename = filename + + def format_message(self): + return 'Could not open file %s: %s' % (self.ui_filename, self.message) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" diff --git a/Lib/site-packages/click/formatting.py b/Lib/site-packages/click/formatting.py new file mode 100644 index 0000000..a3d6a4d --- /dev/null +++ b/Lib/site-packages/click/formatting.py @@ -0,0 +1,256 @@ +from contextlib import contextmanager +from .termui import get_terminal_size +from .parser import split_opt +from ._compat import term_len + + +# Can force a width. This is used by the test system +FORCED_WIDTH = None + + +def measure_table(rows): + widths = {} + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows(rows, col_count): + for row in rows: + row = tuple(row) + yield row + ('',) * (col_count - len(row)) + + +def wrap_text(text, width=78, initial_indent='', subsequent_indent='', + preserve_paragraphs=False): + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + text = text.expandtabs() + wrapper = TextWrapper(width, initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False) + if not preserve_paragraphs: + return wrapper.fill(text) + + p = [] + buf = [] + indent = None + + def _flush_par(): + if not buf: + return + if buf[0].strip() == '\b': + p.append((indent or 0, True, '\n'.join(buf[1:]))) + else: + p.append((indent or 0, False, ' '.join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(' ' * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return '\n\n'.join(rv) + + +class HelpFormatter(object): + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__(self, indent_increment=2, width=None, max_width=None): + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(get_terminal_size()[0], max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer = [] + + def write(self, string): + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self): + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self): + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage(self, prog, args='', prefix='Usage: '): + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: the prefix for the first line. + """ + usage_prefix = '%*s%s ' % (self.current_indent, prefix, prog) + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = ' ' * term_len(usage_prefix) + self.write(wrap_text(args, text_width, + initial_indent=usage_prefix, + subsequent_indent=indent)) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write('\n') + indent = ' ' * (max(self.current_indent, term_len(prefix)) + 4) + self.write(wrap_text(args, text_width, + initial_indent=indent, + subsequent_indent=indent)) + + self.write('\n') + + def write_heading(self, heading): + """Writes a heading into the buffer.""" + self.write('%*s%s:\n' % (self.current_indent, '', heading)) + + def write_paragraph(self): + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write('\n') + + def write_text(self, text): + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + text_width = max(self.width - self.current_indent, 11) + indent = ' ' * self.current_indent + self.write(wrap_text(text, text_width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True)) + self.write('\n') + + def write_dl(self, rows, col_max=30, col_spacing=2): + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError('Expected two columns for definition list') + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write('%*s%s' % (self.current_indent, '', first)) + if not second: + self.write('\n') + continue + if term_len(first) <= first_col - col_spacing: + self.write(' ' * (first_col - term_len(first))) + else: + self.write('\n') + self.write(' ' * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + lines = iter(wrap_text(second, text_width).splitlines()) + if lines: + self.write(next(lines) + '\n') + for line in lines: + self.write('%*s%s\n' % ( + first_col + self.current_indent, '', line)) + else: + self.write('\n') + + @contextmanager + def section(self, name): + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self): + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self): + """Returns the buffer contents.""" + return ''.join(self.buffer) + + +def join_options(options): + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + for opt in options: + prefix = split_opt(opt)[0] + if prefix == '/': + any_prefix_is_slash = True + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + + rv = ', '.join(x[1] for x in rv) + return rv, any_prefix_is_slash diff --git a/Lib/site-packages/click/globals.py b/Lib/site-packages/click/globals.py new file mode 100644 index 0000000..14338e6 --- /dev/null +++ b/Lib/site-packages/click/globals.py @@ -0,0 +1,48 @@ +from threading import local + + +_local = local() + + +def get_current_context(silent=False): + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing it's behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: is set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return getattr(_local, 'stack')[-1] + except (AttributeError, IndexError): + if not silent: + raise RuntimeError('There is no active click context.') + + +def push_context(ctx): + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault('stack', []).append(ctx) + + +def pop_context(): + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color=None): + """"Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + ctx = get_current_context(silent=True) + if ctx is not None: + return ctx.color diff --git a/Lib/site-packages/click/parser.py b/Lib/site-packages/click/parser.py new file mode 100644 index 0000000..9775c9f --- /dev/null +++ b/Lib/site-packages/click/parser.py @@ -0,0 +1,426 @@ +# -*- coding: utf-8 -*- +""" + click.parser + ~~~~~~~~~~~~ + + This module started out as largely a copy paste from the stdlib's + optparse module with the features removed that we do not need from + optparse because we implement them in Click on a higher level (for + instance type handling, help formatting and a lot more). + + The plan is to remove more and more from here over time. + + The reason this is a different module and not optparse from the stdlib + is that there are differences in 2.x and 3.x about the error messages + generated and optparse in the stdlib uses gettext for no good reason + and might cause us issues. +""" +import re +from collections import deque +from .exceptions import UsageError, NoSuchOption, BadOptionUsage, \ + BadArgumentUsage + + +def _unpack_args(args, nargs_spec): + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv = [] + spos = None + + def _fetch(c): + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError('Cannot have two nargs < 0') + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1:] = reversed(rv[spos + 1:]) + + return tuple(rv), list(args) + + +def _error_opt_args(nargs, opt): + if nargs == 1: + raise BadOptionUsage('%s option requires an argument' % opt) + raise BadOptionUsage('%s option requires %d arguments' % (opt, nargs)) + + +def split_opt(opt): + first = opt[:1] + if first.isalnum(): + return '', opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt, ctx): + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return prefix + ctx.token_normalize_func(opt) + + +def split_arg_string(string): + """Given an argument string this attempts to split it into small parts.""" + rv = [] + for match in re.finditer(r"('([^'\\]*(?:\\.[^'\\]*)*)'" + r'|"([^"\\]*(?:\\.[^"\\]*)*)"' + r'|\S+)\s*', string, re.S): + arg = match.group().strip() + if arg[:1] == arg[-1:] and arg[:1] in '"\'': + arg = arg[1:-1].encode('ascii', 'backslashreplace') \ + .decode('unicode-escape') + try: + arg = type(string)(arg) + except UnicodeError: + pass + rv.append(arg) + return rv + + +class Option(object): + + def __init__(self, opts, dest, action=None, nargs=1, const=None, obj=None): + self._short_opts = [] + self._long_opts = [] + self.prefixes = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError('Invalid start character for option (%s)' + % opt) + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = 'store' + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self): + return self.action in ('store', 'append') + + def process(self, value, state): + if self.action == 'store': + state.opts[self.dest] = value + elif self.action == 'store_const': + state.opts[self.dest] = self.const + elif self.action == 'append': + state.opts.setdefault(self.dest, []).append(value) + elif self.action == 'append_const': + state.opts.setdefault(self.dest, []).append(self.const) + elif self.action == 'count': + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 + else: + raise ValueError('unknown action %r' % self.action) + state.order.append(self.obj) + + +class Argument(object): + + def __init__(self, dest, nargs=1, obj=None): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process(self, value, state): + if self.nargs > 1: + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage('argument %s takes %d values' + % (self.dest, self.nargs)) + state.opts[self.dest] = value + state.order.append(self.obj) + + +class ParsingState(object): + + def __init__(self, rargs): + self.opts = {} + self.largs = [] + self.rargs = rargs + self.order = [] + + +class OptionParser(object): + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx=None): + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options = False + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + self._short_opt = {} + self._long_opt = {} + self._opt_prefixes = set(['-', '--']) + self._args = [] + + def add_option(self, opts, dest, action=None, nargs=1, const=None, + obj=None): + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``appnd_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + if obj is None: + obj = dest + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(opts, dest, action=action, nargs=nargs, + const=const, obj=obj) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument(self, dest, nargs=1, obj=None): + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + if obj is None: + obj = dest + self._args.append(Argument(dest=dest, nargs=nargs, obj=obj)) + + def parse_args(self, args): + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state): + pargs, args = _unpack_args(state.largs + state.rargs, + [x.nargs for x in self._args]) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state): + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == '--': + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt(self, opt, explicit_value, state): + if opt not in self._long_opt: + possibilities = [word for word in self._long_opt + if word.startswith(opt)] + raise NoSuchOption(opt, possibilities=possibilities) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + nargs = option.nargs + if len(state.rargs) < nargs: + _error_opt_args(nargs, opt) + elif nargs == 1: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + elif explicit_value is not None: + raise BadOptionUsage('%s option does not take a value' % opt) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg, state): + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(prefix + ch, self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + nargs = option.nargs + if len(state.rargs) < nargs: + _error_opt_args(nargs, opt) + elif nargs == 1: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we re-combinate the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(prefix + ''.join(unknown_options)) + + def _process_opts(self, arg, state): + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if '=' in arg: + long_opt, explicit_value = arg.split('=', 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + return self._match_short_opt(arg, state) + if not self.ignore_unknown_options: + raise + state.largs.append(arg) diff --git a/Lib/site-packages/click/termui.py b/Lib/site-packages/click/termui.py new file mode 100644 index 0000000..d9fba52 --- /dev/null +++ b/Lib/site-packages/click/termui.py @@ -0,0 +1,539 @@ +import os +import sys +import struct + +from ._compat import raw_input, text_type, string_types, \ + isatty, strip_ansi, get_winterm_size, DEFAULT_COLUMNS, WIN +from .utils import echo +from .exceptions import Abort, UsageError +from .types import convert_type +from .globals import resolve_color_default + + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func = raw_input + +_ansi_colors = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', + 'cyan', 'white', 'reset') +_ansi_reset_all = '\033[0m' + + +def hidden_prompt_func(prompt): + import getpass + return getpass.getpass(prompt) + + +def _build_prompt(text, suffix, show_default=False, default=None): + prompt = text + if default is not None and show_default: + prompt = '%s [%s]' % (prompt, default) + return prompt + suffix + + +def prompt(text, default=None, hide_input=False, + confirmation_prompt=False, type=None, + value_proc=None, prompt_suffix=': ', + show_default=True, err=False): + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending a interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: asks for confirmation for the value. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + result = None + + def prompt_func(text): + f = hide_input and hidden_prompt_func or visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text, nl=False, err=err) + return f('') + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt(text, prompt_suffix, show_default, default) + + while 1: + while 1: + value = prompt_func(prompt) + if value: + break + # If a default is set and used, then the confirmation + # prompt is always skipped because that's the only thing + # that really makes sense. + elif default is not None: + return default + try: + result = value_proc(value) + except UsageError as e: + echo('Error: %s' % e.message, err=err) + continue + if not confirmation_prompt: + return result + while 1: + value2 = prompt_func('Repeat for confirmation: ') + if value2: + break + if value == value2: + return result + echo('Error: the two entered values do not match', err=err) + + +def confirm(text, default=False, abort=False, prompt_suffix=': ', + show_default=True, err=False): + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param text: the question to ask. + :param default: the default for the prompt. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + prompt = _build_prompt(text, prompt_suffix, show_default, + default and 'Y/n' or 'y/N') + while 1: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt, nl=False, err=err) + value = visible_prompt_func('').lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() + if value in ('y', 'yes'): + rv = True + elif value in ('n', 'no'): + rv = False + elif value == '': + rv = default + else: + echo('Error: invalid input', err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def get_terminal_size(): + """Returns the current size of the terminal as tuple in the form + ``(width, height)`` in columns and rows. + """ + # If shutil has get_terminal_size() (Python 3.3 and later) use that + if sys.version_info >= (3, 3): + import shutil + shutil_get_terminal_size = getattr(shutil, 'get_terminal_size', None) + if shutil_get_terminal_size: + sz = shutil_get_terminal_size() + return sz.columns, sz.lines + + if get_winterm_size is not None: + return get_winterm_size() + + def ioctl_gwinsz(fd): + try: + import fcntl + import termios + cr = struct.unpack( + 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) + except Exception: + return + return cr + + cr = ioctl_gwinsz(0) or ioctl_gwinsz(1) or ioctl_gwinsz(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + try: + cr = ioctl_gwinsz(fd) + finally: + os.close(fd) + except Exception: + pass + if not cr or not cr[0] or not cr[1]: + cr = (os.environ.get('LINES', 25), + os.environ.get('COLUMNS', DEFAULT_COLUMNS)) + return int(cr[1]), int(cr[0]) + + +def echo_via_pager(text, color=None): + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text: the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + if not isinstance(text, string_types): + text = text_type(text) + from ._termui_impl import pager + return pager(text + '\n', color) + + +def progressbar(iterable=None, length=None, label=None, show_eta=True, + show_percent=None, show_pos=False, + item_show_func=None, fill_char='#', empty_char='-', + bar_template='%(label)s [%(bar)s] %(info)s', + info_sep=' ', width=36, file=None, color=None): + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already displayed. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `color` parameter. Added a `update` method to the + progressbar object. + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: a function called with the current item which + can return a string to show the current item + next to the progress bar. Note that the current + item can be `None`! + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: the file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + """ + from ._termui_impl import ProgressBar + color = resolve_color_default(color) + return ProgressBar(iterable=iterable, length=length, show_eta=show_eta, + show_percent=show_percent, show_pos=show_pos, + item_show_func=item_show_func, fill_char=fill_char, + empty_char=empty_char, bar_template=bar_template, + info_sep=info_sep, file=file, label=label, + width=width, color=color) + + +def clear(): + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + # If we're on Windows and we don't have colorama available, then we + # clear the screen by shelling out. Otherwise we can use an escape + # sequence. + if WIN: + os.system('cls') + else: + sys.stdout.write('\033[2J\033[1;1H') + + +def style(text, fg=None, bg=None, bold=None, dim=None, underline=None, + blink=None, reverse=None, reset=True): + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``reset`` (reset the color code only) + + .. versionadded:: 2.0 + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + """ + bits = [] + if fg: + try: + bits.append('\033[%dm' % (_ansi_colors.index(fg) + 30)) + except ValueError: + raise TypeError('Unknown color %r' % fg) + if bg: + try: + bits.append('\033[%dm' % (_ansi_colors.index(bg) + 40)) + except ValueError: + raise TypeError('Unknown color %r' % bg) + if bold is not None: + bits.append('\033[%dm' % (1 if bold else 22)) + if dim is not None: + bits.append('\033[%dm' % (2 if dim else 22)) + if underline is not None: + bits.append('\033[%dm' % (4 if underline else 24)) + if blink is not None: + bits.append('\033[%dm' % (5 if blink else 25)) + if reverse is not None: + bits.append('\033[%dm' % (7 if reverse else 27)) + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return ''.join(bits) + + +def unstyle(text): + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho(text, file=None, nl=True, err=False, color=None, **styles): + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + .. versionadded:: 2.0 + """ + return echo(style(text, **styles), file=file, nl=nl, err=err, color=color) + + +def edit(text=None, editor=None, env=None, require_save=True, + extension='.txt', filename=None): + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + editor = Editor(editor=editor, env=env, require_save=require_save, + extension=extension) + if filename is None: + return editor.edit(text) + editor.edit_file(filename) + + +def launch(url, wait=False, locate=False): + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('http://click.pocoo.org/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: waits for the program to stop. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar = None + + +def getchar(echo=False): + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + f = _getchar + if f is None: + from ._termui_impl import getchar as f + return f(echo) + + +def pause(info='Press any key to continue ...', err=False): + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: the info string to print before pausing. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/Lib/site-packages/click/testing.py b/Lib/site-packages/click/testing.py new file mode 100644 index 0000000..4416c77 --- /dev/null +++ b/Lib/site-packages/click/testing.py @@ -0,0 +1,322 @@ +import os +import sys +import shutil +import tempfile +import contextlib + +from ._compat import iteritems, PY2 + + +# If someone wants to vendor click, we want to ensure the +# correct package is discovered. Ideally we could use a +# relative import here but unfortunately Python does not +# support that. +clickpkg = sys.modules[__name__.rsplit('.', 1)[0]] + + +if PY2: + from cStringIO import StringIO +else: + import io + from ._compat import _find_binary_reader + + +class EchoingStdin(object): + + def __init__(self, input, output): + self._input = input + self._output = output + + def __getattr__(self, x): + return getattr(self._input, x) + + def _echo(self, rv): + self._output.write(rv) + return rv + + def read(self, n=-1): + return self._echo(self._input.read(n)) + + def readline(self, n=-1): + return self._echo(self._input.readline(n)) + + def readlines(self): + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self): + return iter(self._echo(x) for x in self._input) + + def __repr__(self): + return repr(self._input) + + +def make_input_stream(input, charset): + # Is already an input stream. + if hasattr(input, 'read'): + if PY2: + return input + rv = _find_binary_reader(input) + if rv is not None: + return rv + raise TypeError('Could not find binary reader for input stream.') + + if input is None: + input = b'' + elif not isinstance(input, bytes): + input = input.encode(charset) + if PY2: + return StringIO(input) + return io.BytesIO(input) + + +class Result(object): + """Holds the captured result of an invoked CLI script.""" + + def __init__(self, runner, output_bytes, exit_code, exception, + exc_info=None): + #: The runner that created the result + self.runner = runner + #: The output as bytes. + self.output_bytes = output_bytes + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happend if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self): + """The output as unicode string.""" + return self.output_bytes.decode(self.runner.charset, 'replace') \ + .replace('\r\n', '\n') + + def __repr__(self): + return '' % ( + self.exception and repr(self.exception) or 'okay', + ) + + +class CliRunner(object): + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. This is + UTF-8 by default and should not be changed currently as + the reporting to Click only works in Python 2 properly. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + """ + + def __init__(self, charset=None, env=None, echo_stdin=False): + if charset is None: + charset = 'utf-8' + self.charset = charset + self.env = env or {} + self.echo_stdin = echo_stdin + + def get_default_prog_name(self, cli): + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or 'root' + + def make_env(self, overrides=None): + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation(self, input=None, env=None, color=False): + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + .. versionadded:: 4.0 + The ``color`` parameter was added. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + """ + input = make_input_stream(input, self.charset) + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = clickpkg.formatting.FORCED_WIDTH + clickpkg.formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + if PY2: + sys.stdout = sys.stderr = bytes_output = StringIO() + if self.echo_stdin: + input = EchoingStdin(input, bytes_output) + else: + bytes_output = io.BytesIO() + if self.echo_stdin: + input = EchoingStdin(input, bytes_output) + input = io.TextIOWrapper(input, encoding=self.charset) + sys.stdout = sys.stderr = io.TextIOWrapper( + bytes_output, encoding=self.charset) + + sys.stdin = input + + def visible_input(prompt=None): + sys.stdout.write(prompt or '') + val = input.readline().rstrip('\r\n') + sys.stdout.write(val + '\n') + sys.stdout.flush() + return val + + def hidden_input(prompt=None): + sys.stdout.write((prompt or '') + '\n') + sys.stdout.flush() + return input.readline().rstrip('\r\n') + + def _getchar(echo): + char = sys.stdin.read(1) + if echo: + sys.stdout.write(char) + sys.stdout.flush() + return char + + default_color = color + def should_strip_ansi(stream=None, color=None): + if color is None: + return not default_color + return not color + + old_visible_prompt_func = clickpkg.termui.visible_prompt_func + old_hidden_prompt_func = clickpkg.termui.hidden_prompt_func + old__getchar_func = clickpkg.termui._getchar + old_should_strip_ansi = clickpkg.utils.should_strip_ansi + clickpkg.termui.visible_prompt_func = visible_input + clickpkg.termui.hidden_prompt_func = hidden_input + clickpkg.termui._getchar = _getchar + clickpkg.utils.should_strip_ansi = should_strip_ansi + + old_env = {} + try: + for key, value in iteritems(env): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield bytes_output + finally: + for key, value in iteritems(old_env): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + clickpkg.termui.visible_prompt_func = old_visible_prompt_func + clickpkg.termui.hidden_prompt_func = old_hidden_prompt_func + clickpkg.termui._getchar = old__getchar_func + clickpkg.utils.should_strip_ansi = old_should_strip_ansi + clickpkg.formatting.FORCED_WIDTH = old_forced_width + + def invoke(self, cli, args=None, input=None, env=None, + catch_exceptions=True, color=False, **extra): + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + .. versionadded:: 3.0 + The ``catch_exceptions`` parameter was added. + + .. versionchanged:: 3.0 + The result object now has an `exc_info` attribute with the + traceback if available. + + .. versionadded:: 4.0 + The ``color`` parameter was added. + + :param cli: the command to invoke + :param args: the arguments to invoke + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as out: + exception = None + exit_code = 0 + + try: + cli.main(args=args or (), + prog_name=self.get_default_prog_name(cli), **extra) + except SystemExit as e: + if e.code != 0: + exception = e + + exc_info = sys.exc_info() + + exit_code = e.code + if not isinstance(exit_code, int): + sys.stdout.write(str(exit_code)) + sys.stdout.write('\n') + exit_code = 1 + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = -1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + output = out.getvalue() + + return Result(runner=self, + output_bytes=output, + exit_code=exit_code, + exception=exception, + exc_info=exc_info) + + @contextlib.contextmanager + def isolated_filesystem(self): + """A context manager that creates a temporary folder and changes + the current working directory to it for isolated filesystem tests. + """ + cwd = os.getcwd() + t = tempfile.mkdtemp() + os.chdir(t) + try: + yield t + finally: + os.chdir(cwd) + try: + shutil.rmtree(t) + except (OSError, IOError): + pass diff --git a/Lib/site-packages/click/types.py b/Lib/site-packages/click/types.py new file mode 100644 index 0000000..3639002 --- /dev/null +++ b/Lib/site-packages/click/types.py @@ -0,0 +1,550 @@ +import os +import stat + +from ._compat import open_stream, text_type, filename_to_ui, \ + get_filesystem_encoding, get_streerror, _get_argv_encoding, PY2 +from .exceptions import BadParameter +from .utils import safecall, LazyFile + + +class ParamType(object): + """Helper for converting values through types. The following is + necessary for a valid type: + + * it needs a name + * it needs to pass through None unchanged + * it needs to convert from a string + * it needs to convert its result type through unchanged + (eg: needs to be idempotent) + * it needs to be able to deal with param and context being `None`. + This can be the case when the object is used with prompt + inputs. + """ + is_composite = False + + #: the descriptive name of this type + name = None + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter = None + + def __call__(self, value, param=None, ctx=None): + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param): + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param): + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert(self, value, param, ctx): + """Converts the value. This is not invoked for values that are + `None` (the missing value). + """ + return value + + def split_envvar_value(self, rv): + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or '').split(self.envvar_list_splitter) + + def fail(self, message, param=None, ctx=None): + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self): + raise NotImplementedError() + + +class FuncParamType(ParamType): + + def __init__(self, func): + self.name = func.__name__ + self.func = func + + def convert(self, value, param, ctx): + try: + return self.func(value) + except ValueError: + try: + value = text_type(value) + except UnicodeError: + value = str(value).decode('utf-8', 'replace') + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = 'text' + + def convert(self, value, param, ctx): + return value + + def __repr__(self): + return 'UNPROCESSED' + + +class StringParamType(ParamType): + name = 'text' + + def convert(self, value, param, ctx): + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = get_filesystem_encoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode('utf-8', 'replace') + return value + return value + + def __repr__(self): + return 'STRING' + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set of + supported values. All of these values have to be strings. + + See :ref:`choice-opts` for an example. + """ + name = 'choice' + + def __init__(self, choices): + self.choices = choices + + def get_metavar(self, param): + return '[%s]' % '|'.join(self.choices) + + def get_missing_message(self, param): + return 'Choose from %s.' % ', '.join(self.choices) + + def convert(self, value, param, ctx): + # Exact match + if value in self.choices: + return value + + # Match through normalization + if ctx is not None and \ + ctx.token_normalize_func is not None: + value = ctx.token_normalize_func(value) + for choice in self.choices: + if ctx.token_normalize_func(choice) == value: + return choice + + self.fail('invalid choice: %s. (choose from %s)' % + (value, ', '.join(self.choices)), param, ctx) + + def __repr__(self): + return 'Choice(%r)' % list(self.choices) + + +class IntParamType(ParamType): + name = 'integer' + + def convert(self, value, param, ctx): + try: + return int(value) + except (ValueError, UnicodeError): + self.fail('%s is not a valid integer' % value, param, ctx) + + def __repr__(self): + return 'INT' + + +class IntRange(IntParamType): + """A parameter that works similar to :data:`click.INT` but restricts + the value to fit into a range. The default behavior is to fail if the + value falls outside the range, but it can also be silently clamped + between the two edges. + + See :ref:`ranges` for an example. + """ + name = 'integer range' + + def __init__(self, min=None, max=None, clamp=False): + self.min = min + self.max = max + self.clamp = clamp + + def convert(self, value, param, ctx): + rv = IntParamType.convert(self, value, param, ctx) + if self.clamp: + if self.min is not None and rv < self.min: + return self.min + if self.max is not None and rv > self.max: + return self.max + if self.min is not None and rv < self.min or \ + self.max is not None and rv > self.max: + if self.min is None: + self.fail('%s is bigger than the maximum valid value ' + '%s.' % (rv, self.max), param, ctx) + elif self.max is None: + self.fail('%s is smaller than the minimum valid value ' + '%s.' % (rv, self.min), param, ctx) + else: + self.fail('%s is not in the valid range of %s to %s.' + % (rv, self.min, self.max), param, ctx) + return rv + + def __repr__(self): + return 'IntRange(%r, %r)' % (self.min, self.max) + + +class BoolParamType(ParamType): + name = 'boolean' + + def convert(self, value, param, ctx): + if isinstance(value, bool): + return bool(value) + value = value.lower() + if value in ('true', '1', 'yes', 'y'): + return True + elif value in ('false', '0', 'no', 'n'): + return False + self.fail('%s is not a valid boolean' % value, param, ctx) + + def __repr__(self): + return 'BOOL' + + +class FloatParamType(ParamType): + name = 'float' + + def convert(self, value, param, ctx): + try: + return float(value) + except (UnicodeError, ValueError): + self.fail('%s is not a valid floating point value' % + value, param, ctx) + + def __repr__(self): + return 'FLOAT' + + +class UUIDParameterType(ParamType): + name = 'uuid' + + def convert(self, value, param, ctx): + import uuid + try: + if PY2 and isinstance(value, text_type): + value = value.encode('ascii') + return uuid.UUID(value) + except (UnicodeError, ValueError): + self.fail('%s is not a valid UUID value' % value, param, ctx) + + def __repr__(self): + return 'UUID' + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or + upon first IO. The default is to be non lazy for standard input and + output streams as well as files opened for reading, lazy otherwise. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + name = 'filename' + envvar_list_splitter = os.path.pathsep + + def __init__(self, mode='r', encoding=None, errors='strict', lazy=None, + atomic=False): + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def resolve_lazy_flag(self, value): + if self.lazy is not None: + return self.lazy + if value == '-': + return False + elif 'w' in self.mode: + return True + return False + + def convert(self, value, param, ctx): + try: + if hasattr(value, 'read') or hasattr(value, 'write'): + return value + + lazy = self.resolve_lazy_flag(value) + + if lazy: + f = LazyFile(value, self.mode, self.encoding, self.errors, + atomic=self.atomic) + if ctx is not None: + ctx.call_on_close(f.close_intelligently) + return f + + f, should_close = open_stream(value, self.mode, + self.encoding, self.errors, + atomic=self.atomic) + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + return f + except (IOError, OSError) as e: + self.fail('Could not open file: %s: %s' % ( + filename_to_ui(value), + get_streerror(e), + ), param, ctx) + + +class Path(ParamType): + """The path type is similar to the :class:`File` type but it performs + different checks. First of all, instead of returning an open file + handle it returns just the filename. Secondly, it can perform various + basic checks about what the file or directory should be. + + .. versionchanged:: 6.0 + `allow_dash` was added. + + :param exists: if set to true, the file or directory needs to exist for + this value to be valid. If this is not required and a + file does indeed not exist, then all further checks are + silently skipped. + :param file_okay: controls if a file is a possible value. + :param dir_okay: controls if a directory is a possible value. + :param writable: if true, a writable check is performed. + :param readable: if true, a readable check is performed. + :param resolve_path: if this is true, then the path is fully resolved + before the value is passed onwards. This means + that it's absolute and symlinks are resolved. + :param allow_dash: If this is set to `True`, a single dash to indicate + standard streams is permitted. + :param type: optionally a string type that should be used to + represent the path. The default is `None` which + means the return value will be either bytes or + unicode depending on what makes most sense given the + input data Click deals with. + """ + envvar_list_splitter = os.path.pathsep + + def __init__(self, exists=False, file_okay=True, dir_okay=True, + writable=False, readable=True, resolve_path=False, + allow_dash=False, path_type=None): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.writable = writable + self.readable = readable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name = 'file' + self.path_type = 'File' + if self.dir_okay and not self.file_okay: + self.name = 'directory' + self.path_type = 'Directory' + else: + self.name = 'path' + self.path_type = 'Path' + + def coerce_path_result(self, rv): + if self.type is not None and not isinstance(rv, self.type): + if self.type is text_type: + rv = rv.decode(get_filesystem_encoding()) + else: + rv = rv.encode(get_filesystem_encoding()) + return rv + + def convert(self, value, param, ctx): + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b'-', '-') + + if not is_dash: + if self.resolve_path: + rv = os.path.realpath(rv) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail('%s "%s" does not exist.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail('%s "%s" is a file.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail('%s "%s" is a directory.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + if self.writable and not os.access(value, os.W_OK): + self.fail('%s "%s" is not writable.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + if self.readable and not os.access(value, os.R_OK): + self.fail('%s "%s" is not readable.' % ( + self.path_type, + filename_to_ui(value) + ), param, ctx) + + return self.coerce_path_result(rv) + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types): + self.types = [convert_type(ty) for ty in types] + + @property + def name(self): + return "<" + " ".join(ty.name for ty in self.types) + ">" + + @property + def arity(self): + return len(self.types) + + def convert(self, value, param, ctx): + if len(value) != len(self.types): + raise TypeError('It would appear that nargs is set to conflict ' + 'with the composite type arity.') + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty, default=None): + """Converts a callable or python ty into the most appropriate param + ty. + """ + guessed_type = False + if ty is None and default is not None: + if isinstance(default, tuple): + ty = tuple(map(type, default)) + else: + ty = type(default) + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + if isinstance(ty, ParamType): + return ty + if ty is text_type or ty is str or ty is None: + return STRING + if ty is int: + return INT + # Booleans are only okay if not guessed. This is done because for + # flags the default value is actually a bit of a lie in that it + # indicates which of the flags is the one we want. See get_default() + # for more information. + if ty is bool and not guessed_type: + return BOOL + if ty is float: + return FLOAT + if guessed_type: + return STRING + + # Catch a common mistake + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError('Attempted to use an uninstantiated ' + 'parameter type (%s).' % ty) + except TypeError: + pass + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but internally +#: no string conversion takes place. This is necessary to achieve the +#: same bytes/unicode behavior on Python 2/3 in situations where you want +#: to not convert argument types. This is usually useful when working +#: with file paths as they can appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/Lib/site-packages/click/utils.py b/Lib/site-packages/click/utils.py new file mode 100644 index 0000000..eee626d --- /dev/null +++ b/Lib/site-packages/click/utils.py @@ -0,0 +1,415 @@ +import os +import sys + +from .globals import resolve_color_default + +from ._compat import text_type, open_stream, get_filesystem_encoding, \ + get_streerror, string_types, PY2, binary_streams, text_streams, \ + filename_to_ui, auto_wrap_for_ansi, strip_ansi, should_strip_ansi, \ + _default_text_stdout, _default_text_stderr, is_bytes, WIN + +if not PY2: + from ._compat import _find_binary_writer +elif WIN: + from ._winconsole import _get_windows_argv, \ + _hash_py_argv, _initial_argv_hash + + +echo_native_types = string_types + (bytes, bytearray) + + +def _posixify(name): + return '-'.join(name.split()).lower() + + +def safecall(func): + """Wraps a function so that it swallows exceptions.""" + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except Exception: + pass + return wrapper + + +def make_str(value): + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(get_filesystem_encoding()) + except UnicodeError: + return value.decode('utf-8', 'replace') + return text_type(value) + + +def make_default_short_help(help, max_length=45): + words = help.split() + total_length = 0 + result = [] + done = False + + for word in words: + if word[-1:] == '.': + done = True + new_length = result and 1 + len(word) or len(word) + if total_length + new_length > max_length: + result.append('...') + done = True + else: + if result: + result.append(' ') + result.append(word) + if done: + break + total_length += new_length + + return ''.join(result) + + +class LazyFile(object): + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__(self, filename, mode='r', encoding=None, errors='strict', + atomic=False): + self.name = filename + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + + if filename == '-': + self._f, self.should_close = open_stream(filename, mode, + encoding, errors) + else: + if 'r' in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name): + return getattr(self.open(), name) + + def __repr__(self): + if self._f is not None: + return repr(self._f) + return '' % (self.name, self.mode) + + def open(self): + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream(self.name, self.mode, + self.encoding, + self.errors, + atomic=self.atomic) + except (IOError, OSError) as e: + from .exceptions import FileError + raise FileError(self.name, hint=get_streerror(e)) + self._f = rv + return rv + + def close(self): + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self): + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + self.close_intelligently() + + def __iter__(self): + self.open() + return iter(self._f) + + +class KeepOpenFile(object): + + def __init__(self, file): + self._file = file + + def __getattr__(self, name): + return getattr(self._file, name) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + pass + + def __repr__(self): + return repr(self._file) + + def __iter__(self): + return iter(self._file) + + +def echo(message=None, file=None, nl=True, err=False, color=None): + """Prints a message plus a newline to the given file or stdout. On + first sight, this looks like the print function, but it has improved + support for handling Unicode and binary data that does not fail no + matter how badly configured the system is. + + Primarily it means that you can print binary data as well as Unicode + data on both 2.x and 3.x to the given file in the most appropriate way + possible. This is a very carefree function as in that it will try its + best to not fail. As of Click 6.0 this includes support for unicode + output on the Windows console. + + In addition to that, if `colorama`_ is installed, the echo function will + also support clever handling of ANSI codes. Essentially it will then + do the following: + + - add transparent handling of ANSI color codes on Windows. + - hide ANSI codes automatically if the destination file is not a + terminal. + + .. _colorama: http://pypi.python.org/pypi/colorama + + .. versionchanged:: 6.0 + As of Click 6.0 the echo function will properly support unicode + output on the windows console. Not that click does not modify + the interpreter in any way which means that `sys.stdout` or the + print statement or function will still not provide unicode support. + + .. versionchanged:: 2.0 + Starting with version 2.0 of Click, the echo function will work + with colorama if it's installed. + + .. versionadded:: 3.0 + The `err` parameter was added. + + .. versionchanged:: 4.0 + Added the `color` flag. + + :param message: the message to print + :param file: the file to write to (defaults to ``stdout``) + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``. This is faster and easier than calling + :func:`get_text_stderr` yourself. + :param nl: if set to `True` (the default) a newline is printed afterwards. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, echo_native_types): + message = text_type(message) + + if nl: + message = message or u'' + if isinstance(message, text_type): + message += u'\n' + else: + message += b'\n' + + # If there is a message, and we're in Python 3, and the value looks + # like bytes, we manually need to find the binary stream and write the + # message in there. This is done separately so that most stream + # types will work as you would expect. Eg: you can write to StringIO + # for other cases. + if message and not PY2 and is_bytes(message): + binary_file = _find_binary_writer(file) + if binary_file is not None: + file.flush() + binary_file.write(message) + binary_file.flush() + return + + # ANSI-style support. If there is no message or we are dealing with + # bytes nothing is happening. If we are connected to a file we want + # to strip colors. If we are on windows we either wrap the stream + # to strip the color or we use the colorama support to translate the + # ansi codes to API calls. + if message and not is_bytes(message): + color = resolve_color_default(color) + if should_strip_ansi(file, color): + message = strip_ansi(message) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) + elif not color: + message = strip_ansi(message) + + if message: + file.write(message) + file.flush() + + +def get_binary_stream(name): + """Returns a system stream for byte processing. This essentially + returns the stream from the sys module with the given name but it + solves some compatibility issues between different Python versions. + Primarily this function is necessary for getting binary streams on + Python 3. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError('Unknown standard stream %r' % name) + return opener() + + +def get_text_stream(name, encoding=None, errors='strict'): + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts on Python 3 + for already correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError('Unknown standard stream %r' % name) + return opener(encoding, errors) + + +def open_file(filename, mode='r', encoding=None, errors='strict', + lazy=False, atomic=False): + """This is similar to how the :class:`File` works but for manual + usage. Files are opened non lazy by default. This can open regular + files as well as stdin/stdout if ``'-'`` is passed. + + If stdin/stdout is returned the stream is wrapped so that the context + manager will not close the stream accidentally. This makes it possible + to always use the function like this without having to worry to + accidentally close a standard stream:: + + with open_file(filename) as f: + ... + + .. versionadded:: 3.0 + + :param filename: the name of the file to open (or ``'-'`` for stdin/stdout). + :param mode: the mode in which to open the file. + :param encoding: the encoding to use. + :param errors: the error handling for this file. + :param lazy: can be flipped to true to open the file lazily. + :param atomic: in atomic mode writes go into a temporary file and it's + moved on close. + """ + if lazy: + return LazyFile(filename, mode, encoding, errors, atomic=atomic) + f, should_close = open_stream(filename, mode, encoding, errors, + atomic=atomic) + if not should_close: + f = KeepOpenFile(f) + return f + + +def get_os_args(): + """This returns the argument part of sys.argv in the most appropriate + form for processing. What this means is that this return value is in + a format that works for Click to process but does not necessarily + correspond well to what's actually standard for the interpreter. + + On most environments the return value is ``sys.argv[:1]`` unchanged. + However if you are on Windows and running Python 2 the return value + will actually be a list of unicode strings instead because the + default behavior on that platform otherwise will not be able to + carry all possible values that sys.argv can have. + + .. versionadded:: 6.0 + """ + # We can only extract the unicode argv if sys.argv has not been + # changed since the startup of the application. + if PY2 and WIN and _initial_argv_hash == _hash_py_argv(): + return _get_windows_argv() + return sys.argv[1:] + + +def format_filename(filename, shorten=False): + """Formats a filename for user display. The main purpose of this + function is to ensure that the filename can be displayed at all. This + will decode the filename to unicode if necessary in a way that it will + not fail. Optionally, it can shorten the filename to not include the + full path to the filename. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + return filename_to_ui(filename) + + +def get_app_dir(app_name, roaming=True, force_posix=False): + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Win XP (roaming): + ``C:\Documents and Settings\\Local Settings\Application Data\Foo Bar`` + Win XP (not roaming): + ``C:\Documents and Settings\\Application Data\Foo Bar`` + Win 7 (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Win 7 (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no affect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = roaming and 'APPDATA' or 'LOCALAPPDATA' + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser('~') + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser('~/.' + _posixify(app_name))) + if sys.platform == 'darwin': + return os.path.join(os.path.expanduser( + '~/Library/Application Support'), app_name) + return os.path.join( + os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), + _posixify(app_name)) diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/DESCRIPTION.rst b/Lib/site-packages/colorama-0.3.9.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..bbde73c --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/DESCRIPTION.rst @@ -0,0 +1,348 @@ +.. image:: https://img.shields.io/pypi/v/colorama.svg + :target: https://pypi.python.org/pypi/colorama/ + :alt: Latest Version + +.. image:: https://travis-ci.org/tartley/colorama.svg?branch=master + :target: https://travis-ci.org/tartley/colorama + :alt: Build Status + +Download and docs: + http://pypi.python.org/pypi/colorama +Source code & Development: + https://github.com/tartley/colorama + +Description +=========== + +Makes ANSI escape character sequences (for producing colored terminal text and +cursor positioning) work under MS Windows. + +ANSI escape character sequences have long been used to produce colored terminal +text and cursor positioning on Unix and Macs. Colorama makes this work on +Windows, too, by wrapping ``stdout``, stripping ANSI sequences it finds (which +would appear as gobbledygook in the output), and converting them into the +appropriate win32 calls to modify the state of the terminal. On other platforms, +Colorama does nothing. + +Colorama also provides some shortcuts to help generate ANSI sequences +but works fine in conjunction with any other ANSI sequence generation library, +such as the venerable Termcolor (http://pypi.python.org/pypi/termcolor) +or the fabulous Blessings (https://pypi.python.org/pypi/blessings). + +This has the upshot of providing a simple cross-platform API for printing +colored terminal text from Python, and has the happy side-effect that existing +applications or libraries which use ANSI sequences to produce colored output on +Linux or Macs can now also work on Windows, simply by calling +``colorama.init()``. + +An alternative approach is to install ``ansi.sys`` on Windows machines, which +provides the same behaviour for all applications running in terminals. Colorama +is intended for situations where that isn't easy (e.g., maybe your app doesn't +have an installer.) + +Demo scripts in the source code repository print some colored text using +ANSI sequences. Compare their output under Gnome-terminal's built in ANSI +handling, versus on Windows Command-Prompt using Colorama: + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/ubuntu-demo.png + :width: 661 + :height: 357 + :alt: ANSI sequences on Ubuntu under gnome-terminal. + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/windows-demo.png + :width: 668 + :height: 325 + :alt: Same ANSI sequences on Windows, using Colorama. + +These screengrabs show that, on Windows, Colorama does not support ANSI 'dim +text'; it looks the same as 'normal text'. + + +License +======= + +Copyright Jonathan Hartley 2013. BSD 3-Clause license; see LICENSE file. + + +Dependencies +============ + +None, other than Python. Tested on Python 2.5.5, 2.6.5, 2.7, 3.1.2, 3.2, 3.3, +3.4 and 3.5. + +Usage +===== + +Initialisation +-------------- + +Applications should initialise Colorama using: + +.. code-block:: python + + from colorama import init + init() + +On Windows, calling ``init()`` will filter ANSI escape sequences out of any +text sent to ``stdout`` or ``stderr``, and replace them with equivalent Win32 +calls. + +On other platforms, calling ``init()`` has no effect (unless you request other +optional functionality; see "Init Keyword Args", below). By design, this permits +applications to call ``init()`` unconditionally on all platforms, after which +ANSI output should just work. + +To stop using colorama before your program exits, simply call ``deinit()``. +This will restore ``stdout`` and ``stderr`` to their original values, so that +Colorama is disabled. To resume using Colorama again, call ``reinit()``; it is +cheaper to calling ``init()`` again (but does the same thing). + + +Colored Output +-------------- + +Cross-platform printing of colored text can then be done using Colorama's +constant shorthand for ANSI escape sequences: + +.. code-block:: python + + from colorama import Fore, Back, Style + print(Fore.RED + 'some red text') + print(Back.GREEN + 'and with a green background') + print(Style.DIM + 'and in dim text') + print(Style.RESET_ALL) + print('back to normal now') + +...or simply by manually printing ANSI sequences from your own code: + +.. code-block:: python + + print('\033[31m' + 'some red text') + print('\033[30m') # and reset to default color + +...or, Colorama can be used happily in conjunction with existing ANSI libraries +such as Termcolor: + +.. code-block:: python + + from colorama import init + from termcolor import colored + + # use Colorama to make Termcolor work on Windows too + init() + + # then use Termcolor for all colored text output + print(colored('Hello, World!', 'green', 'on_red')) + +Available formatting constants are:: + + Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Style: DIM, NORMAL, BRIGHT, RESET_ALL + +``Style.RESET_ALL`` resets foreground, background, and brightness. Colorama will +perform this reset automatically on program exit. + + +Cursor Positioning +------------------ + +ANSI codes to reposition the cursor are supported. See ``demos/demo06.py`` for +an example of how to generate them. + + +Init Keyword Args +----------------- + +``init()`` accepts some ``**kwargs`` to override default behaviour. + +init(autoreset=False): + If you find yourself repeatedly sending reset sequences to turn off color + changes at the end of every print, then ``init(autoreset=True)`` will + automate that: + + .. code-block:: python + + from colorama import init + init(autoreset=True) + print(Fore.RED + 'some red text') + print('automatically back to default color again') + +init(strip=None): + Pass ``True`` or ``False`` to override whether ansi codes should be + stripped from the output. The default behaviour is to strip if on Windows + or if output is redirected (not a tty). + +init(convert=None): + Pass ``True`` or ``False`` to override whether to convert ANSI codes in the + output into win32 calls. The default behaviour is to convert if on Windows + and output is to a tty (terminal). + +init(wrap=True): + On Windows, colorama works by replacing ``sys.stdout`` and ``sys.stderr`` + with proxy objects, which override the ``.write()`` method to do their work. + If this wrapping causes you problems, then this can be disabled by passing + ``init(wrap=False)``. The default behaviour is to wrap if ``autoreset`` or + ``strip`` or ``convert`` are True. + + When wrapping is disabled, colored printing on non-Windows platforms will + continue to work as normal. To do cross-platform colored output, you can + use Colorama's ``AnsiToWin32`` proxy directly: + + .. code-block:: python + + import sys + from colorama import init, AnsiToWin32 + init(wrap=False) + stream = AnsiToWin32(sys.stderr).stream + + # Python 2 + print >>stream, Fore.BLUE + 'blue text on stderr' + + # Python 3 + print(Fore.BLUE + 'blue text on stderr', file=stream) + + +Status & Known Problems +======================= + +I've personally only tested it on Windows XP (CMD, Console2), Ubuntu +(gnome-terminal, xterm), and OS X. + +Some presumably valid ANSI sequences aren't recognised (see details below), +but to my knowledge nobody has yet complained about this. Puzzling. + +See outstanding issues and wishlist: +https://github.com/tartley/colorama/issues + +If anything doesn't work for you, or doesn't do what you expected or hoped for, +I'd love to hear about it on that issues list, would be delighted by patches, +and would be happy to grant commit access to anyone who submits a working patch +or two. + + +Recognised ANSI Sequences +========================= + +ANSI sequences generally take the form: + + ESC [ ; ... + +Where ```` is an integer, and ```` is a single letter. Zero or +more params are passed to a ````. If no params are passed, it is +generally synonymous with passing a single zero. No spaces exist in the +sequence; they have been inserted here simply to read more easily. + +The only ANSI sequences that colorama converts into win32 calls are:: + + ESC [ 0 m # reset all (colors and brightness) + ESC [ 1 m # bright + ESC [ 2 m # dim (looks same as normal brightness) + ESC [ 22 m # normal brightness + + # FOREGROUND: + ESC [ 30 m # black + ESC [ 31 m # red + ESC [ 32 m # green + ESC [ 33 m # yellow + ESC [ 34 m # blue + ESC [ 35 m # magenta + ESC [ 36 m # cyan + ESC [ 37 m # white + ESC [ 39 m # reset + + # BACKGROUND + ESC [ 40 m # black + ESC [ 41 m # red + ESC [ 42 m # green + ESC [ 43 m # yellow + ESC [ 44 m # blue + ESC [ 45 m # magenta + ESC [ 46 m # cyan + ESC [ 47 m # white + ESC [ 49 m # reset + + # cursor positioning + ESC [ y;x H # position cursor at x across, y down + ESC [ y;x f # position cursor at x across, y down + ESC [ n A # move cursor n lines up + ESC [ n B # move cursor n lines down + ESC [ n C # move cursor n characters forward + ESC [ n D # move cursor n characters backward + + # clear the screen + ESC [ mode J # clear the screen + + # clear the line + ESC [ mode K # clear the line + +Multiple numeric params to the ``'m'`` command can be combined into a single +sequence:: + + ESC [ 36 ; 45 ; 1 m # bright cyan text on magenta background + +All other ANSI sequences of the form ``ESC [ ; ... `` +are silently stripped from the output on Windows. + +Any other form of ANSI sequence, such as single-character codes or alternative +initial characters, are not recognised or stripped. It would be cool to add +them though. Let me know if it would be useful for you, via the Issues on +GitHub. + + +Development +=========== + +Help and fixes welcome! + +Running tests requires: + +- Michael Foord's ``mock`` module to be installed. +- Tests are written using 2010-era updates to ``unittest``, and require + Python 2.7 or greater, OR to have Michael Foord's ``unittest2`` module + installed. + +To run tests:: + + python -m unittest discover -p *_test.py + +This, like a few other handy commands, is captured in a ``Makefile``. + +If you use nose to run the tests, you must pass the ``-s`` flag; otherwise, +``nosetests`` applies its own proxy to ``stdout``, which confuses the unit +tests. + + +Thanks +====== +* Marc Schlaich (schlamar) for a ``setup.py`` fix for Python2.5. +* Marc Abramowitz, reported & fixed a crash on exit with closed ``stdout``, + providing a solution to issue #7's setuptools/distutils debate, + and other fixes. +* User 'eryksun', for guidance on correctly instantiating ``ctypes.windll``. +* Matthew McCormick for politely pointing out a longstanding crash on non-Win. +* Ben Hoyt, for a magnificent fix under 64-bit Windows. +* Jesse at Empty Square for submitting a fix for examples in the README. +* User 'jamessp', an observant documentation fix for cursor positioning. +* User 'vaal1239', Dave Mckee & Lackner Kristof for a tiny but much-needed Win7 + fix. +* Julien Stuyck, for wisely suggesting Python3 compatible updates to README. +* Daniel Griffith for multiple fabulous patches. +* Oscar Lesta for a valuable fix to stop ANSI chars being sent to non-tty + output. +* Roger Binns, for many suggestions, valuable feedback, & bug reports. +* Tim Golden for thought and much appreciated feedback on the initial idea. +* User 'Zearin' for updates to the README file. +* John Szakmeister for adding support for light colors +* Charles Merriam for adding documentation to demos +* Jurko for a fix on 64-bit Windows CPython2.5 w/o ctypes +* Florian Bruhin for a fix when stdout or stderr are None +* Thomas Weininger for fixing ValueError on Windows +* Remi Rampin for better Github integration and fixes to the README file +* Simeon Visser for closing a file handle using 'with' and updating classifiers + to include Python 3.3 and 3.4 +* Andy Neff for fixing RESET of LIGHT_EX colors. +* Jonathan Hartley for the initial idea and implementation. + + + diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/INSTALLER b/Lib/site-packages/colorama-0.3.9.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/METADATA b/Lib/site-packages/colorama-0.3.9.dist-info/METADATA new file mode 100644 index 0000000..7017c04 --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/METADATA @@ -0,0 +1,375 @@ +Metadata-Version: 2.0 +Name: colorama +Version: 0.3.9 +Summary: Cross-platform colored terminal text. +Home-page: https://github.com/tartley/colorama +Author: Arnon Yaari +Author-email: tartley@tartley.com +License: BSD +Keywords: color colour terminal text ansi windows crossplatform xplatform +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.5 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.1 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Terminals + +.. image:: https://img.shields.io/pypi/v/colorama.svg + :target: https://pypi.python.org/pypi/colorama/ + :alt: Latest Version + +.. image:: https://travis-ci.org/tartley/colorama.svg?branch=master + :target: https://travis-ci.org/tartley/colorama + :alt: Build Status + +Download and docs: + http://pypi.python.org/pypi/colorama +Source code & Development: + https://github.com/tartley/colorama + +Description +=========== + +Makes ANSI escape character sequences (for producing colored terminal text and +cursor positioning) work under MS Windows. + +ANSI escape character sequences have long been used to produce colored terminal +text and cursor positioning on Unix and Macs. Colorama makes this work on +Windows, too, by wrapping ``stdout``, stripping ANSI sequences it finds (which +would appear as gobbledygook in the output), and converting them into the +appropriate win32 calls to modify the state of the terminal. On other platforms, +Colorama does nothing. + +Colorama also provides some shortcuts to help generate ANSI sequences +but works fine in conjunction with any other ANSI sequence generation library, +such as the venerable Termcolor (http://pypi.python.org/pypi/termcolor) +or the fabulous Blessings (https://pypi.python.org/pypi/blessings). + +This has the upshot of providing a simple cross-platform API for printing +colored terminal text from Python, and has the happy side-effect that existing +applications or libraries which use ANSI sequences to produce colored output on +Linux or Macs can now also work on Windows, simply by calling +``colorama.init()``. + +An alternative approach is to install ``ansi.sys`` on Windows machines, which +provides the same behaviour for all applications running in terminals. Colorama +is intended for situations where that isn't easy (e.g., maybe your app doesn't +have an installer.) + +Demo scripts in the source code repository print some colored text using +ANSI sequences. Compare their output under Gnome-terminal's built in ANSI +handling, versus on Windows Command-Prompt using Colorama: + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/ubuntu-demo.png + :width: 661 + :height: 357 + :alt: ANSI sequences on Ubuntu under gnome-terminal. + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/windows-demo.png + :width: 668 + :height: 325 + :alt: Same ANSI sequences on Windows, using Colorama. + +These screengrabs show that, on Windows, Colorama does not support ANSI 'dim +text'; it looks the same as 'normal text'. + + +License +======= + +Copyright Jonathan Hartley 2013. BSD 3-Clause license; see LICENSE file. + + +Dependencies +============ + +None, other than Python. Tested on Python 2.5.5, 2.6.5, 2.7, 3.1.2, 3.2, 3.3, +3.4 and 3.5. + +Usage +===== + +Initialisation +-------------- + +Applications should initialise Colorama using: + +.. code-block:: python + + from colorama import init + init() + +On Windows, calling ``init()`` will filter ANSI escape sequences out of any +text sent to ``stdout`` or ``stderr``, and replace them with equivalent Win32 +calls. + +On other platforms, calling ``init()`` has no effect (unless you request other +optional functionality; see "Init Keyword Args", below). By design, this permits +applications to call ``init()`` unconditionally on all platforms, after which +ANSI output should just work. + +To stop using colorama before your program exits, simply call ``deinit()``. +This will restore ``stdout`` and ``stderr`` to their original values, so that +Colorama is disabled. To resume using Colorama again, call ``reinit()``; it is +cheaper to calling ``init()`` again (but does the same thing). + + +Colored Output +-------------- + +Cross-platform printing of colored text can then be done using Colorama's +constant shorthand for ANSI escape sequences: + +.. code-block:: python + + from colorama import Fore, Back, Style + print(Fore.RED + 'some red text') + print(Back.GREEN + 'and with a green background') + print(Style.DIM + 'and in dim text') + print(Style.RESET_ALL) + print('back to normal now') + +...or simply by manually printing ANSI sequences from your own code: + +.. code-block:: python + + print('\033[31m' + 'some red text') + print('\033[30m') # and reset to default color + +...or, Colorama can be used happily in conjunction with existing ANSI libraries +such as Termcolor: + +.. code-block:: python + + from colorama import init + from termcolor import colored + + # use Colorama to make Termcolor work on Windows too + init() + + # then use Termcolor for all colored text output + print(colored('Hello, World!', 'green', 'on_red')) + +Available formatting constants are:: + + Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Style: DIM, NORMAL, BRIGHT, RESET_ALL + +``Style.RESET_ALL`` resets foreground, background, and brightness. Colorama will +perform this reset automatically on program exit. + + +Cursor Positioning +------------------ + +ANSI codes to reposition the cursor are supported. See ``demos/demo06.py`` for +an example of how to generate them. + + +Init Keyword Args +----------------- + +``init()`` accepts some ``**kwargs`` to override default behaviour. + +init(autoreset=False): + If you find yourself repeatedly sending reset sequences to turn off color + changes at the end of every print, then ``init(autoreset=True)`` will + automate that: + + .. code-block:: python + + from colorama import init + init(autoreset=True) + print(Fore.RED + 'some red text') + print('automatically back to default color again') + +init(strip=None): + Pass ``True`` or ``False`` to override whether ansi codes should be + stripped from the output. The default behaviour is to strip if on Windows + or if output is redirected (not a tty). + +init(convert=None): + Pass ``True`` or ``False`` to override whether to convert ANSI codes in the + output into win32 calls. The default behaviour is to convert if on Windows + and output is to a tty (terminal). + +init(wrap=True): + On Windows, colorama works by replacing ``sys.stdout`` and ``sys.stderr`` + with proxy objects, which override the ``.write()`` method to do their work. + If this wrapping causes you problems, then this can be disabled by passing + ``init(wrap=False)``. The default behaviour is to wrap if ``autoreset`` or + ``strip`` or ``convert`` are True. + + When wrapping is disabled, colored printing on non-Windows platforms will + continue to work as normal. To do cross-platform colored output, you can + use Colorama's ``AnsiToWin32`` proxy directly: + + .. code-block:: python + + import sys + from colorama import init, AnsiToWin32 + init(wrap=False) + stream = AnsiToWin32(sys.stderr).stream + + # Python 2 + print >>stream, Fore.BLUE + 'blue text on stderr' + + # Python 3 + print(Fore.BLUE + 'blue text on stderr', file=stream) + + +Status & Known Problems +======================= + +I've personally only tested it on Windows XP (CMD, Console2), Ubuntu +(gnome-terminal, xterm), and OS X. + +Some presumably valid ANSI sequences aren't recognised (see details below), +but to my knowledge nobody has yet complained about this. Puzzling. + +See outstanding issues and wishlist: +https://github.com/tartley/colorama/issues + +If anything doesn't work for you, or doesn't do what you expected or hoped for, +I'd love to hear about it on that issues list, would be delighted by patches, +and would be happy to grant commit access to anyone who submits a working patch +or two. + + +Recognised ANSI Sequences +========================= + +ANSI sequences generally take the form: + + ESC [ ; ... + +Where ```` is an integer, and ```` is a single letter. Zero or +more params are passed to a ````. If no params are passed, it is +generally synonymous with passing a single zero. No spaces exist in the +sequence; they have been inserted here simply to read more easily. + +The only ANSI sequences that colorama converts into win32 calls are:: + + ESC [ 0 m # reset all (colors and brightness) + ESC [ 1 m # bright + ESC [ 2 m # dim (looks same as normal brightness) + ESC [ 22 m # normal brightness + + # FOREGROUND: + ESC [ 30 m # black + ESC [ 31 m # red + ESC [ 32 m # green + ESC [ 33 m # yellow + ESC [ 34 m # blue + ESC [ 35 m # magenta + ESC [ 36 m # cyan + ESC [ 37 m # white + ESC [ 39 m # reset + + # BACKGROUND + ESC [ 40 m # black + ESC [ 41 m # red + ESC [ 42 m # green + ESC [ 43 m # yellow + ESC [ 44 m # blue + ESC [ 45 m # magenta + ESC [ 46 m # cyan + ESC [ 47 m # white + ESC [ 49 m # reset + + # cursor positioning + ESC [ y;x H # position cursor at x across, y down + ESC [ y;x f # position cursor at x across, y down + ESC [ n A # move cursor n lines up + ESC [ n B # move cursor n lines down + ESC [ n C # move cursor n characters forward + ESC [ n D # move cursor n characters backward + + # clear the screen + ESC [ mode J # clear the screen + + # clear the line + ESC [ mode K # clear the line + +Multiple numeric params to the ``'m'`` command can be combined into a single +sequence:: + + ESC [ 36 ; 45 ; 1 m # bright cyan text on magenta background + +All other ANSI sequences of the form ``ESC [ ; ... `` +are silently stripped from the output on Windows. + +Any other form of ANSI sequence, such as single-character codes or alternative +initial characters, are not recognised or stripped. It would be cool to add +them though. Let me know if it would be useful for you, via the Issues on +GitHub. + + +Development +=========== + +Help and fixes welcome! + +Running tests requires: + +- Michael Foord's ``mock`` module to be installed. +- Tests are written using 2010-era updates to ``unittest``, and require + Python 2.7 or greater, OR to have Michael Foord's ``unittest2`` module + installed. + +To run tests:: + + python -m unittest discover -p *_test.py + +This, like a few other handy commands, is captured in a ``Makefile``. + +If you use nose to run the tests, you must pass the ``-s`` flag; otherwise, +``nosetests`` applies its own proxy to ``stdout``, which confuses the unit +tests. + + +Thanks +====== +* Marc Schlaich (schlamar) for a ``setup.py`` fix for Python2.5. +* Marc Abramowitz, reported & fixed a crash on exit with closed ``stdout``, + providing a solution to issue #7's setuptools/distutils debate, + and other fixes. +* User 'eryksun', for guidance on correctly instantiating ``ctypes.windll``. +* Matthew McCormick for politely pointing out a longstanding crash on non-Win. +* Ben Hoyt, for a magnificent fix under 64-bit Windows. +* Jesse at Empty Square for submitting a fix for examples in the README. +* User 'jamessp', an observant documentation fix for cursor positioning. +* User 'vaal1239', Dave Mckee & Lackner Kristof for a tiny but much-needed Win7 + fix. +* Julien Stuyck, for wisely suggesting Python3 compatible updates to README. +* Daniel Griffith for multiple fabulous patches. +* Oscar Lesta for a valuable fix to stop ANSI chars being sent to non-tty + output. +* Roger Binns, for many suggestions, valuable feedback, & bug reports. +* Tim Golden for thought and much appreciated feedback on the initial idea. +* User 'Zearin' for updates to the README file. +* John Szakmeister for adding support for light colors +* Charles Merriam for adding documentation to demos +* Jurko for a fix on 64-bit Windows CPython2.5 w/o ctypes +* Florian Bruhin for a fix when stdout or stderr are None +* Thomas Weininger for fixing ValueError on Windows +* Remi Rampin for better Github integration and fixes to the README file +* Simeon Visser for closing a file handle using 'with' and updating classifiers + to include Python 3.3 and 3.4 +* Andy Neff for fixing RESET of LIGHT_EX colors. +* Jonathan Hartley for the initial idea and implementation. + + + diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/RECORD b/Lib/site-packages/colorama-0.3.9.dist-info/RECORD new file mode 100644 index 0000000..a230bd1 --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/RECORD @@ -0,0 +1,20 @@ +colorama/__init__.py,sha256=V3-Hv_vOa-2lE5Q_0mGkdhZo-9e4XrGTW_44cU81qQY,240 +colorama/ansi.py,sha256=Fi0un-QLqRm-v7o_nKiOqyC8PapBJK7DLV_q9LKtTO0,2524 +colorama/ansitowin32.py,sha256=QrieYX2tsaWIO19P6biMa1zUCt-_abudoEp2_IdqZZU,9668 +colorama/initialise.py,sha256=cHqVJtb82OG7HUCxvQ2joG7N_CoxbIKbI_fgryZkj20,1917 +colorama/win32.py,sha256=5Hc7L1LabubrYDhdWAfRyzlt14ErP3YKDvf_zYaarLk,5426 +colorama/winterm.py,sha256=V7U7ojwG1q4n6PKripjEvW_htYQi5ueXSM3LUUoqqDY,6290 +colorama-0.3.9.dist-info/DESCRIPTION.rst,sha256=Wvxoc5cqU6Zp3KqXrZr6yfPQh35oh4_hEhDy9x4XkUs,12015 +colorama-0.3.9.dist-info/METADATA,sha256=kUDCdB_XVo_pu4TSBRJUUqsdbhyWffljmogqeui8k3I,13081 +colorama-0.3.9.dist-info/RECORD,, +colorama-0.3.9.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +colorama-0.3.9.dist-info/metadata.json,sha256=PtYxKEP8PtrANvH78Uo8ILoZnsUwCFrMqXEJf-UhWgY,1153 +colorama-0.3.9.dist-info/pbr.json,sha256=69CJVZrIaKuqSWybmv1ghLuEfP2OJPwJCc05_uo0qiY,47 +colorama-0.3.9.dist-info/top_level.txt,sha256=_Kx6-Cni2BT1PEATPhrSRxo0d7kSgfBbHf5o7IF1ABw,9 +colorama-0.3.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +colorama/__pycache__/ansi.cpython-37.pyc,, +colorama/__pycache__/ansitowin32.cpython-37.pyc,, +colorama/__pycache__/initialise.cpython-37.pyc,, +colorama/__pycache__/win32.cpython-37.pyc,, +colorama/__pycache__/winterm.cpython-37.pyc,, +colorama/__pycache__/__init__.cpython-37.pyc,, diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/WHEEL b/Lib/site-packages/colorama-0.3.9.dist-info/WHEEL new file mode 100644 index 0000000..8b6dd1b --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/metadata.json b/Lib/site-packages/colorama-0.3.9.dist-info/metadata.json new file mode 100644 index 0000000..4d3b58e --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.1", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Terminals"], "extensions": {"python.details": {"contacts": [{"email": "tartley@tartley.com", "name": "Arnon Yaari", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/tartley/colorama"}}}, "generator": "bdist_wheel (0.29.0)", "keywords": ["color", "colour", "terminal", "text", "ansi", "windows", "crossplatform", "xplatform"], "license": "BSD", "metadata_version": "2.0", "name": "colorama", "summary": "Cross-platform colored terminal text.", "version": "0.3.9"} \ No newline at end of file diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/pbr.json b/Lib/site-packages/colorama-0.3.9.dist-info/pbr.json new file mode 100644 index 0000000..0206db9 --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/pbr.json @@ -0,0 +1 @@ +{"is_release": false, "git_version": "69e4069"} \ No newline at end of file diff --git a/Lib/site-packages/colorama-0.3.9.dist-info/top_level.txt b/Lib/site-packages/colorama-0.3.9.dist-info/top_level.txt new file mode 100644 index 0000000..3fcfb51 --- /dev/null +++ b/Lib/site-packages/colorama-0.3.9.dist-info/top_level.txt @@ -0,0 +1 @@ +colorama diff --git a/Lib/site-packages/colorama/__init__.py b/Lib/site-packages/colorama/__init__.py new file mode 100644 index 0000000..f4d9ce2 --- /dev/null +++ b/Lib/site-packages/colorama/__init__.py @@ -0,0 +1,7 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.3.9' + diff --git a/Lib/site-packages/colorama/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/colorama/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..961dbbdec718c2bc4887ebf3a749ee87cb73e4c7 GIT binary patch literal 424 zcmYL_J5R$f5P4Fvi~GDKVjNo=;dUM@oHYD$ZL1U+#7d@3m=`;(b~;&0E)^A&=;BpF z*-Wa!pfO!PnqZ-~yfEQpqiU&A*Tkc;W=na;%0d4vIO+|0!+DyR7PMrPv${~Qf${+e z5Lg&Q?KKsG-vC5_CS+pBX!!yS6?}_{33)D5&16Z)hocUl6!5c}oM*T8fjYaMukH_z zPqR@~O{u2Yja*ZnEela)6|1_etTpAl`*fB|)jt_#`xXBULSSM-dezoM7eeM6UR=WD MH4NEtJ8s+i1p*mzH~;_u literal 0 HcmV?d00001 diff --git a/Lib/site-packages/colorama/__pycache__/ansi.cpython-37.pyc b/Lib/site-packages/colorama/__pycache__/ansi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce1d3722a4a74100699b20fb03ade6f5f624aef4 GIT binary patch literal 3322 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 P*Zeq4_Toyj8dv@SMc!Ak literal 0 HcmV?d00001 diff --git a/Lib/site-packages/colorama/__pycache__/win32.cpython-37.pyc b/Lib/site-packages/colorama/__pycache__/win32.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9365de69d50f6928e5fe06ac56d9e04d795775d0 GIT binary patch literal 3858 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 HQpNfiqU5ME literal 0 HcmV?d00001 diff --git a/Lib/site-packages/colorama/ansi.py b/Lib/site-packages/colorama/ansi.py new file mode 100644 index 0000000..7877658 --- /dev/null +++ b/Lib/site-packages/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/Lib/site-packages/colorama/ansitowin32.py b/Lib/site-packages/colorama/ansitowin32.py new file mode 100644 index 0000000..1d6e605 --- /dev/null +++ b/Lib/site-packages/colorama/ansitowin32.py @@ -0,0 +1,236 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +def is_stream_closed(stream): + return not hasattr(stream, 'closed') or stream.closed + + +def is_a_tty(stream): + return hasattr(stream, 'isatty') and stream.isatty() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + self.__convertor.write(text) + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not is_stream_closed(self.wrapped): + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/Lib/site-packages/colorama/initialise.py b/Lib/site-packages/colorama/initialise.py new file mode 100644 index 0000000..834962a --- /dev/null +++ b/Lib/site-packages/colorama/initialise.py @@ -0,0 +1,82 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream + + diff --git a/Lib/site-packages/colorama/win32.py b/Lib/site-packages/colorama/win32.py new file mode 100644 index 0000000..8262e35 --- /dev/null +++ b/Lib/site-packages/colorama/win32.py @@ -0,0 +1,156 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + handles = { + STDOUT: _GetStdHandle(STDOUT), + STDERR: _GetStdHandle(STDERR), + } + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in handles.values()) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = handles[stream_id] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = handles[stream_id] + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = handles[stream_id] + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = handles[stream_id] + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = handles[stream_id] + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/Lib/site-packages/colorama/winterm.py b/Lib/site-packages/colorama/winterm.py new file mode 100644 index 0000000..60309d3 --- /dev/null +++ b/Lib/site-packages/colorama/winterm.py @@ -0,0 +1,162 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + if mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + if mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/Lib/site-packages/easy_install.py b/Lib/site-packages/easy_install.py new file mode 100644 index 0000000..d87e984 --- /dev/null +++ b/Lib/site-packages/easy_install.py @@ -0,0 +1,5 @@ +"""Run the EasyInstall command""" + +if __name__ == '__main__': + from setuptools.command.easy_install import main + main() diff --git a/Lib/site-packages/flask/__init__.py b/Lib/site-packages/flask/__init__.py new file mode 100644 index 0000000..ded1982 --- /dev/null +++ b/Lib/site-packages/flask/__init__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" + flask + ~~~~~ + + A microframework based on Werkzeug. It's extensively documented + and follows best practice patterns. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +__version__ = '1.0.2' + +# utilities we import from Werkzeug and Jinja2 that are unused +# in the module but are exported as public interface. +from werkzeug.exceptions import abort +from werkzeug.utils import redirect +from jinja2 import Markup, escape + +from .app import Flask, Request, Response +from .config import Config +from .helpers import url_for, flash, send_file, send_from_directory, \ + get_flashed_messages, get_template_attribute, make_response, safe_join, \ + stream_with_context +from .globals import current_app, g, request, session, _request_ctx_stack, \ + _app_ctx_stack +from .ctx import has_request_context, has_app_context, \ + after_this_request, copy_current_request_context +from .blueprints import Blueprint +from .templating import render_template, render_template_string + +# the signals +from .signals import signals_available, template_rendered, request_started, \ + request_finished, got_request_exception, request_tearing_down, \ + appcontext_tearing_down, appcontext_pushed, \ + appcontext_popped, message_flashed, before_render_template + +# We're not exposing the actual json module but a convenient wrapper around +# it. +from . import json + +# This was the only thing that Flask used to export at one point and it had +# a more generic name. +jsonify = json.jsonify + +# backwards compat, goes away in 1.0 +from .sessions import SecureCookieSession as Session +json_available = True diff --git a/Lib/site-packages/flask/__main__.py b/Lib/site-packages/flask/__main__.py new file mode 100644 index 0000000..4aee654 --- /dev/null +++ b/Lib/site-packages/flask/__main__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" + flask.__main__ + ~~~~~~~~~~~~~~ + + Alias for flask.run for the command line. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +if __name__ == '__main__': + from .cli import main + main(as_module=True) diff --git a/Lib/site-packages/flask/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48f7f8525b4bc9fa4210e6acd6a446b481b91910 GIT binary patch literal 1829 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/app.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/app.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e778bf3bea390cf395e6534685cb3c284f8284c2 GIT binary patch literal 70879 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/blueprints.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/blueprints.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b066fcf2d724f9022d90ff90ad1dabcb202d70a4 GIT binary patch literal 20497 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/config.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/config.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c74d088ce1498ee3060f749ae5f7cc0ffbd54f09 GIT binary patch literal 9995 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 JYHs1;{{X{774-lB literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/ctx.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/ctx.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c0de6b4c46e943d1844a30687d9fa46c026ebe7 GIT binary patch literal 13965 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/globals.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/globals.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd6a05d8cfd42fc065442e022e01de6fe60b8163 GIT binary patch literal 1756 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/sessions.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/sessions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c4be3fad8abd3b481f22f13ba182ca2ab6b03cf GIT binary patch literal 12230 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 WUDZc%_0ritTwPiH%fhX4@&5p*j4`DE literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/signals.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/signals.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d8cebf0270672761a08ec195a8f51797efdc5d4c GIT binary patch literal 2417 zcmZuy&2Aev5Z+y_WLcKupEzkQ1$gMiKrAFhfdWPlq;Z_WK;Q&*`jf2zf?87c#;e^8 zNyU*6^ibzPTJ)4--=OGY?6sHn6?*D7++9TqN`cgn91e%yd^7uSeZA+Q{k~&={H^PG zf6=6An0pV<%^w(~7kSc;{OOJiWGfBEt*GUDGK~E1z3hw7Q{hEVKl45MeeKD%?7Z`2 zN42k@hxv-^V%~N0&I>OKe(+T5%8ORi$}e5H`l}zUI;jV#=cF}AYfkDz>N{y2(z=tb zLAvIo4M-bK+Jv;}q%BBWPTGdFEw7(=yE~J=@r)ir8>PZr3`}yCiPX52pB7usEgg-E zREa4k)&dns@p8L=Sp8DMpc)HG^L{{Or%qsjW3wZ znP6F-7lZ1K{WveCIypPH`|Qv6?DIQ!@37&N!47+d;|h0MCB_41a6e6Al^M0q9-ch9 z&5Tm)$pX9MfPoJxCaattB zUXmFL9QM*z=T=Pbj!s?V>amW>pqQ4OO1@5hk;|Sx+nm3<4m5cfmR-)t9nQ-h=i^*X zQj+_eznX}&+R>{p;2d2TC>IQsteMuw7*XJ!YAi6!-%Ie-i_E>2dFEfDz2D_!;OncFGmb!9~t@TROztE$R+QM9ylU za1&ROEU}z_ikTr@&+quNoduE)8kHCUa*e`8o;*c2eGC?5^UD9Z@*+5%J*~Kk3UbEG zq$qNY*DuAB4OJ{Arb44BHEA-`LQhE*cp#20Gn5=4?fTzLGMkLmAw{KrRv7|EQ+6&c z>Hp)WwYdu``B>-6*3zqJH^#1Oq(RSfPa+s$24U}(GNHSTj#Cevf*hW2>m`2_@7lvyUtK>Bb3P&Z3 z)|aQZEXqj^@RD@O>tjlCn@9b{*@FL$2QK3&np7ZNB)jb}=(W0GH@M}yw47~`=@hBA zr{SQ|O3rQ$6?|wG_8NuRhE}g8%Gf=`O`2YR$s zmsLJ5FVRZPL09j}HGCMsS;w`qlMi1aA`XqH%j>hQf<|+25S|L0s0OEA;0-uY0}ijj zi5hTt15VU{gG27I$l=Q@B5+{Mfy3wEL<`_7>n|X|D{!KvB?nH_fWvEW{*M}E_g?k+ exKFG#MDj2Q{lM@0UH_WD8Q#3nY4`k(fBylL!J57R literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/templating.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/templating.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bf832ff0190b184e44678e9281e8573ee70ed45 GIT binary patch literal 4966 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 B!+QV# literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/views.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/views.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b45fcc09d1029032cc3b4d1bd0e207828eaff595 GIT binary patch literal 4779 zcma)AOLG*-5$@MKG)O``7Q7Fyi?9i4)-Wr4al`~mparo@7_B_`;lUUln-OUGMPS$xKJ#_Ds_1?P=YhFmPLum zB8lPV9@Bln(gb8t!ftK{$yVAbc(ubc+mq2&U$@!ce`3E|zOp=~zZb-@(28jh3|eO6 zb{vHwQKHShd~ov;Q$nyiw{NVjJy>PER6-;v7#BK-V%2K=%f^A4c3zX>=};(**ZJK@ z_x%AVjI_DCC3Nm(sY2fu0nck`rlT}bd6f(7Epj&->b#<55Q@B#1v>19;5vC+yj@3A z%jksFv0*ib+Z~rX9S^O--A2)=I2}OadJ} z6Kpqt!csO=!f2B9hDm6|YB9FL)Ns>C&-wv$ld@=##bO{5U8o4B>$kf+Qbt<8Jbah! z_M@=RV7QRf${DG`n1zhR0=YFL9*Xs3Ixw8bWDoD(VKN=+DA{6aPiZlL2)BEz9cV4v zUD_+qukPN zrO@3bg9nn3VUQT;8rv2)DdkNiph91w&7l^@4fsHW*ys_dfVv}kKW;>_#Q2$RK~`47 zOi1{TH29|=^#7Xt$fm@;)hc7vIy7-;AEgm*I7Ku%>Y<4^QW_ow^JG9PND%p0(1U}s z0ImRg7zO@MJHXf0QdpTRH&N|p;PBZ*!3Oz;TM>B=Nui=7q_ru+$Zk4}`B+5ySQ@`@ zoFL)GMe*6N+7gK%col(s5`He2$+e%XkRmHR^h@mqnxed>tpn=^o7)I(&i-E?l#vQy zf9(C~Ga)7N1w^16V&ca;L5yTG`;g{?P!EIn2u{P43uvZDLIr~(Q4IlZ!h(+aZg4ZF zH-QborN}F^*BbJ}8L0dAIGhT;DrGA1*`rt>=WssL{rm2X_QpeiOKq&KJ^GGa`TfR9 zmfZ|=uyH3vblq4NgKQ&f z|A0K9b(A7BvqXSKN$4b+iqXBYUfHjlo=c^}%lePb$lA8#)sg+$@ol_2_;sG2qpvru zC$lfSk@wm;uzz%(Ui#J=S(tSvw3zX|@f!SAFs|UYieEI?*bV*&^WR7lSd|hrbX_1S zN)V+G2i|Ky180g7NCogwKC#s#B^^&WiOG&}OqB$zJw~WP1e^r0)HvdVTMxuV(%Yqg zXl#+_h{7fb+BTB5yQJSPJd}w5`LRrwke!=EIpJoO5MJMxTT2{+NuSzz=$DmSvy!`Eta6W-$q%qxqRh5XaTPf;l}6sC zJDoFPOFBSaDyf%*uY)mZSVcGa%qFtfGdt&UOM-k&{uv}Qwo2x>`d@>$=1invuA zM}AD-KcViI)RA3`y7Lo8m&K7JqtBBNb4aJNm^h23=%xOt=i={#=hSPGK1^(ncVm0{ zRSezXYV?)WLpb2>%X-IqWqDSo0t|Th{9O}1=^X2Onb`jhZtOj_SSl9+t$-1#4bw%FTz-qL>fqP6)OKzeXTRP4xorNg_z1~D5|MK$z9ZLd1aWPjwm=) z<)>gF$+z+fC0mu-+)U-}j@Uz*nDGl|0&I;TjZ0hvy`n}V%RcMW?W)tT8}{j{XYZe% z>Xt0f8q3$LPT?dkU}1qGVwTU9+k~hl$6L{UO?|4N6`r|ib@|vs}w3r6OOvlfW&yf z7(Xp`3o%YS4=4j)Vo}f3Jd^7U3s|>{3tP8aE&z$fH3qSLvnUxTnNaxbBYLAC?sie@ zgSwPPwb=2J^F}(P)UtB#_R{p2M`}R29$;T{BRDceQNFB=0SJYwV~Z#k!-6e}{N=KS zCrWyV8C^Jkj$6s*@r1<_)U!X!oBftunPiG$gNZz@#Z}E%&}&UAZY~oBi_-lL;7L=mK2qq69{3&^o!TBv9woVk)o1 z>8_CZ{0gp{k}l9iLFbvoCeMIWQe@3NqCXUTjR#Ri{0o|?Yc2bk$8GbXdm3pJ)?0V0|8LN?+ERv&P?XtT^37!Yqze^TTw2TfKBalh5Fy zzEA%Q(Q=W-)pT=PgxX|<+|!6A#^nve_wAk6uNGPM8Wrwp9-ZeP$+-=C-d*S{oc|9g C8$A{P literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/__pycache__/wrappers.cpython-37.pyc b/Lib/site-packages/flask/__pycache__/wrappers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d31458a6c58ab29177bb1df3a5ae8e700a7c279c GIT binary patch literal 6773 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/flask/_compat.py b/Lib/site-packages/flask/_compat.py new file mode 100644 index 0000000..a3b5b9c --- /dev/null +++ b/Lib/site-packages/flask/_compat.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +""" + flask._compat + ~~~~~~~~~~~~~ + + Some py2/py3 compatibility support based on a stripped down + version of six so we don't have to depend on a specific version + of it. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import sys + +PY2 = sys.version_info[0] == 2 +_identity = lambda x: x + + +if not PY2: + text_type = str + string_types = (str,) + integer_types = (int,) + + iterkeys = lambda d: iter(d.keys()) + itervalues = lambda d: iter(d.values()) + iteritems = lambda d: iter(d.items()) + + from inspect import getfullargspec as getargspec + from io import StringIO + + def reraise(tp, value, tb=None): + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + + implements_to_string = _identity + +else: + text_type = unicode + string_types = (str, unicode) + integer_types = (int, long) + + iterkeys = lambda d: d.iterkeys() + itervalues = lambda d: d.itervalues() + iteritems = lambda d: d.iteritems() + + from inspect import getargspec + from cStringIO import StringIO + + exec('def reraise(tp, value, tb=None):\n raise tp, value, tb') + + def implements_to_string(cls): + cls.__unicode__ = cls.__str__ + cls.__str__ = lambda x: x.__unicode__().encode('utf-8') + return cls + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a + # dummy metaclass for one level of class instantiation that replaces + # itself with the actual metaclass. + class metaclass(type): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +# Certain versions of pypy have a bug where clearing the exception stack +# breaks the __exit__ function in a very peculiar way. The second level of +# exception blocks is necessary because pypy seems to forget to check if an +# exception happened until the next bytecode instruction? +# +# Relevant PyPy bugfix commit: +# https://bitbucket.org/pypy/pypy/commits/77ecf91c635a287e88e60d8ddb0f4e9df4003301 +# According to ronan on #pypy IRC, it is released in PyPy2 2.3 and later +# versions. +# +# Ubuntu 14.04 has PyPy 2.2.1, which does exhibit this bug. +BROKEN_PYPY_CTXMGR_EXIT = False +if hasattr(sys, 'pypy_version_info'): + class _Mgr(object): + def __enter__(self): + return self + def __exit__(self, *args): + if hasattr(sys, 'exc_clear'): + # Python 3 (PyPy3) doesn't have exc_clear + sys.exc_clear() + try: + try: + with _Mgr(): + raise AssertionError() + except: + raise + except TypeError: + BROKEN_PYPY_CTXMGR_EXIT = True + except AssertionError: + pass diff --git a/Lib/site-packages/flask/app.py b/Lib/site-packages/flask/app.py new file mode 100644 index 0000000..87c5900 --- /dev/null +++ b/Lib/site-packages/flask/app.py @@ -0,0 +1,2315 @@ +# -*- coding: utf-8 -*- +""" + flask.app + ~~~~~~~~~ + + This module implements the central WSGI application object. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +import sys +import warnings +from datetime import timedelta +from functools import update_wrapper +from itertools import chain +from threading import Lock + +from werkzeug.datastructures import Headers, ImmutableDict +from werkzeug.exceptions import BadRequest, BadRequestKeyError, HTTPException, \ + InternalServerError, MethodNotAllowed, default_exceptions +from werkzeug.routing import BuildError, Map, RequestRedirect, Rule + +from . import cli, json +from ._compat import integer_types, reraise, string_types, text_type +from .config import Config, ConfigAttribute +from .ctx import AppContext, RequestContext, _AppCtxGlobals +from .globals import _request_ctx_stack, g, request, session +from .helpers import ( + _PackageBoundObject, + _endpoint_from_view_func, find_package, get_env, get_debug_flag, + get_flashed_messages, locked_cached_property, url_for, get_load_dotenv +) +from .logging import create_logger +from .sessions import SecureCookieSessionInterface +from .signals import appcontext_tearing_down, got_request_exception, \ + request_finished, request_started, request_tearing_down +from .templating import DispatchingJinjaLoader, Environment, \ + _default_template_ctx_processor +from .wrappers import Request, Response + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +def _make_timedelta(value): + if not isinstance(value, timedelta): + return timedelta(seconds=value) + return value + + +def setupmethod(f): + """Wraps a method so that it performs a check in debug mode if the + first request was already handled. + """ + def wrapper_func(self, *args, **kwargs): + if self.debug and self._got_first_request: + raise AssertionError('A setup function was called after the ' + 'first request was handled. This usually indicates a bug ' + 'in the application where a module was not imported ' + 'and decorators or other functionality was called too late.\n' + 'To fix this make sure to import all your view modules, ' + 'database models and everything related at a central place ' + 'before the application starts serving requests.') + return f(self, *args, **kwargs) + return update_wrapper(wrapper_func, f) + + +class Flask(_PackageBoundObject): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: the folder with static files that should be served + at `static_url_path`. Defaults to the ``'static'`` + folder in the root path of the application. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: Flask by default will automatically calculate the path + to the root of the application. In certain situations + this cannot be achieved (for instance if the package + is a Python 3 namespace package) and needs to be + manually defined. + """ + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class = Response + + #: The class that is used for the Jinja environment. + #: + #: .. versionadded:: 0.11 + jinja_environment = Environment + + #: The class that is used for the :data:`~flask.g` instance. + #: + #: Example use cases for a custom class: + #: + #: 1. Store arbitrary attributes on flask.g. + #: 2. Add a property for lazy per-request database connectors. + #: 3. Return None instead of AttributeError on unexpected attributes. + #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. + #: + #: In Flask 0.9 this property was called `request_globals_class` but it + #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the + #: flask.g object is now application context scoped. + #: + #: .. versionadded:: 0.10 + app_ctx_globals_class = _AppCtxGlobals + + #: The class that is used for the ``config`` attribute of this app. + #: Defaults to :class:`~flask.Config`. + #: + #: Example use cases for a custom class: + #: + #: 1. Default values for certain config options. + #: 2. Access to config values through attributes in addition to keys. + #: + #: .. versionadded:: 0.11 + config_class = Config + + #: The testing flag. Set this to ``True`` to enable the test mode of + #: Flask extensions (and in the future probably also Flask itself). + #: For example this might activate test helpers that have an + #: additional runtime cost which should not be enabled by default. + #: + #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the + #: default it's implicitly enabled. + #: + #: This attribute can also be configured from the config with the + #: ``TESTING`` configuration key. Defaults to ``False``. + testing = ConfigAttribute('TESTING') + + #: If a secret key is set, cryptographic components can use this to + #: sign cookies and other things. Set this to a complex random value + #: when you want to use the secure cookie for instance. + #: + #: This attribute can also be configured from the config with the + #: :data:`SECRET_KEY` configuration key. Defaults to ``None``. + secret_key = ConfigAttribute('SECRET_KEY') + + #: The secure cookie uses this for the name of the session cookie. + #: + #: This attribute can also be configured from the config with the + #: ``SESSION_COOKIE_NAME`` configuration key. Defaults to ``'session'`` + session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME') + + #: A :class:`~datetime.timedelta` which is used to set the expiration + #: date of a permanent session. The default is 31 days which makes a + #: permanent session survive for roughly one month. + #: + #: This attribute can also be configured from the config with the + #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to + #: ``timedelta(days=31)`` + permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME', + get_converter=_make_timedelta) + + #: A :class:`~datetime.timedelta` which is used as default cache_timeout + #: for the :func:`send_file` functions. The default is 12 hours. + #: + #: This attribute can also be configured from the config with the + #: ``SEND_FILE_MAX_AGE_DEFAULT`` configuration key. This configuration + #: variable can also be set with an integer value used as seconds. + #: Defaults to ``timedelta(hours=12)`` + send_file_max_age_default = ConfigAttribute('SEND_FILE_MAX_AGE_DEFAULT', + get_converter=_make_timedelta) + + #: Enable this if you want to use the X-Sendfile feature. Keep in + #: mind that the server has to support this. This only affects files + #: sent with the :func:`send_file` method. + #: + #: .. versionadded:: 0.2 + #: + #: This attribute can also be configured from the config with the + #: ``USE_X_SENDFILE`` configuration key. Defaults to ``False``. + use_x_sendfile = ConfigAttribute('USE_X_SENDFILE') + + #: The JSON encoder class to use. Defaults to :class:`~flask.json.JSONEncoder`. + #: + #: .. versionadded:: 0.10 + json_encoder = json.JSONEncoder + + #: The JSON decoder class to use. Defaults to :class:`~flask.json.JSONDecoder`. + #: + #: .. versionadded:: 0.10 + json_decoder = json.JSONDecoder + + #: Options that are passed directly to the Jinja2 environment. + jinja_options = ImmutableDict( + extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_'] + ) + + #: Default configuration parameters. + default_config = ImmutableDict({ + 'ENV': None, + 'DEBUG': None, + 'TESTING': False, + 'PROPAGATE_EXCEPTIONS': None, + 'PRESERVE_CONTEXT_ON_EXCEPTION': None, + 'SECRET_KEY': None, + 'PERMANENT_SESSION_LIFETIME': timedelta(days=31), + 'USE_X_SENDFILE': False, + 'SERVER_NAME': None, + 'APPLICATION_ROOT': '/', + 'SESSION_COOKIE_NAME': 'session', + 'SESSION_COOKIE_DOMAIN': None, + 'SESSION_COOKIE_PATH': None, + 'SESSION_COOKIE_HTTPONLY': True, + 'SESSION_COOKIE_SECURE': False, + 'SESSION_COOKIE_SAMESITE': None, + 'SESSION_REFRESH_EACH_REQUEST': True, + 'MAX_CONTENT_LENGTH': None, + 'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12), + 'TRAP_BAD_REQUEST_ERRORS': None, + 'TRAP_HTTP_EXCEPTIONS': False, + 'EXPLAIN_TEMPLATE_LOADING': False, + 'PREFERRED_URL_SCHEME': 'http', + 'JSON_AS_ASCII': True, + 'JSON_SORT_KEYS': True, + 'JSONIFY_PRETTYPRINT_REGULAR': False, + 'JSONIFY_MIMETYPE': 'application/json', + 'TEMPLATES_AUTO_RELOAD': None, + 'MAX_COOKIE_SIZE': 4093, + }) + + #: The rule object to use for URL rules created. This is used by + #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. + #: + #: .. versionadded:: 0.7 + url_rule_class = Rule + + #: the test client that is used with when `test_client` is used. + #: + #: .. versionadded:: 0.7 + test_client_class = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class = None + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface = SecureCookieSessionInterface() + + # TODO remove the next three attrs when Sphinx :inherited-members: works + # https://github.com/sphinx-doc/sphinx/issues/741 + + #: The name of the package or module that this app belongs to. Do not + #: change this once it is set by the constructor. + import_name = None + + #: Location of the template files to be added to the template lookup. + #: ``None`` if templates should not be added. + template_folder = None + + #: Absolute path to the package on the filesystem. Used to look up + #: resources contained in the package. + root_path = None + + def __init__( + self, + import_name, + static_url_path=None, + static_folder='static', + static_host=None, + host_matching=False, + subdomain_matching=False, + template_folder='templates', + instance_path=None, + instance_relative_config=False, + root_path=None + ): + _PackageBoundObject.__init__( + self, + import_name, + template_folder=template_folder, + root_path=root_path + ) + + if static_url_path is not None: + self.static_url_path = static_url_path + + if static_folder is not None: + self.static_folder = static_folder + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + 'If an instance path is provided it must be absolute.' + ' A relative path was given instead.' + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: A dictionary of all view functions registered. The keys will + #: be function names which are also used to generate URLs and + #: the values are the function objects themselves. + #: To register a view function, use the :meth:`route` decorator. + self.view_functions = {} + + #: A dictionary of all registered error handlers. The key is ``None`` + #: for error handlers active on the application, otherwise the key is + #: the name of the blueprint. Each key points to another dictionary + #: where the key is the status code of the http exception. The + #: special key ``None`` points to a list of tuples where the first item + #: is the class for the instance check and the second the error handler + #: function. + #: + #: To register an error handler, use the :meth:`errorhandler` + #: decorator. + self.error_handler_spec = {} + + #: A list of functions that are called when :meth:`url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function registered here + #: is called with `error`, `endpoint` and `values`. If a function + #: returns ``None`` or raises a :exc:`BuildError` the next function is + #: tried. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers = [] + + #: A dictionary with lists of functions that will be called at the + #: beginning of each request. The key of the dictionary is the name of + #: the blueprint this function is active for, or ``None`` for all + #: requests. To register a function, use the :meth:`before_request` + #: decorator. + self.before_request_funcs = {} + + #: A list of functions that will be called at the beginning of the + #: first request to this instance. To register a function, use the + #: :meth:`before_first_request` decorator. + #: + #: .. versionadded:: 0.8 + self.before_first_request_funcs = [] + + #: A dictionary with lists of functions that should be called after + #: each request. The key of the dictionary is the name of the blueprint + #: this function is active for, ``None`` for all requests. This can for + #: example be used to close database connections. To register a function + #: here, use the :meth:`after_request` decorator. + self.after_request_funcs = {} + + #: A dictionary with lists of functions that are called after + #: each request, even if an exception has occurred. The key of the + #: dictionary is the name of the blueprint this function is active for, + #: ``None`` for all requests. These functions are not allowed to modify + #: the request, and their return values are ignored. If an exception + #: occurred while processing the request, it gets passed to each + #: teardown_request function. To register a function here, use the + #: :meth:`teardown_request` decorator. + #: + #: .. versionadded:: 0.7 + self.teardown_request_funcs = {} + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs = [] + + #: A dictionary with lists of functions that are called before the + #: :attr:`before_request_funcs` functions. The key of the dictionary is + #: the name of the blueprint this function is active for, or ``None`` + #: for all requests. To register a function, use + #: :meth:`url_value_preprocessor`. + #: + #: .. versionadded:: 0.7 + self.url_value_preprocessors = {} + + #: A dictionary with lists of functions that can be used as URL value + #: preprocessors. The key ``None`` here is used for application wide + #: callbacks, otherwise the key is the name of the blueprint. + #: Each of these functions has the chance to modify the dictionary + #: of URL values before they are used as the keyword arguments of the + #: view function. For each function registered this one should also + #: provide a :meth:`url_defaults` function that adds the parameters + #: automatically again that were removed that way. + #: + #: .. versionadded:: 0.7 + self.url_default_functions = {} + + #: A dictionary with list of functions that are called without argument + #: to populate the template context. The key of the dictionary is the + #: name of the blueprint this function is active for, ``None`` for all + #: requests. Each returns a dictionary that the template context is + #: updated with. To register a function here, use the + #: :meth:`context_processor` decorator. + self.template_context_processors = { + None: [_default_template_ctx_processor] + } + + #: A list of shell context processor functions that should be run + #: when a shell context is created. + #: + #: .. versionadded:: 0.11 + self.shell_context_processors = [] + + #: all the attached blueprints in a dictionary by name. Blueprints + #: can be attached multiple times so this dictionary does not tell + #: you how often they got attached. + #: + #: .. versionadded:: 0.7 + self.blueprints = {} + self._blueprint_order = [] + + #: a place where extensions can store application specific state. For + #: example this is where an extension could store database engines and + #: similar things. For backwards compatibility extensions should register + #: themselves like this:: + #: + #: if not hasattr(app, 'extensions'): + #: app.extensions = {} + #: app.extensions['extensionname'] = SomeObject() + #: + #: The key must match the name of the extension module. For example in + #: case of a "Flask-Foo" extension in `flask_foo`, the key would be + #: ``'foo'``. + #: + #: .. versionadded:: 0.7 + self.extensions = {} + + #: The :class:`~werkzeug.routing.Map` for this instance. You can use + #: this to change the routing converters after the class was created + #: but before any routes are connected. Example:: + #: + #: from werkzeug.routing import BaseConverter + #: + #: class ListConverter(BaseConverter): + #: def to_python(self, value): + #: return value.split(',') + #: def to_url(self, values): + #: return ','.join(super(ListConverter, self).to_url(value) + #: for value in values) + #: + #: app = Flask(__name__) + #: app.url_map.converters['list'] = ListConverter + self.url_map = Map() + + self.url_map.host_matching = host_matching + self.subdomain_matching = subdomain_matching + + # tracks internally if the application already handled at least one + # request. + self._got_first_request = False + self._before_request_lock = Lock() + + # Add a static route using the provided static_url_path, static_host, + # and static_folder if there is a configured static_folder. + # Note we do this without checking if static_folder exists. + # For one, it might be created while the server is running (e.g. during + # development). Also, Google App Engine stores static files somewhere + if self.has_static_folder: + assert bool(static_host) == host_matching, 'Invalid static_host/host_matching combination' + self.add_url_rule( + self.static_url_path + '/', + endpoint='static', + host=static_host, + view_func=self.send_static_file + ) + + #: The click command line context for this application. Commands + #: registered here show up in the :command:`flask` command once the + #: application has been discovered. The default commands are + #: provided by Flask itself and can be overridden. + #: + #: This is an instance of a :class:`click.Group` object. + self.cli = cli.AppGroup(self.name) + + @locked_cached_property + def name(self): + """The name of the application. This is usually the import name + with the difference that it's guessed from the run file if the + import name is main. This name is used as a display name when + Flask needs the name of the application. It can be set and overridden + to change the value. + + .. versionadded:: 0.8 + """ + if self.import_name == '__main__': + fn = getattr(sys.modules['__main__'], '__file__', None) + if fn is None: + return '__main__' + return os.path.splitext(os.path.basename(fn))[0] + return self.import_name + + @property + def propagate_exceptions(self): + """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration + value in case it's set, otherwise a sensible default is returned. + + .. versionadded:: 0.7 + """ + rv = self.config['PROPAGATE_EXCEPTIONS'] + if rv is not None: + return rv + return self.testing or self.debug + + @property + def preserve_context_on_exception(self): + """Returns the value of the ``PRESERVE_CONTEXT_ON_EXCEPTION`` + configuration value in case it's set, otherwise a sensible default + is returned. + + .. versionadded:: 0.7 + """ + rv = self.config['PRESERVE_CONTEXT_ON_EXCEPTION'] + if rv is not None: + return rv + return self.debug + + @locked_cached_property + def logger(self): + """The ``'flask.app'`` logger, a standard Python + :class:`~logging.Logger`. + + In debug mode, the logger's :attr:`~logging.Logger.level` will be set + to :data:`~logging.DEBUG`. + + If there are no handlers configured, a default handler will be added. + See :ref:`logging` for more information. + + .. versionchanged:: 1.0 + Behavior was simplified. The logger is always named + ``flask.app``. The level is only set during configuration, it + doesn't check ``app.debug`` each time. Only one format is used, + not different ones depending on ``app.debug``. No handlers are + removed, and a handler is only added if no handlers are already + configured. + + .. versionadded:: 0.3 + """ + return create_logger(self) + + @locked_cached_property + def jinja_env(self): + """The Jinja2 environment used to load templates.""" + return self.create_jinja_environment() + + @property + def got_first_request(self): + """This attribute is set to ``True`` if the application started + handling the first request. + + .. versionadded:: 0.8 + """ + return self._got_first_request + + def make_config(self, instance_relative=False): + """Used to create the config attribute by the Flask constructor. + The `instance_relative` parameter is passed in from the constructor + of Flask (there named `instance_relative_config`) and indicates if + the config should be relative to the instance path or the root path + of the application. + + .. versionadded:: 0.8 + """ + root_path = self.root_path + if instance_relative: + root_path = self.instance_path + defaults = dict(self.default_config) + defaults['ENV'] = get_env() + defaults['DEBUG'] = get_debug_flag() + return self.config_class(root_path, defaults) + + def auto_find_instance_path(self): + """Tries to locate the instance path if it was not provided to the + constructor of the application class. It will basically calculate + the path to a folder named ``instance`` next to your main file or + the package. + + .. versionadded:: 0.8 + """ + prefix, package_path = find_package(self.import_name) + if prefix is None: + return os.path.join(package_path, 'instance') + return os.path.join(prefix, 'var', self.name + '-instance') + + def open_instance_resource(self, resource, mode='rb'): + """Opens a resource from the application's instance folder + (:attr:`instance_path`). Otherwise works like + :meth:`open_resource`. Instance resources can also be opened for + writing. + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + return open(os.path.join(self.instance_path, resource), mode) + + def _get_templates_auto_reload(self): + """Reload templates when they are changed. Used by + :meth:`create_jinja_environment`. + + This attribute can be configured with :data:`TEMPLATES_AUTO_RELOAD`. If + not set, it will be enabled in debug mode. + + .. versionadded:: 1.0 + This property was added but the underlying config and behavior + already existed. + """ + rv = self.config['TEMPLATES_AUTO_RELOAD'] + return rv if rv is not None else self.debug + + def _set_templates_auto_reload(self, value): + self.config['TEMPLATES_AUTO_RELOAD'] = value + + templates_auto_reload = property( + _get_templates_auto_reload, _set_templates_auto_reload + ) + del _get_templates_auto_reload, _set_templates_auto_reload + + def create_jinja_environment(self): + """Creates the Jinja2 environment based on :attr:`jinja_options` + and :meth:`select_jinja_autoescape`. Since 0.7 this also adds + the Jinja2 globals and filters after initialization. Override + this function to customize the behavior. + + .. versionadded:: 0.5 + .. versionchanged:: 0.11 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. + """ + options = dict(self.jinja_options) + + if 'autoescape' not in options: + options['autoescape'] = self.select_jinja_autoescape + + if 'auto_reload' not in options: + options['auto_reload'] = self.templates_auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=url_for, + get_flashed_messages=get_flashed_messages, + config=self.config, + # request, session and g are normally added with the + # context processor for efficiency reasons but for imported + # templates we also want the proxies in there. + request=request, + session=session, + g=g + ) + rv.filters['tojson'] = json.tojson_filter + return rv + + def create_global_jinja_loader(self): + """Creates the loader for the Jinja2 environment. Can be used to + override just the loader and keeping the rest unchanged. It's + discouraged to override this function. Instead one should override + the :meth:`jinja_loader` function instead. + + The global loader dispatches between the loaders of the application + and the individual blueprints. + + .. versionadded:: 0.7 + """ + return DispatchingJinjaLoader(self) + + def select_jinja_autoescape(self, filename): + """Returns ``True`` if autoescaping should be active for the given + template name. If no template name is given, returns `True`. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith(('.html', '.htm', '.xml', '.xhtml')) + + def update_template_context(self, context): + """Update the template context with some commonly used variables. + This injects request, session, config and g into the template + context as well as everything template context processors want + to inject. Note that the as of Flask 0.6, the original values + in the context will not be overridden if a context processor + decides to return a value with the same key. + + :param context: the context as a dictionary that is updated in place + to add extra variables. + """ + funcs = self.template_context_processors[None] + reqctx = _request_ctx_stack.top + if reqctx is not None: + bp = reqctx.request.blueprint + if bp is not None and bp in self.template_context_processors: + funcs = chain(funcs, self.template_context_processors[bp]) + orig_ctx = context.copy() + for func in funcs: + context.update(func()) + # make sure the original values win. This makes it possible to + # easier add new variables in context processors without breaking + # existing views. + context.update(orig_ctx) + + def make_shell_context(self): + """Returns the shell context for an interactive shell for this + application. This runs all the registered shell context + processors. + + .. versionadded:: 0.11 + """ + rv = {'app': self, 'g': g} + for processor in self.shell_context_processors: + rv.update(processor()) + return rv + + #: What environment the app is running in. Flask and extensions may + #: enable behaviors based on the environment, such as enabling debug + #: mode. This maps to the :data:`ENV` config key. This is set by the + #: :envvar:`FLASK_ENV` environment variable and may not behave as + #: expected if set in code. + #: + #: **Do not enable development when deploying in production.** + #: + #: Default: ``'production'`` + env = ConfigAttribute('ENV') + + def _get_debug(self): + return self.config['DEBUG'] + + def _set_debug(self, value): + self.config['DEBUG'] = value + self.jinja_env.auto_reload = self.templates_auto_reload + + #: Whether debug mode is enabled. When using ``flask run`` to start + #: the development server, an interactive debugger will be shown for + #: unhandled exceptions, and the server will be reloaded when code + #: changes. This maps to the :data:`DEBUG` config key. This is + #: enabled when :attr:`env` is ``'development'`` and is overridden + #: by the ``FLASK_DEBUG`` environment variable. It may not behave as + #: expected if set in code. + #: + #: **Do not enable debug mode when deploying in production.** + #: + #: Default: ``True`` if :attr:`env` is ``'development'``, or + #: ``False`` otherwise. + debug = property(_get_debug, _set_debug) + del _get_debug, _set_debug + + def run(self, host=None, port=None, debug=None, + load_dotenv=True, **options): + """Runs the application on a local development server. + + Do not use ``run()`` in a production setting. It is not intended to + meet security and performance requirements for a production server. + Instead, see :ref:`deployment` for WSGI server recommendations. + + If the :attr:`debug` flag is set the server will automatically reload + for code changes and show a debugger in case an exception happened. + + If you want to run the application in debug mode, but disable the + code execution on the interactive debugger, you can pass + ``use_evalex=False`` as parameter. This will keep the debugger's + traceback screen active, but disable code execution. + + It is not recommended to use this function for development with + automatic reloading as this is badly supported. Instead you should + be using the :command:`flask` command line script's ``run`` support. + + .. admonition:: Keep in Mind + + Flask will suppress any server error with a generic error page + unless it is in debug mode. As such to enable just the + interactive debugger without the code reloading, you have to + invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. + Setting ``use_debugger`` to ``True`` without being in debug mode + won't catch any exceptions because there won't be any to + catch. + + :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to + have the server available externally as well. Defaults to + ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable + if present. + :param port: the port of the webserver. Defaults to ``5000`` or the + port defined in the ``SERVER_NAME`` config variable if present. + :param debug: if given, enable or disable debug mode. See + :attr:`debug`. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param options: the options to be forwarded to the underlying Werkzeug + server. See :func:`werkzeug.serving.run_simple` for more + information. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment + variables from :file:`.env` and :file:`.flaskenv` files. + + If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG` + environment variables will override :attr:`env` and + :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Change this into a no-op if the server is invoked from the + # command line. Have a look at cli.py for more information. + if os.environ.get('FLASK_RUN_FROM_CLI') == 'true': + from .debughelpers import explain_ignored_app_run + explain_ignored_app_run() + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, let env vars override previous values + if 'FLASK_ENV' in os.environ: + self.env = get_env() + self.debug = get_debug_flag() + elif 'FLASK_DEBUG' in os.environ: + self.debug = get_debug_flag() + + # debug passed to method overrides all other sources + if debug is not None: + self.debug = bool(debug) + + _host = '127.0.0.1' + _port = 5000 + server_name = self.config.get('SERVER_NAME') + sn_host, sn_port = None, None + + if server_name: + sn_host, _, sn_port = server_name.partition(':') + + host = host or sn_host or _host + port = int(port or sn_port or _port) + + options.setdefault('use_reloader', self.debug) + options.setdefault('use_debugger', self.debug) + options.setdefault('threaded', True) + + cli.show_server_banner(self.env, self.debug, self.name, False) + + from werkzeug.serving import run_simple + + try: + run_simple(host, port, self, **options) + finally: + # reset the first request information if the development server + # reset normally. This makes it possible to restart the server + # without reloader and that stuff from an interactive shell. + self._got_first_request = False + + def test_client(self, use_cookies=True, **kwargs): + """Creates a test client for this application. For information + about unit testing head over to :ref:`testing`. + + Note that if you are testing for assertions or exceptions in your + application code, you must set ``app.testing = True`` in order for the + exceptions to propagate to the test client. Otherwise, the exception + will be handled by the application (not visible to the test client) and + the only indication of an AssertionError or other exception will be a + 500 status code response to the test client. See the :attr:`testing` + attribute. For example:: + + app.testing = True + client = app.test_client() + + The test client can be used in a ``with`` block to defer the closing down + of the context until the end of the ``with`` block. This is useful if + you want to access the context locals for testing:: + + with app.test_client() as c: + rv = c.get('/?vodka=42') + assert request.args['vodka'] == '42' + + Additionally, you may pass optional keyword arguments that will then + be passed to the application's :attr:`test_client_class` constructor. + For example:: + + from flask.testing import FlaskClient + + class CustomClient(FlaskClient): + def __init__(self, *args, **kwargs): + self._authentication = kwargs.pop("authentication") + super(CustomClient,self).__init__( *args, **kwargs) + + app.test_client_class = CustomClient + client = app.test_client(authentication='Basic ....') + + See :class:`~flask.testing.FlaskClient` for more information. + + .. versionchanged:: 0.4 + added support for ``with`` block usage for the client. + + .. versionadded:: 0.7 + The `use_cookies` parameter was added as well as the ability + to override the client to be used by setting the + :attr:`test_client_class` attribute. + + .. versionchanged:: 0.11 + Added `**kwargs` to support passing additional keyword arguments to + the constructor of :attr:`test_client_class`. + """ + cls = self.test_client_class + if cls is None: + from flask.testing import FlaskClient as cls + return cls(self, self.response_class, use_cookies=use_cookies, **kwargs) + + def test_cli_runner(self, **kwargs): + """Create a CLI runner for testing CLI commands. + See :ref:`testing-cli`. + + Returns an instance of :attr:`test_cli_runner_class`, by default + :class:`~flask.testing.FlaskCliRunner`. The Flask app object is + passed as the first argument. + + .. versionadded:: 1.0 + """ + cls = self.test_cli_runner_class + + if cls is None: + from flask.testing import FlaskCliRunner as cls + + return cls(self, **kwargs) + + def open_session(self, request): + """Creates or opens a new session. Default implementation stores all + session data in a signed cookie. This requires that the + :attr:`secret_key` is set. Instead of overriding this method + we recommend replacing the :class:`session_interface`. + + .. deprecated: 1.0 + Will be removed in 1.1. Use ``session_interface.open_session`` + instead. + + :param request: an instance of :attr:`request_class`. + """ + + warnings.warn(DeprecationWarning( + '"open_session" is deprecated and will be removed in 1.1. Use' + ' "session_interface.open_session" instead.' + )) + return self.session_interface.open_session(self, request) + + def save_session(self, session, response): + """Saves the session if it needs updates. For the default + implementation, check :meth:`open_session`. Instead of overriding this + method we recommend replacing the :class:`session_interface`. + + .. deprecated: 1.0 + Will be removed in 1.1. Use ``session_interface.save_session`` + instead. + + :param session: the session to be saved (a + :class:`~werkzeug.contrib.securecookie.SecureCookie` + object) + :param response: an instance of :attr:`response_class` + """ + + warnings.warn(DeprecationWarning( + '"save_session" is deprecated and will be removed in 1.1. Use' + ' "session_interface.save_session" instead.' + )) + return self.session_interface.save_session(self, session, response) + + def make_null_session(self): + """Creates a new instance of a missing session. Instead of overriding + this method we recommend replacing the :class:`session_interface`. + + .. deprecated: 1.0 + Will be removed in 1.1. Use ``session_interface.make_null_session`` + instead. + + .. versionadded:: 0.7 + """ + + warnings.warn(DeprecationWarning( + '"make_null_session" is deprecated and will be removed in 1.1. Use' + ' "session_interface.make_null_session" instead.' + )) + return self.session_interface.make_null_session(self) + + @setupmethod + def register_blueprint(self, blueprint, **options): + """Register a :class:`~flask.Blueprint` on the application. Keyword + arguments passed to this method will override the defaults set on the + blueprint. + + Calls the blueprint's :meth:`~flask.Blueprint.register` method after + recording the blueprint in the application's :attr:`blueprints`. + + :param blueprint: The blueprint to register. + :param url_prefix: Blueprint routes will be prefixed with this. + :param subdomain: Blueprint routes will match on this subdomain. + :param url_defaults: Blueprint routes will use these default values for + view arguments. + :param options: Additional keyword arguments are passed to + :class:`~flask.blueprints.BlueprintSetupState`. They can be + accessed in :meth:`~flask.Blueprint.record` callbacks. + + .. versionadded:: 0.7 + """ + first_registration = False + + if blueprint.name in self.blueprints: + assert self.blueprints[blueprint.name] is blueprint, ( + 'A name collision occurred between blueprints %r and %r. Both' + ' share the same name "%s". Blueprints that are created on the' + ' fly need unique names.' % ( + blueprint, self.blueprints[blueprint.name], blueprint.name + ) + ) + else: + self.blueprints[blueprint.name] = blueprint + self._blueprint_order.append(blueprint) + first_registration = True + + blueprint.register(self, options, first_registration) + + def iter_blueprints(self): + """Iterates over all blueprints by the order they were registered. + + .. versionadded:: 0.11 + """ + return iter(self._blueprint_order) + + @setupmethod + def add_url_rule(self, rule, endpoint=None, view_func=None, + provide_automatic_options=None, **options): + """Connects a URL rule. Works exactly like the :meth:`route` + decorator. If a view_func is provided it will be registered with the + endpoint. + + Basically this example:: + + @app.route('/') + def index(): + pass + + Is equivalent to the following:: + + def index(): + pass + app.add_url_rule('/', 'index', index) + + If the view_func is not provided you will need to connect the endpoint + to a view function like so:: + + app.view_functions['index'] = index + + Internally :meth:`route` invokes :meth:`add_url_rule` so if you want + to customize the behavior via subclassing you only need to change + this method. + + For more information refer to :ref:`url-route-registrations`. + + .. versionchanged:: 0.2 + `view_func` parameter added. + + .. versionchanged:: 0.6 + ``OPTIONS`` is added automatically as method. + + :param rule: the URL rule as string + :param endpoint: the endpoint for the registered URL rule. Flask + itself assumes the name of the view function as + endpoint + :param view_func: the function to call when serving a request to the + provided endpoint + :param provide_automatic_options: controls whether the ``OPTIONS`` + method should be added automatically. This can also be controlled + by setting the ``view_func.provide_automatic_options = False`` + before adding the rule. + :param options: the options to be forwarded to the underlying + :class:`~werkzeug.routing.Rule` object. A change + to Werkzeug is handling of method options. methods + is a list of methods this rule should be limited + to (``GET``, ``POST`` etc.). By default a rule + just listens for ``GET`` (and implicitly ``HEAD``). + Starting with Flask 0.6, ``OPTIONS`` is implicitly + added and handled by the standard request handling. + """ + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) + options['endpoint'] = endpoint + methods = options.pop('methods', None) + + # if the methods are not given and the view_func object knows its + # methods we can use that instead. If neither exists, we go with + # a tuple of only ``GET`` as default. + if methods is None: + methods = getattr(view_func, 'methods', None) or ('GET',) + if isinstance(methods, string_types): + raise TypeError('Allowed methods have to be iterables of strings, ' + 'for example: @app.route(..., methods=["POST"])') + methods = set(item.upper() for item in methods) + + # Methods that should always be added + required_methods = set(getattr(view_func, 'required_methods', ())) + + # starting with Flask 0.8 the view_func object can disable and + # force-enable the automatic options handling. + if provide_automatic_options is None: + provide_automatic_options = getattr(view_func, + 'provide_automatic_options', None) + + if provide_automatic_options is None: + if 'OPTIONS' not in methods: + provide_automatic_options = True + required_methods.add('OPTIONS') + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule = self.url_rule_class(rule, methods=methods, **options) + rule.provide_automatic_options = provide_automatic_options + + self.url_map.add(rule) + if view_func is not None: + old_func = self.view_functions.get(endpoint) + if old_func is not None and old_func != view_func: + raise AssertionError('View function mapping is overwriting an ' + 'existing endpoint function: %s' % endpoint) + self.view_functions[endpoint] = view_func + + def route(self, rule, **options): + """A decorator that is used to register a view function for a + given URL rule. This does the same thing as :meth:`add_url_rule` + but is intended for decorator usage:: + + @app.route('/') + def index(): + return 'Hello World' + + For more information refer to :ref:`url-route-registrations`. + + :param rule: the URL rule as string + :param endpoint: the endpoint for the registered URL rule. Flask + itself assumes the name of the view function as + endpoint + :param options: the options to be forwarded to the underlying + :class:`~werkzeug.routing.Rule` object. A change + to Werkzeug is handling of method options. methods + is a list of methods this rule should be limited + to (``GET``, ``POST`` etc.). By default a rule + just listens for ``GET`` (and implicitly ``HEAD``). + Starting with Flask 0.6, ``OPTIONS`` is implicitly + added and handled by the standard request handling. + """ + def decorator(f): + endpoint = options.pop('endpoint', None) + self.add_url_rule(rule, endpoint, f, **options) + return f + return decorator + + @setupmethod + def endpoint(self, endpoint): + """A decorator to register a function as an endpoint. + Example:: + + @app.endpoint('example.endpoint') + def example(): + return "example" + + :param endpoint: the name of the endpoint + """ + def decorator(f): + self.view_functions[endpoint] = f + return f + return decorator + + @staticmethod + def _get_exc_class_and_code(exc_class_or_code): + """Ensure that we register only exceptions as handler keys""" + if isinstance(exc_class_or_code, integer_types): + exc_class = default_exceptions[exc_class_or_code] + else: + exc_class = exc_class_or_code + + assert issubclass(exc_class, Exception) + + if issubclass(exc_class, HTTPException): + return exc_class, exc_class.code + else: + return exc_class, None + + @setupmethod + def errorhandler(self, code_or_exception): + """Register a function to handle errors by code or exception class. + + A decorator that is used to register a function given an + error code. Example:: + + @app.errorhandler(404) + def page_not_found(error): + return 'This page does not exist', 404 + + You can also register handlers for arbitrary exceptions:: + + @app.errorhandler(DatabaseError) + def special_exception_handler(error): + return 'Database connection failed', 500 + + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + + .. versionadded:: 0.7 + One can now additionally also register custom exception types + that do not necessarily have to be a subclass of the + :class:`~werkzeug.exceptions.HTTPException` class. + + :param code_or_exception: the code as integer for the handler, or + an arbitrary exception + """ + def decorator(f): + self._register_error_handler(None, code_or_exception, f) + return f + return decorator + + @setupmethod + def register_error_handler(self, code_or_exception, f): + """Alternative error attach function to the :meth:`errorhandler` + decorator that is more straightforward to use for non decorator + usage. + + .. versionadded:: 0.7 + """ + self._register_error_handler(None, code_or_exception, f) + + @setupmethod + def _register_error_handler(self, key, code_or_exception, f): + """ + :type key: None|str + :type code_or_exception: int|T<=Exception + :type f: callable + """ + if isinstance(code_or_exception, HTTPException): # old broken behavior + raise ValueError( + 'Tried to register a handler for an exception instance {0!r}.' + ' Handlers can only be registered for exception classes or' + ' HTTP error codes.'.format(code_or_exception) + ) + + try: + exc_class, code = self._get_exc_class_and_code(code_or_exception) + except KeyError: + raise KeyError( + "'{0}' is not a recognized HTTP error code. Use a subclass of" + " HTTPException with that code instead.".format(code_or_exception) + ) + + handlers = self.error_handler_spec.setdefault(key, {}).setdefault(code, {}) + handlers[exc_class] = f + + @setupmethod + def template_filter(self, name=None): + """A decorator that is used to register custom template filter. + You can specify a name for the filter, otherwise the function + name will be used. Example:: + + @app.template_filter() + def reverse(s): + return s[::-1] + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + def decorator(f): + self.add_template_filter(f, name=name) + return f + return decorator + + @setupmethod + def add_template_filter(self, f, name=None): + """Register a custom template filter. Works exactly like the + :meth:`template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + self.jinja_env.filters[name or f.__name__] = f + + @setupmethod + def template_test(self, name=None): + """A decorator that is used to register custom template test. + You can specify a name for the test, otherwise the function + name will be used. Example:: + + @app.template_test() + def is_prime(n): + if n == 2: + return True + for i in range(2, int(math.ceil(math.sqrt(n))) + 1): + if n % i == 0: + return False + return True + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + def decorator(f): + self.add_template_test(f, name=name) + return f + return decorator + + @setupmethod + def add_template_test(self, f, name=None): + """Register a custom template test. Works exactly like the + :meth:`template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + self.jinja_env.tests[name or f.__name__] = f + + @setupmethod + def template_global(self, name=None): + """A decorator that is used to register a custom template global function. + You can specify a name for the global function, otherwise the function + name will be used. Example:: + + @app.template_global() + def double(n): + return 2 * n + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + def decorator(f): + self.add_template_global(f, name=name) + return f + return decorator + + @setupmethod + def add_template_global(self, f, name=None): + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + + @setupmethod + def before_request(self, f): + """Registers a function to run before each request. + + For example, this can be used to open a database connection, or to load + the logged in user from the session. + + The function will be called without any arguments. If it returns a + non-None value, the value is handled as if it was the return value from + the view, and further request handling is stopped. + """ + self.before_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def before_first_request(self, f): + """Registers a function to be run before the first request to this + instance of the application. + + The function will be called without any arguments and its return + value is ignored. + + .. versionadded:: 0.8 + """ + self.before_first_request_funcs.append(f) + return f + + @setupmethod + def after_request(self, f): + """Register a function to be run after each request. + + Your function must take one parameter, an instance of + :attr:`response_class` and return a new response object or the + same (see :meth:`process_response`). + + As of Flask 0.7 this function might not be executed at the end of the + request in case an unhandled exception occurred. + """ + self.after_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_request(self, f): + """Register a function to be run at the end of each request, + regardless of whether there was an exception or not. These functions + are executed when the request context is popped, even if not an + actual request was performed. + + Example:: + + ctx = app.test_request_context() + ctx.push() + ... + ctx.pop() + + When ``ctx.pop()`` is executed in the above example, the teardown + functions are called just before the request context moves from the + stack of active contexts. This becomes relevant if you are using + such constructs in tests. + + Generally teardown functions must take every necessary step to avoid + that they will fail. If they do execute code that might fail they + will have to surround the execution of these code by try/except + statements and log occurring errors. + + When a teardown function was called because of an exception it will + be passed an error object. + + The return values of teardown functions are ignored. + + .. admonition:: Debug Note + + In debug mode Flask will not tear down a request on an exception + immediately. Instead it will keep it alive so that the interactive + debugger can still access it. This behavior can be controlled + by the ``PRESERVE_CONTEXT_ON_EXCEPTION`` configuration variable. + """ + self.teardown_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_appcontext(self, f): + """Registers a function to be called when the application context + ends. These functions are typically also called when the request + context is popped. + + Example:: + + ctx = app.app_context() + ctx.push() + ... + ctx.pop() + + When ``ctx.pop()`` is executed in the above example, the teardown + functions are called just before the app context moves from the + stack of active contexts. This becomes relevant if you are using + such constructs in tests. + + Since a request context typically also manages an application + context it would also be called when you pop a request context. + + When a teardown function was called because of an unhandled exception + it will be passed an error object. If an :meth:`errorhandler` is + registered, it will handle the exception and the teardown will not + receive it. + + The return values of teardown functions are ignored. + + .. versionadded:: 0.9 + """ + self.teardown_appcontext_funcs.append(f) + return f + + @setupmethod + def context_processor(self, f): + """Registers a template context processor function.""" + self.template_context_processors[None].append(f) + return f + + @setupmethod + def shell_context_processor(self, f): + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + @setupmethod + def url_value_preprocessor(self, f): + """Register a URL value preprocessor function for all view + functions in the application. These functions will be called before the + :meth:`before_request` functions. + + The function can modify the values captured from the matched url before + they are passed to the view. For example, this can be used to pop a + common language code value and place it in ``g`` rather than pass it to + every view. + + The function is passed the endpoint name and values dict. The return + value is ignored. + """ + self.url_value_preprocessors.setdefault(None, []).append(f) + return f + + @setupmethod + def url_defaults(self, f): + """Callback function for URL defaults for all view functions of the + application. It's called with the endpoint and values and should + update the values passed in place. + """ + self.url_default_functions.setdefault(None, []).append(f) + return f + + def _find_error_handler(self, e): + """Return a registered error handler for an exception in this order: + blueprint handler for a specific code, app handler for a specific code, + blueprint handler for an exception class, app handler for an exception + class, or ``None`` if a suitable handler is not found. + """ + exc_class, code = self._get_exc_class_and_code(type(e)) + + for name, c in ( + (request.blueprint, code), (None, code), + (request.blueprint, None), (None, None) + ): + handler_map = self.error_handler_spec.setdefault(name, {}).get(c) + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + + def handle_http_exception(self, e): + """Handles an HTTP exception. By default this will invoke the + registered error handlers and fall back to returning the + exception as response. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + handler = self._find_error_handler(e) + if handler is None: + return e + return handler(e) + + def trap_http_exception(self, e): + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config['TRAP_HTTP_EXCEPTIONS']: + return True + + trap_bad_request = self.config['TRAP_BAD_REQUEST_ERRORS'] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def handle_user_exception(self, e): + """This method is called whenever an exception occurs that should be + handled. A special case are + :class:`~werkzeug.exception.HTTPException`\s which are forwarded by + this function to the :meth:`handle_http_exception` method. This + function will either return a response value or reraise the + exception with the same traceback. + + .. versionchanged:: 1.0 + Key errors raised from request data like ``form`` show the the bad + key in debug mode rather than a generic bad request message. + + .. versionadded:: 0.7 + """ + exc_type, exc_value, tb = sys.exc_info() + assert exc_value is e + # ensure not to trash sys.exc_info() at that point in case someone + # wants the traceback preserved in handle_http_exception. Of course + # we cannot prevent users from trashing it themselves in a custom + # trap_http_exception method so that's their fault then. + + # MultiDict passes the key to the exception, but that's ignored + # when generating the response message. Set an informative + # description for key errors in debug mode or when trapping errors. + if ( + (self.debug or self.config['TRAP_BAD_REQUEST_ERRORS']) + and isinstance(e, BadRequestKeyError) + # only set it if it's still the default description + and e.description is BadRequestKeyError.description + ): + e.description = "KeyError: '{0}'".format(*e.args) + + if isinstance(e, HTTPException) and not self.trap_http_exception(e): + return self.handle_http_exception(e) + + handler = self._find_error_handler(e) + + if handler is None: + reraise(exc_type, exc_value, tb) + return handler(e) + + def handle_exception(self, e): + """Default exception handling that kicks in when an exception + occurs that is not caught. In debug mode the exception will + be re-raised immediately, otherwise it is logged and the handler + for a 500 internal server error is used. If no such handler + exists, a default 500 internal server error message is displayed. + + .. versionadded:: 0.3 + """ + exc_type, exc_value, tb = sys.exc_info() + + got_request_exception.send(self, exception=e) + handler = self._find_error_handler(InternalServerError()) + + if self.propagate_exceptions: + # if we want to repropagate the exception, we can attempt to + # raise it with the whole traceback in case we can do that + # (the function was actually called from the except part) + # otherwise, we just raise the error again + if exc_value is e: + reraise(exc_type, exc_value, tb) + else: + raise e + + self.log_exception((exc_type, exc_value, tb)) + if handler is None: + return InternalServerError() + return self.finalize_request(handler(e), from_error_handler=True) + + def log_exception(self, exc_info): + """Logs an exception. This is called by :meth:`handle_exception` + if debugging is disabled and right before the handler is called. + The default implementation logs the exception as error on the + :attr:`logger`. + + .. versionadded:: 0.8 + """ + self.logger.error('Exception on %s [%s]' % ( + request.path, + request.method + ), exc_info=exc_info) + + def raise_routing_exception(self, request): + """Exceptions that are recording during routing are reraised with + this method. During debug we are not reraising redirect requests + for non ``GET``, ``HEAD``, or ``OPTIONS`` requests and we're raising + a different error instead to help debug situations. + + :internal: + """ + if not self.debug \ + or not isinstance(request.routing_exception, RequestRedirect) \ + or request.method in ('GET', 'HEAD', 'OPTIONS'): + raise request.routing_exception + + from .debughelpers import FormDataRoutingRedirect + raise FormDataRoutingRedirect(request) + + def dispatch_request(self): + """Does the request dispatching. Matches the URL and returns the + return value of the view or error handler. This does not have to + be a response object. In order to convert the return value to a + proper response object, call :func:`make_response`. + + .. versionchanged:: 0.7 + This no longer does the exception handling, this code was + moved to the new :meth:`full_dispatch_request`. + """ + req = _request_ctx_stack.top.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule = req.url_rule + # if we provide automatic options for this URL and the + # request came with the OPTIONS method, reply automatically + if getattr(rule, 'provide_automatic_options', False) \ + and req.method == 'OPTIONS': + return self.make_default_options_response() + # otherwise dispatch to the handler for that endpoint + return self.view_functions[rule.endpoint](**req.view_args) + + def full_dispatch_request(self): + """Dispatches the request and on top of that performs request + pre and postprocessing as well as HTTP exception catching and + error handling. + + .. versionadded:: 0.7 + """ + self.try_trigger_before_first_request_functions() + try: + request_started.send(self) + rv = self.preprocess_request() + if rv is None: + rv = self.dispatch_request() + except Exception as e: + rv = self.handle_user_exception(e) + return self.finalize_request(rv) + + def finalize_request(self, rv, from_error_handler=False): + """Given the return value from a view function this finalizes + the request by converting it into a response and invoking the + postprocessing functions. This is invoked for both normal + request dispatching as well as error handlers. + + Because this means that it might be called as a result of a + failure a special safe mode is available which can be enabled + with the `from_error_handler` flag. If enabled, failures in + response processing will be logged and otherwise ignored. + + :internal: + """ + response = self.make_response(rv) + try: + response = self.process_response(response) + request_finished.send(self, response=response) + except Exception: + if not from_error_handler: + raise + self.logger.exception('Request finalizing failed with an ' + 'error while handling an error') + return response + + def try_trigger_before_first_request_functions(self): + """Called before each request and will ensure that it triggers + the :attr:`before_first_request_funcs` and only exactly once per + application instance (which means process usually). + + :internal: + """ + if self._got_first_request: + return + with self._before_request_lock: + if self._got_first_request: + return + for func in self.before_first_request_funcs: + func() + self._got_first_request = True + + def make_default_options_response(self): + """This method is called to create the default ``OPTIONS`` response. + This can be changed through subclassing to change the default + behavior of ``OPTIONS`` responses. + + .. versionadded:: 0.7 + """ + adapter = _request_ctx_stack.top.url_adapter + if hasattr(adapter, 'allowed_methods'): + methods = adapter.allowed_methods() + else: + # fallback for Werkzeug < 0.7 + methods = [] + try: + adapter.match(method='--') + except MethodNotAllowed as e: + methods = e.valid_methods + except HTTPException as e: + pass + rv = self.response_class() + rv.allow.update(methods) + return rv + + def should_ignore_error(self, error): + """This is called to figure out if an error should be ignored + or not as far as the teardown system is concerned. If this + function returns ``True`` then the teardown handlers will not be + passed the error. + + .. versionadded:: 0.10 + """ + return False + + def make_response(self, rv): + """Convert the return value from a view function to an instance of + :attr:`response_class`. + + :param rv: the return value from the view function. The view function + must return a response. Returning ``None``, or the view ending + without returning, is not allowed. The following types are allowed + for ``view_rv``: + + ``str`` (``unicode`` in Python 2) + A response object is created with the string encoded to UTF-8 + as the body. + + ``bytes`` (``str`` in Python 2) + A response object is created with the bytes as the body. + + ``tuple`` + Either ``(body, status, headers)``, ``(body, status)``, or + ``(body, headers)``, where ``body`` is any of the other types + allowed here, ``status`` is a string or an integer, and + ``headers`` is a dictionary or a list of ``(key, value)`` + tuples. If ``body`` is a :attr:`response_class` instance, + ``status`` overwrites the exiting value and ``headers`` are + extended. + + :attr:`response_class` + The object is returned unchanged. + + other :class:`~werkzeug.wrappers.Response` class + The object is coerced to :attr:`response_class`. + + :func:`callable` + The function is called as a WSGI application. The result is + used to create a response object. + + .. versionchanged:: 0.9 + Previously a tuple was interpreted as the arguments for the + response object. + """ + + status = headers = None + + # unpack tuple returns + if isinstance(rv, tuple): + len_rv = len(rv) + + # a 3-tuple is unpacked directly + if len_rv == 3: + rv, status, headers = rv + # decide if a 2-tuple has status or headers + elif len_rv == 2: + if isinstance(rv[1], (Headers, dict, tuple, list)): + rv, headers = rv + else: + rv, status = rv + # other sized tuples are not allowed + else: + raise TypeError( + 'The view function did not return a valid response tuple.' + ' The tuple must have the form (body, status, headers),' + ' (body, status), or (body, headers).' + ) + + # the body must not be None + if rv is None: + raise TypeError( + 'The view function did not return a valid response. The' + ' function either returned None or ended without a return' + ' statement.' + ) + + # make sure the body is an instance of the response class + if not isinstance(rv, self.response_class): + if isinstance(rv, (text_type, bytes, bytearray)): + # let the response class set the status and headers instead of + # waiting to do it manually, so that the class can handle any + # special logic + rv = self.response_class(rv, status=status, headers=headers) + status = headers = None + else: + # evaluate a WSGI callable, or coerce a different response + # class to the correct type + try: + rv = self.response_class.force_type(rv, request.environ) + except TypeError as e: + new_error = TypeError( + '{e}\nThe view function did not return a valid' + ' response. The return type must be a string, tuple,' + ' Response instance, or WSGI callable, but it was a' + ' {rv.__class__.__name__}.'.format(e=e, rv=rv) + ) + reraise(TypeError, new_error, sys.exc_info()[2]) + + # prefer the status if it was provided + if status is not None: + if isinstance(status, (text_type, bytes, bytearray)): + rv.status = status + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.extend(headers) + + return rv + + def create_url_adapter(self, request): + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionadded:: 0.6 + + .. versionchanged:: 0.9 + This can now also be called without a request object when the + URL adapter is created for the application context. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + """ + if request is not None: + # If subdomain matching is disabled (the default), use the + # default subdomain in all cases. This should be the default + # in Werkzeug but it currently does not have that feature. + subdomain = ((self.url_map.default_subdomain or None) + if not self.subdomain_matching else None) + return self.url_map.bind_to_environ( + request.environ, + server_name=self.config['SERVER_NAME'], + subdomain=subdomain) + # We need at the very least the server name to be set for this + # to work. + if self.config['SERVER_NAME'] is not None: + return self.url_map.bind( + self.config['SERVER_NAME'], + script_name=self.config['APPLICATION_ROOT'], + url_scheme=self.config['PREFERRED_URL_SCHEME']) + + def inject_url_defaults(self, endpoint, values): + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + funcs = self.url_default_functions.get(None, ()) + if '.' in endpoint: + bp = endpoint.rsplit('.', 1)[0] + funcs = chain(funcs, self.url_default_functions.get(bp, ())) + for func in funcs: + func(endpoint, values) + + def handle_url_build_error(self, error, endpoint, values): + """Handle :class:`~werkzeug.routing.BuildError` on :meth:`url_for`. + """ + exc_type, exc_value, tb = sys.exc_info() + for handler in self.url_build_error_handlers: + try: + rv = handler(error, endpoint, values) + if rv is not None: + return rv + except BuildError as e: + # make error available outside except block (py3) + error = e + + # At this point we want to reraise the exception. If the error is + # still the same one we can reraise it with the original traceback, + # otherwise we raise it from here. + if error is exc_value: + reraise(exc_type, exc_value, tb) + raise error + + def preprocess_request(self): + """Called before the request is dispatched. Calls + :attr:`url_value_preprocessors` registered with the app and the + current blueprint (if any). Then calls :attr:`before_request_funcs` + registered with the app and the blueprint. + + If any :meth:`before_request` handler returns a non-None value, the + value is handled as if it was the return value from the view, and + further request handling is stopped. + """ + + bp = _request_ctx_stack.top.request.blueprint + + funcs = self.url_value_preprocessors.get(None, ()) + if bp is not None and bp in self.url_value_preprocessors: + funcs = chain(funcs, self.url_value_preprocessors[bp]) + for func in funcs: + func(request.endpoint, request.view_args) + + funcs = self.before_request_funcs.get(None, ()) + if bp is not None and bp in self.before_request_funcs: + funcs = chain(funcs, self.before_request_funcs[bp]) + for func in funcs: + rv = func() + if rv is not None: + return rv + + def process_response(self, response): + """Can be overridden in order to modify the response object + before it's sent to the WSGI server. By default this will + call all the :meth:`after_request` decorated functions. + + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + + :param response: a :attr:`response_class` object. + :return: a new response object or the same, has to be an + instance of :attr:`response_class`. + """ + ctx = _request_ctx_stack.top + bp = ctx.request.blueprint + funcs = ctx._after_request_functions + if bp is not None and bp in self.after_request_funcs: + funcs = chain(funcs, reversed(self.after_request_funcs[bp])) + if None in self.after_request_funcs: + funcs = chain(funcs, reversed(self.after_request_funcs[None])) + for handler in funcs: + response = handler(response) + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + return response + + def do_teardown_request(self, exc=_sentinel): + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + funcs = reversed(self.teardown_request_funcs.get(None, ())) + bp = _request_ctx_stack.top.request.blueprint + if bp is not None and bp in self.teardown_request_funcs: + funcs = chain(funcs, reversed(self.teardown_request_funcs[bp])) + for func in funcs: + func(exc) + request_tearing_down.send(self, exc=exc) + + def do_teardown_appcontext(self, exc=_sentinel): + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + for func in reversed(self.teardown_appcontext_funcs): + func(exc) + appcontext_tearing_down.send(self, exc=exc) + + def app_context(self): + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ): + """Create a :class:`~flask.ctx.RequestContext` representing a + WSGI environment. Use a ``with`` block to push the context, + which will make :data:`request` point at this request. + + See :doc:`/reqcontext`. + + Typically you should not call this from your own code. A request + context is automatically pushed by the :meth:`wsgi_app` when + handling a request. Use :meth:`test_request_context` to create + an environment and context instead of this method. + + :param environ: a WSGI environment + """ + return RequestContext(self, environ) + + def test_request_context(self, *args, **kwargs): + """Create a :class:`~flask.ctx.RequestContext` for a WSGI + environment created from the given values. This is mostly useful + during testing, where you may want to run a function that uses + request data without dispatching a full request. + + See :doc:`/reqcontext`. + + Use a ``with`` block to push the context, which will make + :data:`request` point at the request for the created + environment. :: + + with test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from flask.testing import make_test_environ_builder + + builder = make_test_environ_builder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app(self, environ, start_response): + """The actual WSGI application. This is not implemented in + :meth:`__call__` so that middlewares can be applied without + losing a reference to the app object. Instead of doing this:: + + app = MyMiddleware(app) + + It's a better idea to do this instead:: + + app.wsgi_app = MyMiddleware(app.wsgi_app) + + Then you still have the original application object around and + can continue to call methods on it. + + .. versionchanged:: 0.7 + Teardown events for the request and app contexts are called + even if an unhandled error occurs. Other events may not be + called depending on when an error occurs during dispatch. + See :ref:`callbacks-and-errors`. + + :param environ: A WSGI environment. + :param start_response: A callable accepting a status code, + a list of headers, and an optional exception context to + start the response. + """ + ctx = self.request_context(environ) + error = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if self.should_ignore_error(error): + error = None + ctx.auto_pop(error) + + def __call__(self, environ, start_response): + """The WSGI server calls the Flask application object as the + WSGI application. This calls :meth:`wsgi_app` which can be + wrapped to applying middleware.""" + return self.wsgi_app(environ, start_response) + + def __repr__(self): + return '<%s %r>' % ( + self.__class__.__name__, + self.name, + ) diff --git a/Lib/site-packages/flask/blueprints.py b/Lib/site-packages/flask/blueprints.py new file mode 100644 index 0000000..5ce5561 --- /dev/null +++ b/Lib/site-packages/flask/blueprints.py @@ -0,0 +1,448 @@ +# -*- coding: utf-8 -*- +""" + flask.blueprints + ~~~~~~~~~~~~~~~~ + + Blueprints are the recommended way to implement larger or more + pluggable applications in Flask 0.7 and later. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" +from functools import update_wrapper +from werkzeug.urls import url_join + +from .helpers import _PackageBoundObject, _endpoint_from_view_func + + +class BlueprintSetupState(object): + """Temporary holder object for registering a blueprint with the + application. An instance of this class is created by the + :meth:`~flask.Blueprint.make_setup_state` method and later passed + to all register callback functions. + """ + + def __init__(self, blueprint, app, options, first_registration): + #: a reference to the current application + self.app = app + + #: a reference to the blueprint that created this setup state. + self.blueprint = blueprint + + #: a dictionary with all options that were passed to the + #: :meth:`~flask.Flask.register_blueprint` method. + self.options = options + + #: as blueprints can be registered multiple times with the + #: application and not everything wants to be registered + #: multiple times on it, this attribute can be used to figure + #: out if the blueprint was registered in the past already. + self.first_registration = first_registration + + subdomain = self.options.get('subdomain') + if subdomain is None: + subdomain = self.blueprint.subdomain + + #: The subdomain that the blueprint should be active for, ``None`` + #: otherwise. + self.subdomain = subdomain + + url_prefix = self.options.get('url_prefix') + if url_prefix is None: + url_prefix = self.blueprint.url_prefix + #: The prefix that should be used for all URLs defined on the + #: blueprint. + self.url_prefix = url_prefix + + #: A dictionary with URL defaults that is added to each and every + #: URL that was defined with the blueprint. + self.url_defaults = dict(self.blueprint.url_values_defaults) + self.url_defaults.update(self.options.get('url_defaults', ())) + + def add_url_rule(self, rule, endpoint=None, view_func=None, **options): + """A helper method to register a rule (and optionally a view function) + to the application. The endpoint is automatically prefixed with the + blueprint's name. + """ + if self.url_prefix is not None: + if rule: + rule = '/'.join(( + self.url_prefix.rstrip('/'), rule.lstrip('/'))) + else: + rule = self.url_prefix + options.setdefault('subdomain', self.subdomain) + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) + defaults = self.url_defaults + if 'defaults' in options: + defaults = dict(defaults, **options.pop('defaults')) + self.app.add_url_rule(rule, '%s.%s' % (self.blueprint.name, endpoint), + view_func, defaults=defaults, **options) + + +class Blueprint(_PackageBoundObject): + """Represents a blueprint. A blueprint is an object that records + functions that will be called with the + :class:`~flask.blueprints.BlueprintSetupState` later to register functions + or other things on the main application. See :ref:`blueprints` for more + information. + + .. versionadded:: 0.7 + """ + + warn_on_modifications = False + _got_registered_once = False + + #: Blueprint local JSON decoder class to use. + #: Set to ``None`` to use the app's :class:`~flask.app.Flask.json_encoder`. + json_encoder = None + #: Blueprint local JSON decoder class to use. + #: Set to ``None`` to use the app's :class:`~flask.app.Flask.json_decoder`. + json_decoder = None + + # TODO remove the next three attrs when Sphinx :inherited-members: works + # https://github.com/sphinx-doc/sphinx/issues/741 + + #: The name of the package or module that this app belongs to. Do not + #: change this once it is set by the constructor. + import_name = None + + #: Location of the template files to be added to the template lookup. + #: ``None`` if templates should not be added. + template_folder = None + + #: Absolute path to the package on the filesystem. Used to look up + #: resources contained in the package. + root_path = None + + def __init__(self, name, import_name, static_folder=None, + static_url_path=None, template_folder=None, + url_prefix=None, subdomain=None, url_defaults=None, + root_path=None): + _PackageBoundObject.__init__(self, import_name, template_folder, + root_path=root_path) + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.static_folder = static_folder + self.static_url_path = static_url_path + self.deferred_functions = [] + if url_defaults is None: + url_defaults = {} + self.url_values_defaults = url_defaults + + def record(self, func): + """Registers a function that is called when the blueprint is + registered on the application. This function is called with the + state as argument as returned by the :meth:`make_setup_state` + method. + """ + if self._got_registered_once and self.warn_on_modifications: + from warnings import warn + warn(Warning('The blueprint was already registered once ' + 'but is getting modified now. These changes ' + 'will not show up.')) + self.deferred_functions.append(func) + + def record_once(self, func): + """Works like :meth:`record` but wraps the function in another + function that will ensure the function is only called once. If the + blueprint is registered a second time on the application, the + function passed is not called. + """ + def wrapper(state): + if state.first_registration: + func(state) + return self.record(update_wrapper(wrapper, func)) + + def make_setup_state(self, app, options, first_registration=False): + """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` + object that is later passed to the register callback functions. + Subclasses can override this to return a subclass of the setup state. + """ + return BlueprintSetupState(self, app, options, first_registration) + + def register(self, app, options, first_registration=False): + """Called by :meth:`Flask.register_blueprint` to register all views + and callbacks registered on the blueprint with the application. Creates + a :class:`.BlueprintSetupState` and calls each :meth:`record` callback + with it. + + :param app: The application this blueprint is being registered with. + :param options: Keyword arguments forwarded from + :meth:`~Flask.register_blueprint`. + :param first_registration: Whether this is the first time this + blueprint has been registered on the application. + """ + self._got_registered_once = True + state = self.make_setup_state(app, options, first_registration) + + if self.has_static_folder: + state.add_url_rule( + self.static_url_path + '/', + view_func=self.send_static_file, endpoint='static' + ) + + for deferred in self.deferred_functions: + deferred(state) + + def route(self, rule, **options): + """Like :meth:`Flask.route` but for a blueprint. The endpoint for the + :func:`url_for` function is prefixed with the name of the blueprint. + """ + def decorator(f): + endpoint = options.pop("endpoint", f.__name__) + self.add_url_rule(rule, endpoint, f, **options) + return f + return decorator + + def add_url_rule(self, rule, endpoint=None, view_func=None, **options): + """Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for + the :func:`url_for` function is prefixed with the name of the blueprint. + """ + if endpoint: + assert '.' not in endpoint, "Blueprint endpoints should not contain dots" + if view_func and hasattr(view_func, '__name__'): + assert '.' not in view_func.__name__, "Blueprint view function name should not contain dots" + self.record(lambda s: + s.add_url_rule(rule, endpoint, view_func, **options)) + + def endpoint(self, endpoint): + """Like :meth:`Flask.endpoint` but for a blueprint. This does not + prefix the endpoint with the blueprint name, this has to be done + explicitly by the user of this method. If the endpoint is prefixed + with a `.` it will be registered to the current blueprint, otherwise + it's an application independent endpoint. + """ + def decorator(f): + def register_endpoint(state): + state.app.view_functions[endpoint] = f + self.record_once(register_endpoint) + return f + return decorator + + def app_template_filter(self, name=None): + """Register a custom template filter, available application wide. Like + :meth:`Flask.template_filter` but for a blueprint. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + def decorator(f): + self.add_app_template_filter(f, name=name) + return f + return decorator + + def add_app_template_filter(self, f, name=None): + """Register a custom template filter, available application wide. Like + :meth:`Flask.add_template_filter` but for a blueprint. Works exactly + like the :meth:`app_template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + def register_template(state): + state.app.jinja_env.filters[name or f.__name__] = f + self.record_once(register_template) + + def app_template_test(self, name=None): + """Register a custom template test, available application wide. Like + :meth:`Flask.template_test` but for a blueprint. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + def decorator(f): + self.add_app_template_test(f, name=name) + return f + return decorator + + def add_app_template_test(self, f, name=None): + """Register a custom template test, available application wide. Like + :meth:`Flask.add_template_test` but for a blueprint. Works exactly + like the :meth:`app_template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + def register_template(state): + state.app.jinja_env.tests[name or f.__name__] = f + self.record_once(register_template) + + def app_template_global(self, name=None): + """Register a custom template global, available application wide. Like + :meth:`Flask.template_global` but for a blueprint. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + def decorator(f): + self.add_app_template_global(f, name=name) + return f + return decorator + + def add_app_template_global(self, f, name=None): + """Register a custom template global, available application wide. Like + :meth:`Flask.add_template_global` but for a blueprint. Works exactly + like the :meth:`app_template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + def register_template(state): + state.app.jinja_env.globals[name or f.__name__] = f + self.record_once(register_template) + + def before_request(self, f): + """Like :meth:`Flask.before_request` but for a blueprint. This function + is only executed before each request that is handled by a function of + that blueprint. + """ + self.record_once(lambda s: s.app.before_request_funcs + .setdefault(self.name, []).append(f)) + return f + + def before_app_request(self, f): + """Like :meth:`Flask.before_request`. Such a function is executed + before each request, even if outside of a blueprint. + """ + self.record_once(lambda s: s.app.before_request_funcs + .setdefault(None, []).append(f)) + return f + + def before_app_first_request(self, f): + """Like :meth:`Flask.before_first_request`. Such a function is + executed before the first request to the application. + """ + self.record_once(lambda s: s.app.before_first_request_funcs.append(f)) + return f + + def after_request(self, f): + """Like :meth:`Flask.after_request` but for a blueprint. This function + is only executed after each request that is handled by a function of + that blueprint. + """ + self.record_once(lambda s: s.app.after_request_funcs + .setdefault(self.name, []).append(f)) + return f + + def after_app_request(self, f): + """Like :meth:`Flask.after_request` but for a blueprint. Such a function + is executed after each request, even if outside of the blueprint. + """ + self.record_once(lambda s: s.app.after_request_funcs + .setdefault(None, []).append(f)) + return f + + def teardown_request(self, f): + """Like :meth:`Flask.teardown_request` but for a blueprint. This + function is only executed when tearing down requests handled by a + function of that blueprint. Teardown request functions are executed + when the request context is popped, even when no actual request was + performed. + """ + self.record_once(lambda s: s.app.teardown_request_funcs + .setdefault(self.name, []).append(f)) + return f + + def teardown_app_request(self, f): + """Like :meth:`Flask.teardown_request` but for a blueprint. Such a + function is executed when tearing down each request, even if outside of + the blueprint. + """ + self.record_once(lambda s: s.app.teardown_request_funcs + .setdefault(None, []).append(f)) + return f + + def context_processor(self, f): + """Like :meth:`Flask.context_processor` but for a blueprint. This + function is only executed for requests handled by a blueprint. + """ + self.record_once(lambda s: s.app.template_context_processors + .setdefault(self.name, []).append(f)) + return f + + def app_context_processor(self, f): + """Like :meth:`Flask.context_processor` but for a blueprint. Such a + function is executed each request, even if outside of the blueprint. + """ + self.record_once(lambda s: s.app.template_context_processors + .setdefault(None, []).append(f)) + return f + + def app_errorhandler(self, code): + """Like :meth:`Flask.errorhandler` but for a blueprint. This + handler is used for all requests, even if outside of the blueprint. + """ + def decorator(f): + self.record_once(lambda s: s.app.errorhandler(code)(f)) + return f + return decorator + + def url_value_preprocessor(self, f): + """Registers a function as URL value preprocessor for this + blueprint. It's called before the view functions are called and + can modify the url values provided. + """ + self.record_once(lambda s: s.app.url_value_preprocessors + .setdefault(self.name, []).append(f)) + return f + + def url_defaults(self, f): + """Callback function for URL defaults for this blueprint. It's called + with the endpoint and values and should update the values passed + in place. + """ + self.record_once(lambda s: s.app.url_default_functions + .setdefault(self.name, []).append(f)) + return f + + def app_url_value_preprocessor(self, f): + """Same as :meth:`url_value_preprocessor` but application wide. + """ + self.record_once(lambda s: s.app.url_value_preprocessors + .setdefault(None, []).append(f)) + return f + + def app_url_defaults(self, f): + """Same as :meth:`url_defaults` but application wide. + """ + self.record_once(lambda s: s.app.url_default_functions + .setdefault(None, []).append(f)) + return f + + def errorhandler(self, code_or_exception): + """Registers an error handler that becomes active for this blueprint + only. Please be aware that routing does not happen local to a + blueprint so an error handler for 404 usually is not handled by + a blueprint unless it is caused inside a view function. Another + special case is the 500 internal server error which is always looked + up from the application. + + Otherwise works as the :meth:`~flask.Flask.errorhandler` decorator + of the :class:`~flask.Flask` object. + """ + def decorator(f): + self.record_once(lambda s: s.app._register_error_handler( + self.name, code_or_exception, f)) + return f + return decorator + + def register_error_handler(self, code_or_exception, f): + """Non-decorator version of the :meth:`errorhandler` error attach + function, akin to the :meth:`~flask.Flask.register_error_handler` + application-wide function of the :class:`~flask.Flask` object but + for error handlers limited to this blueprint. + + .. versionadded:: 0.11 + """ + self.record_once(lambda s: s.app._register_error_handler( + self.name, code_or_exception, f)) diff --git a/Lib/site-packages/flask/cli.py b/Lib/site-packages/flask/cli.py new file mode 100644 index 0000000..efc1733 --- /dev/null +++ b/Lib/site-packages/flask/cli.py @@ -0,0 +1,898 @@ +# -*- coding: utf-8 -*- +""" + flask.cli + ~~~~~~~~~ + + A simple command line application to run flask apps. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +from __future__ import print_function + +import ast +import inspect +import os +import re +import ssl +import sys +import traceback +from functools import update_wrapper +from operator import attrgetter +from threading import Lock, Thread + +import click +from werkzeug.utils import import_string + +from . import __version__ +from ._compat import getargspec, iteritems, reraise, text_type +from .globals import current_app +from .helpers import get_debug_flag, get_env, get_load_dotenv + +try: + import dotenv +except ImportError: + dotenv = None + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(script_info, module): + """Given a module instance this tries to find the best possible + application in the module or raises an exception. + """ + from . import Flask + + # Search for the most common names first. + for attr_name in ('app', 'application'): + app = getattr(module, attr_name, None) + + if isinstance(app, Flask): + return app + + # Otherwise find the only object that is a Flask instance. + matches = [ + v for k, v in iteritems(module.__dict__) if isinstance(v, Flask) + ] + + if len(matches) == 1: + return matches[0] + elif len(matches) > 1: + raise NoAppException( + 'Detected multiple Flask applications in module "{module}". Use ' + '"FLASK_APP={module}:name" to specify the correct ' + 'one.'.format(module=module.__name__) + ) + + # Search for app factory functions. + for attr_name in ('create_app', 'make_app'): + app_factory = getattr(module, attr_name, None) + + if inspect.isfunction(app_factory): + try: + app = call_factory(script_info, app_factory) + + if isinstance(app, Flask): + return app + except TypeError: + if not _called_with_wrong_args(app_factory): + raise + raise NoAppException( + 'Detected factory "{factory}" in module "{module}", but ' + 'could not call it without arguments. Use ' + '"FLASK_APP=\'{module}:{factory}(args)\'" to specify ' + 'arguments.'.format( + factory=attr_name, module=module.__name__ + ) + ) + + raise NoAppException( + 'Failed to find Flask application or factory in module "{module}". ' + 'Use "FLASK_APP={module}:name to specify one.'.format( + module=module.__name__ + ) + ) + + +def call_factory(script_info, app_factory, arguments=()): + """Takes an app factory, a ``script_info` object and optionally a tuple + of arguments. Checks for the existence of a script_info argument and calls + the app_factory depending on that and the arguments provided. + """ + args_spec = getargspec(app_factory) + arg_names = args_spec.args + arg_defaults = args_spec.defaults + + if 'script_info' in arg_names: + return app_factory(*arguments, script_info=script_info) + elif arguments: + return app_factory(*arguments) + elif not arguments and len(arg_names) == 1 and arg_defaults is None: + return app_factory(script_info) + + return app_factory() + + +def _called_with_wrong_args(factory): + """Check whether calling a function raised a ``TypeError`` because + the call failed or because something in the factory raised the + error. + + :param factory: the factory function that was called + :return: true if the call failed + """ + tb = sys.exc_info()[2] + + try: + while tb is not None: + if tb.tb_frame.f_code is factory.__code__: + # in the factory, it was called successfully + return False + + tb = tb.tb_next + + # didn't reach the factory + return True + finally: + del tb + + +def find_app_by_string(script_info, module, app_name): + """Checks if the given string is a variable name or a function. If it is a + function, it checks for specified arguments and whether it takes a + ``script_info`` argument and calls the function with the appropriate + arguments. + """ + from flask import Flask + match = re.match(r'^ *([^ ()]+) *(?:\((.*?) *,? *\))? *$', app_name) + + if not match: + raise NoAppException( + '"{name}" is not a valid variable name or function ' + 'expression.'.format(name=app_name) + ) + + name, args = match.groups() + + try: + attr = getattr(module, name) + except AttributeError as e: + raise NoAppException(e.args[0]) + + if inspect.isfunction(attr): + if args: + try: + args = ast.literal_eval('({args},)'.format(args=args)) + except (ValueError, SyntaxError)as e: + raise NoAppException( + 'Could not parse the arguments in ' + '"{app_name}".'.format(e=e, app_name=app_name) + ) + else: + args = () + + try: + app = call_factory(script_info, attr, args) + except TypeError as e: + if not _called_with_wrong_args(attr): + raise + + raise NoAppException( + '{e}\nThe factory "{app_name}" in module "{module}" could not ' + 'be called with the specified arguments.'.format( + e=e, app_name=app_name, module=module.__name__ + ) + ) + else: + app = attr + + if isinstance(app, Flask): + return app + + raise NoAppException( + 'A valid Flask application was not obtained from ' + '"{module}:{app_name}".'.format( + module=module.__name__, app_name=app_name + ) + ) + + +def prepare_import(path): + """Given a filename this will try to calculate the python path, add it + to the search path and return the actual module name that is expected. + """ + path = os.path.realpath(path) + + if os.path.splitext(path)[1] == '.py': + path = os.path.splitext(path)[0] + + if os.path.basename(path) == '__init__': + path = os.path.dirname(path) + + module_name = [] + + # move up until outside package structure (no __init__.py) + while True: + path, name = os.path.split(path) + module_name.append(name) + + if not os.path.exists(os.path.join(path, '__init__.py')): + break + + if sys.path[0] != path: + sys.path.insert(0, path) + + return '.'.join(module_name[::-1]) + + +def locate_app(script_info, module_name, app_name, raise_if_not_found=True): + __traceback_hide__ = True + + try: + __import__(module_name) + except ImportError: + # Reraise the ImportError if it occurred within the imported module. + # Determine this by checking whether the trace has a depth > 1. + if sys.exc_info()[-1].tb_next: + raise NoAppException( + 'While importing "{name}", an ImportError was raised:' + '\n\n{tb}'.format(name=module_name, tb=traceback.format_exc()) + ) + elif raise_if_not_found: + raise NoAppException( + 'Could not import "{name}".'.format(name=module_name) + ) + else: + return + + module = sys.modules[module_name] + + if app_name is None: + return find_best_app(script_info, module) + else: + return find_app_by_string(script_info, module, app_name) + + +def get_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + message = 'Flask %(version)s\nPython %(python_version)s' + click.echo(message % { + 'version': __version__, + 'python_version': sys.version, + }, color=ctx.color) + ctx.exit() + + +version_option = click.Option( + ['--version'], + help='Show the flask version', + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True +) + + +class DispatchingApp(object): + """Special application that dispatches to a Flask application which + is imported by name in a background thread. If an error happens + it is recorded and shown as part of the WSGI handling which in case + of the Werkzeug debugger means that it shows up in the browser. + """ + + def __init__(self, loader, use_eager_loading=False): + self.loader = loader + self._app = None + self._lock = Lock() + self._bg_loading_exc_info = None + if use_eager_loading: + self._load_unlocked() + else: + self._load_in_background() + + def _load_in_background(self): + def _load_app(): + __traceback_hide__ = True + with self._lock: + try: + self._load_unlocked() + except Exception: + self._bg_loading_exc_info = sys.exc_info() + t = Thread(target=_load_app, args=()) + t.start() + + def _flush_bg_loading_exception(self): + __traceback_hide__ = True + exc_info = self._bg_loading_exc_info + if exc_info is not None: + self._bg_loading_exc_info = None + reraise(*exc_info) + + def _load_unlocked(self): + __traceback_hide__ = True + self._app = rv = self.loader() + self._bg_loading_exc_info = None + return rv + + def __call__(self, environ, start_response): + __traceback_hide__ = True + if self._app is not None: + return self._app(environ, start_response) + self._flush_bg_loading_exception() + with self._lock: + if self._app is not None: + rv = self._app + else: + rv = self._load_unlocked() + return rv(environ, start_response) + + +class ScriptInfo(object): + """Help object to deal with Flask applications. This is usually not + necessary to interface with as it's used internally in the dispatching + to click. In future versions of Flask this object will most likely play + a bigger role. Typically it's created automatically by the + :class:`FlaskGroup` but you can also manually create it and pass it + onwards as click object. + """ + + def __init__(self, app_import_path=None, create_app=None): + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path or os.environ.get('FLASK_APP') + #: Optionally a function that is passed the script info to create + #: the instance of the application. + self.create_app = create_app + #: A dictionary with arbitrary data that can be associated with + #: this script info. + self.data = {} + self._loaded_app = None + + def load_app(self): + """Loads the Flask app (if not yet loaded) and returns it. Calling + this multiple times will just result in the already loaded app to + be returned. + """ + __traceback_hide__ = True + + if self._loaded_app is not None: + return self._loaded_app + + app = None + + if self.create_app is not None: + app = call_factory(self, self.create_app) + else: + if self.app_import_path: + path, name = (self.app_import_path.split(':', 1) + [None])[:2] + import_name = prepare_import(path) + app = locate_app(self, import_name, name) + else: + for path in ('wsgi.py', 'app.py'): + import_name = prepare_import(path) + app = locate_app(self, import_name, None, + raise_if_not_found=False) + + if app: + break + + if not app: + raise NoAppException( + 'Could not locate a Flask application. You did not provide ' + 'the "FLASK_APP" environment variable, and a "wsgi.py" or ' + '"app.py" module was not found in the current directory.' + ) + + debug = get_debug_flag() + + # Update the app's debug flag through the descriptor so that other + # values repopulate as well. + if debug is not None: + app.debug = debug + + self._loaded_app = app + return app + + +pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True) + + +def with_appcontext(f): + """Wraps a callback so that it's guaranteed to be executed with the + script's application context. If callbacks are registered directly + to the ``app.cli`` object then they are wrapped with this function + by default unless it's disabled. + """ + @click.pass_context + def decorator(__ctx, *args, **kwargs): + with __ctx.ensure_object(ScriptInfo).load_app().app_context(): + return __ctx.invoke(f, *args, **kwargs) + return update_wrapper(decorator, f) + + +class AppGroup(click.Group): + """This works similar to a regular click :class:`~click.Group` but it + changes the behavior of the :meth:`command` decorator so that it + automatically wraps the functions in :func:`with_appcontext`. + + Not to be confused with :class:`FlaskGroup`. + """ + + def command(self, *args, **kwargs): + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it wraps callbacks in :func:`with_appcontext` + unless it's disabled by passing ``with_appcontext=False``. + """ + wrap_for_ctx = kwargs.pop('with_appcontext', True) + def decorator(f): + if wrap_for_ctx: + f = with_appcontext(f) + return click.Group.command(self, *args, **kwargs)(f) + return decorator + + def group(self, *args, **kwargs): + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it defaults the group class to + :class:`AppGroup`. + """ + kwargs.setdefault('cls', AppGroup) + return click.Group.group(self, *args, **kwargs) + + +class FlaskGroup(AppGroup): + """Special subclass of the :class:`AppGroup` group that supports + loading more commands from the configured Flask app. Normally a + developer does not have to interface with this class but there are + some very advanced use cases for which it makes sense to create an + instance of this. + + For information as of why this is useful see :ref:`custom-scripts`. + + :param add_default_commands: if this is True then the default run and + shell commands wil be added. + :param add_version_option: adds the ``--version`` option. + :param create_app: an optional callback that is passed the script info and + returns the loaded app. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment variables + from :file:`.env` and :file:`.flaskenv` files. + """ + + def __init__(self, add_default_commands=True, create_app=None, + add_version_option=True, load_dotenv=True, **extra): + params = list(extra.pop('params', None) or ()) + + if add_version_option: + params.append(version_option) + + AppGroup.__init__(self, params=params, **extra) + self.create_app = create_app + self.load_dotenv = load_dotenv + + if add_default_commands: + self.add_command(run_command) + self.add_command(shell_command) + self.add_command(routes_command) + + self._loaded_plugin_commands = False + + def _load_plugin_commands(self): + if self._loaded_plugin_commands: + return + try: + import pkg_resources + except ImportError: + self._loaded_plugin_commands = True + return + + for ep in pkg_resources.iter_entry_points('flask.commands'): + self.add_command(ep.load(), ep.name) + self._loaded_plugin_commands = True + + def get_command(self, ctx, name): + self._load_plugin_commands() + + # We load built-in commands first as these should always be the + # same no matter what the app does. If the app does want to + # override this it needs to make a custom instance of this group + # and not attach the default commands. + # + # This also means that the script stays functional in case the + # application completely fails. + rv = AppGroup.get_command(self, ctx, name) + if rv is not None: + return rv + + info = ctx.ensure_object(ScriptInfo) + try: + rv = info.load_app().cli.get_command(ctx, name) + if rv is not None: + return rv + except NoAppException: + pass + + def list_commands(self, ctx): + self._load_plugin_commands() + + # The commands available is the list of both the application (if + # available) plus the builtin commands. + rv = set(click.Group.list_commands(self, ctx)) + info = ctx.ensure_object(ScriptInfo) + try: + rv.update(info.load_app().cli.list_commands(ctx)) + except Exception: + # Here we intentionally swallow all exceptions as we don't + # want the help page to break if the app does not exist. + # If someone attempts to use the command we try to create + # the app again and this will give us the error. + # However, we will not do so silently because that would confuse + # users. + traceback.print_exc() + return sorted(rv) + + def main(self, *args, **kwargs): + # Set a global flag that indicates that we were invoked from the + # command line interface. This is detected by Flask.run to make the + # call into a no-op. This is necessary to avoid ugly errors when the + # script that is loaded here also attempts to start a server. + os.environ['FLASK_RUN_FROM_CLI'] = 'true' + + if get_load_dotenv(self.load_dotenv): + load_dotenv() + + obj = kwargs.get('obj') + + if obj is None: + obj = ScriptInfo(create_app=self.create_app) + + kwargs['obj'] = obj + kwargs.setdefault('auto_envvar_prefix', 'FLASK') + return super(FlaskGroup, self).main(*args, **kwargs) + + +def _path_is_ancestor(path, other): + """Take ``other`` and remove the length of ``path`` from it. Then join it + to ``path``. If it is the original value, ``path`` is an ancestor of + ``other``.""" + return os.path.join(path, other[len(path):].lstrip(os.sep)) == other + + +def load_dotenv(path=None): + """Load "dotenv" files in order of precedence to set environment variables. + + If an env var is already set it is not overwritten, so earlier files in the + list are preferred over later files. + + Changes the current working directory to the location of the first file + found, with the assumption that it is in the top level project directory + and will be where the Python path should import local packages from. + + This is a no-op if `python-dotenv`_ is not installed. + + .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme + + :param path: Load the file at this location instead of searching. + :return: ``True`` if a file was loaded. + + .. versionadded:: 1.0 + """ + if dotenv is None: + if path or os.path.exists('.env') or os.path.exists('.flaskenv'): + click.secho( + ' * Tip: There are .env files present.' + ' Do "pip install python-dotenv" to use them.', + fg='yellow') + return + + if path is not None: + return dotenv.load_dotenv(path) + + new_dir = None + + for name in ('.env', '.flaskenv'): + path = dotenv.find_dotenv(name, usecwd=True) + + if not path: + continue + + if new_dir is None: + new_dir = os.path.dirname(path) + + dotenv.load_dotenv(path) + + if new_dir and os.getcwd() != new_dir: + os.chdir(new_dir) + + return new_dir is not None # at least one file was located and loaded + + +def show_server_banner(env, debug, app_import_path, eager_loading): + """Show extra startup messages the first time the server is run, + ignoring the reloader. + """ + if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': + return + + if app_import_path is not None: + message = ' * Serving Flask app "{0}"'.format(app_import_path) + + if not eager_loading: + message += ' (lazy loading)' + + click.echo(message) + + click.echo(' * Environment: {0}'.format(env)) + + if env == 'production': + click.secho( + ' WARNING: Do not use the development server in a production' + ' environment.', fg='red') + click.secho(' Use a production WSGI server instead.', dim=True) + + if debug is not None: + click.echo(' * Debug mode: {0}'.format('on' if debug else 'off')) + + +class CertParamType(click.ParamType): + """Click option type for the ``--cert`` option. Allows either an + existing file, the string ``'adhoc'``, or an import for a + :class:`~ssl.SSLContext` object. + """ + + name = 'path' + + def __init__(self): + self.path_type = click.Path( + exists=True, dir_okay=False, resolve_path=True) + + def convert(self, value, param, ctx): + try: + return self.path_type(value, param, ctx) + except click.BadParameter: + value = click.STRING(value, param, ctx).lower() + + if value == 'adhoc': + try: + import OpenSSL + except ImportError: + raise click.BadParameter( + 'Using ad-hoc certificates requires pyOpenSSL.', + ctx, param) + + return value + + obj = import_string(value, silent=True) + + if sys.version_info < (2, 7): + if obj: + return obj + else: + if isinstance(obj, ssl.SSLContext): + return obj + + raise + + +def _validate_key(ctx, param, value): + """The ``--key`` option must be specified when ``--cert`` is a file. + Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. + """ + cert = ctx.params.get('cert') + is_adhoc = cert == 'adhoc' + + if sys.version_info < (2, 7): + is_context = cert and not isinstance(cert, (text_type, bytes)) + else: + is_context = isinstance(cert, ssl.SSLContext) + + if value is not None: + if is_adhoc: + raise click.BadParameter( + 'When "--cert" is "adhoc", "--key" is not used.', + ctx, param) + + if is_context: + raise click.BadParameter( + 'When "--cert" is an SSLContext object, "--key is not used.', + ctx, param) + + if not cert: + raise click.BadParameter( + '"--cert" must also be specified.', + ctx, param) + + ctx.params['cert'] = cert, value + + else: + if cert and not (is_adhoc or is_context): + raise click.BadParameter( + 'Required when using "--cert".', + ctx, param) + + return value + + +@click.command('run', short_help='Runs a development server.') +@click.option('--host', '-h', default='127.0.0.1', + help='The interface to bind to.') +@click.option('--port', '-p', default=5000, + help='The port to bind to.') +@click.option('--cert', type=CertParamType(), + help='Specify a certificate file to use HTTPS.') +@click.option('--key', + type=click.Path(exists=True, dir_okay=False, resolve_path=True), + callback=_validate_key, expose_value=False, + help='The key file to use when specifying a certificate.') +@click.option('--reload/--no-reload', default=None, + help='Enable or disable the reloader. By default the reloader ' + 'is active if debug is enabled.') +@click.option('--debugger/--no-debugger', default=None, + help='Enable or disable the debugger. By default the debugger ' + 'is active if debug is enabled.') +@click.option('--eager-loading/--lazy-loader', default=None, + help='Enable or disable eager loading. By default eager ' + 'loading is enabled if the reloader is disabled.') +@click.option('--with-threads/--without-threads', default=True, + help='Enable or disable multithreading.') +@pass_script_info +def run_command(info, host, port, reload, debugger, eager_loading, + with_threads, cert): + """Run a local development server. + + This server is for development purposes only. It does not provide + the stability, security, or performance of production WSGI servers. + + The reloader and debugger are enabled by default if + FLASK_ENV=development or FLASK_DEBUG=1. + """ + debug = get_debug_flag() + + if reload is None: + reload = debug + + if debugger is None: + debugger = debug + + if eager_loading is None: + eager_loading = not reload + + show_server_banner(get_env(), debug, info.app_import_path, eager_loading) + app = DispatchingApp(info.load_app, use_eager_loading=eager_loading) + + from werkzeug.serving import run_simple + run_simple(host, port, app, use_reloader=reload, use_debugger=debugger, + threaded=with_threads, ssl_context=cert) + + +@click.command('shell', short_help='Runs a shell in the app context.') +@with_appcontext +def shell_command(): + """Runs an interactive Python shell in the context of a given + Flask application. The application will populate the default + namespace of this shell according to it's configuration. + + This is useful for executing small snippets of management code + without having to manually configure the application. + """ + import code + from flask.globals import _app_ctx_stack + app = _app_ctx_stack.top.app + banner = 'Python %s on %s\nApp: %s [%s]\nInstance: %s' % ( + sys.version, + sys.platform, + app.import_name, + app.env, + app.instance_path, + ) + ctx = {} + + # Support the regular Python interpreter startup script if someone + # is using it. + startup = os.environ.get('PYTHONSTARTUP') + if startup and os.path.isfile(startup): + with open(startup, 'r') as f: + eval(compile(f.read(), startup, 'exec'), ctx) + + ctx.update(app.make_shell_context()) + + code.interact(banner=banner, local=ctx) + + +@click.command('routes', short_help='Show the routes for the app.') +@click.option( + '--sort', '-s', + type=click.Choice(('endpoint', 'methods', 'rule', 'match')), + default='endpoint', + help=( + 'Method to sort routes by. "match" is the order that Flask will match ' + 'routes when dispatching a request.' + ) +) +@click.option( + '--all-methods', + is_flag=True, + help="Show HEAD and OPTIONS methods." +) +@with_appcontext +def routes_command(sort, all_methods): + """Show all registered routes with endpoints and methods.""" + + rules = list(current_app.url_map.iter_rules()) + if not rules: + click.echo('No routes were registered.') + return + + ignored_methods = set(() if all_methods else ('HEAD', 'OPTIONS')) + + if sort in ('endpoint', 'rule'): + rules = sorted(rules, key=attrgetter(sort)) + elif sort == 'methods': + rules = sorted(rules, key=lambda rule: sorted(rule.methods)) + + rule_methods = [ + ', '.join(sorted(rule.methods - ignored_methods)) for rule in rules + ] + + headers = ('Endpoint', 'Methods', 'Rule') + widths = ( + max(len(rule.endpoint) for rule in rules), + max(len(methods) for methods in rule_methods), + max(len(rule.rule) for rule in rules), + ) + widths = [max(len(h), w) for h, w in zip(headers, widths)] + row = '{{0:<{0}}} {{1:<{1}}} {{2:<{2}}}'.format(*widths) + + click.echo(row.format(*headers).strip()) + click.echo(row.format(*('-' * width for width in widths))) + + for rule, methods in zip(rules, rule_methods): + click.echo(row.format(rule.endpoint, methods, rule.rule).rstrip()) + + +cli = FlaskGroup(help="""\ +A general utility script for Flask applications. + +Provides commands from Flask, extensions, and the application. Loads the +application defined in the FLASK_APP environment variable, or from a wsgi.py +file. Setting the FLASK_ENV environment variable to 'development' will enable +debug mode. + +\b + {prefix}{cmd} FLASK_APP=hello.py + {prefix}{cmd} FLASK_ENV=development + {prefix}flask run +""".format( + cmd='export' if os.name == 'posix' else 'set', + prefix='$ ' if os.name == 'posix' else '> ' +)) + + +def main(as_module=False): + args = sys.argv[1:] + + if as_module: + this_module = 'flask' + + if sys.version_info < (2, 7): + this_module += '.cli' + + name = 'python -m ' + this_module + + # Python rewrites "python -m flask" to the path to the file in argv. + # Restore the original command so that the reloader works. + sys.argv = ['-m', this_module] + args + else: + name = None + + cli.main(args=args, prog_name=name) + + +if __name__ == '__main__': + main(as_module=True) diff --git a/Lib/site-packages/flask/config.py b/Lib/site-packages/flask/config.py new file mode 100644 index 0000000..d6074ba --- /dev/null +++ b/Lib/site-packages/flask/config.py @@ -0,0 +1,265 @@ +# -*- coding: utf-8 -*- +""" + flask.config + ~~~~~~~~~~~~ + + Implements the configuration related objects. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +import types +import errno + +from werkzeug.utils import import_string +from ._compat import string_types, iteritems +from . import json + + +class ConfigAttribute(object): + """Makes an attribute forward to the config""" + + def __init__(self, name, get_converter=None): + self.__name__ = name + self.get_converter = get_converter + + def __get__(self, obj, type=None): + if obj is None: + return self + rv = obj.config[self.__name__] + if self.get_converter is not None: + rv = self.get_converter(rv) + return rv + + def __set__(self, obj, value): + obj.config[self.__name__] = value + + +class Config(dict): + """Works exactly like a dict but provides ways to fill it from files + or special dictionaries. There are two common patterns to populate the + config. + + Either you can fill the config from a config file:: + + app.config.from_pyfile('yourconfig.cfg') + + Or alternatively you can define the configuration options in the + module that calls :meth:`from_object` or provide an import path to + a module that should be loaded. It is also possible to tell it to + use the same module and with that provide the configuration values + just before the call:: + + DEBUG = True + SECRET_KEY = 'development key' + app.config.from_object(__name__) + + In both cases (loading from any Python file or loading from modules), + only uppercase keys are added to the config. This makes it possible to use + lowercase values in the config file for temporary values that are not added + to the config or to define the config keys in the same file that implements + the application. + + Probably the most interesting way to load configurations is from an + environment variable pointing to a file:: + + app.config.from_envvar('YOURAPPLICATION_SETTINGS') + + In this case before launching the application you have to set this + environment variable to the file you want to use. On Linux and OS X + use the export statement:: + + export YOURAPPLICATION_SETTINGS='/path/to/config/file' + + On windows use `set` instead. + + :param root_path: path to which files are read relative from. When the + config object is created by the application, this is + the application's :attr:`~flask.Flask.root_path`. + :param defaults: an optional dictionary of default values + """ + + def __init__(self, root_path, defaults=None): + dict.__init__(self, defaults or {}) + self.root_path = root_path + + def from_envvar(self, variable_name, silent=False): + """Loads a configuration from an environment variable pointing to + a configuration file. This is basically just a shortcut with nicer + error messages for this line of code:: + + app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) + + :param variable_name: name of the environment variable + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: bool. ``True`` if able to load config, ``False`` otherwise. + """ + rv = os.environ.get(variable_name) + if not rv: + if silent: + return False + raise RuntimeError('The environment variable %r is not set ' + 'and as such configuration could not be ' + 'loaded. Set this variable and make it ' + 'point to a configuration file' % + variable_name) + return self.from_pyfile(rv, silent=silent) + + def from_pyfile(self, filename, silent=False): + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType('config') + d.__file__ = filename + try: + with open(filename, mode='rb') as config_file: + exec(compile(config_file.read(), filename, 'exec'), d.__dict__) + except IOError as e: + if silent and e.errno in ( + errno.ENOENT, errno.EISDIR, errno.ENOTDIR + ): + return False + e.strerror = 'Unable to load configuration file (%s)' % e.strerror + raise + self.from_object(d) + return True + + def from_object(self, obj): + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, string_types): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_json(self, filename, silent=False): + """Updates the values in the config from a JSON file. This function + behaves as if the JSON object was a dictionary and passed to the + :meth:`from_mapping` function. + + :param filename: the filename of the JSON file. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + + .. versionadded:: 0.11 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename) as json_file: + obj = json.loads(json_file.read()) + except IOError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + e.strerror = 'Unable to load configuration file (%s)' % e.strerror + raise + return self.from_mapping(obj) + + def from_mapping(self, *mapping, **kwargs): + """Updates the config like :meth:`update` ignoring items with non-upper + keys. + + .. versionadded:: 0.11 + """ + mappings = [] + if len(mapping) == 1: + if hasattr(mapping[0], 'items'): + mappings.append(mapping[0].items()) + else: + mappings.append(mapping[0]) + elif len(mapping) > 1: + raise TypeError( + 'expected at most 1 positional argument, got %d' % len(mapping) + ) + mappings.append(kwargs.items()) + for mapping in mappings: + for (key, value) in mapping: + if key.isupper(): + self[key] = value + return True + + def get_namespace(self, namespace, lowercase=True, trim_namespace=True): + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in iteritems(self): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace):] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self): + return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self)) diff --git a/Lib/site-packages/flask/ctx.py b/Lib/site-packages/flask/ctx.py new file mode 100644 index 0000000..8472c92 --- /dev/null +++ b/Lib/site-packages/flask/ctx.py @@ -0,0 +1,457 @@ +# -*- coding: utf-8 -*- +""" + flask.ctx + ~~~~~~~~~ + + Implements the objects required to keep the context. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import sys +from functools import update_wrapper + +from werkzeug.exceptions import HTTPException + +from .globals import _request_ctx_stack, _app_ctx_stack +from .signals import appcontext_pushed, appcontext_popped +from ._compat import BROKEN_PYPY_CTXMGR_EXIT, reraise + + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +class _AppCtxGlobals(object): + """A plain object. Used as a namespace for storing data during an + application context. + + Creating an app context automatically creates this object, which is + made available as the :data:`g` proxy. + + .. describe:: 'key' in g + + Check whether an attribute is present. + + .. versionadded:: 0.10 + + .. describe:: iter(g) + + Return an iterator over the attribute names. + + .. versionadded:: 0.10 + """ + + def get(self, name, default=None): + """Get an attribute by name, or a default value. Like + :meth:`dict.get`. + + :param name: Name of attribute to get. + :param default: Value to return if the attribute is not present. + + .. versionadded:: 0.10 + """ + return self.__dict__.get(name, default) + + def pop(self, name, default=_sentinel): + """Get and remove an attribute by name. Like :meth:`dict.pop`. + + :param name: Name of attribute to pop. + :param default: Value to return if the attribute is not present, + instead of raise a ``KeyError``. + + .. versionadded:: 0.11 + """ + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name, default=None): + """Get the value of an attribute if it is present, otherwise + set and return a default value. Like :meth:`dict.setdefault`. + + :param name: Name of attribute to get. + :param: default: Value to set and return if the attribute is not + present. + + .. versionadded:: 0.11 + """ + return self.__dict__.setdefault(name, default) + + def __contains__(self, item): + return item in self.__dict__ + + def __iter__(self): + return iter(self.__dict__) + + def __repr__(self): + top = _app_ctx_stack.top + if top is not None: + return '' % top.app.name + return object.__repr__(self) + + +def after_this_request(f): + """Executes a function after this request. This is useful to modify + response objects. The function is passed the response object and has + to return the same or a new one. + + Example:: + + @app.route('/') + def index(): + @after_this_request + def add_header(response): + response.headers['X-Foo'] = 'Parachute' + return response + return 'Hello World!' + + This is more useful if a function other than the view function wants to + modify a response. For instance think of a decorator that wants to add + some headers without converting the return value into a response object. + + .. versionadded:: 0.9 + """ + _request_ctx_stack.top._after_request_functions.append(f) + return f + + +def copy_current_request_context(f): + """A helper function that decorates a function to retain the current + request context. This is useful when working with greenlets. The moment + the function is decorated a copy of the request context is created and + then pushed when the function is called. + + Example:: + + import gevent + from flask import copy_current_request_context + + @app.route('/') + def index(): + @copy_current_request_context + def do_some_work(): + # do some work here, it can access flask.request like you + # would otherwise in the view function. + ... + gevent.spawn(do_some_work) + return 'Regular response' + + .. versionadded:: 0.10 + """ + top = _request_ctx_stack.top + if top is None: + raise RuntimeError('This decorator can only be used at local scopes ' + 'when a request context is on the stack. For instance within ' + 'view functions.') + reqctx = top.copy() + def wrapper(*args, **kwargs): + with reqctx: + return f(*args, **kwargs) + return update_wrapper(wrapper, f) + + +def has_request_context(): + """If you have code that wants to test if a request context is there or + not this function can be used. For instance, you may want to take advantage + of request information if the request object is available, but fail + silently if it is unavailable. + + :: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and has_request_context(): + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + Alternatively you can also just test any of the context bound objects + (such as :class:`request` or :class:`g` for truthness):: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and request: + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + .. versionadded:: 0.7 + """ + return _request_ctx_stack.top is not None + + +def has_app_context(): + """Works like :func:`has_request_context` but for the application + context. You can also just do a boolean check on the + :data:`current_app` object instead. + + .. versionadded:: 0.9 + """ + return _app_ctx_stack.top is not None + + +class AppContext(object): + """The application context binds an application object implicitly + to the current thread or greenlet, similar to how the + :class:`RequestContext` binds request information. The application + context is also implicitly created if a request context is created + but the application is not on top of the individual application + context. + """ + + def __init__(self, app): + self.app = app + self.url_adapter = app.create_url_adapter(None) + self.g = app.app_ctx_globals_class() + + # Like request context, app contexts can be pushed multiple times + # but there a basic "refcount" is enough to track them. + self._refcnt = 0 + + def push(self): + """Binds the app context to the current context.""" + self._refcnt += 1 + if hasattr(sys, 'exc_clear'): + sys.exc_clear() + _app_ctx_stack.push(self) + appcontext_pushed.send(self.app) + + def pop(self, exc=_sentinel): + """Pops the app context.""" + try: + self._refcnt -= 1 + if self._refcnt <= 0: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + rv = _app_ctx_stack.pop() + assert rv is self, 'Popped wrong app context. (%r instead of %r)' \ + % (rv, self) + appcontext_popped.send(self.app) + + def __enter__(self): + self.push() + return self + + def __exit__(self, exc_type, exc_value, tb): + self.pop(exc_value) + + if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None: + reraise(exc_type, exc_value, tb) + + +class RequestContext(object): + """The request context contains all request relevant information. It is + created at the beginning of the request and pushed to the + `_request_ctx_stack` and removed at the end of it. It will create the + URL adapter and request object for the WSGI environment provided. + + Do not attempt to use this class directly, instead use + :meth:`~flask.Flask.test_request_context` and + :meth:`~flask.Flask.request_context` to create this object. + + When the request context is popped, it will evaluate all the + functions registered on the application for teardown execution + (:meth:`~flask.Flask.teardown_request`). + + The request context is automatically popped at the end of the request + for you. In debug mode the request context is kept around if + exceptions happen so that interactive debuggers have a chance to + introspect the data. With 0.4 this can also be forced for requests + that did not fail and outside of ``DEBUG`` mode. By setting + ``'flask._preserve_context'`` to ``True`` on the WSGI environment the + context will not pop itself at the end of the request. This is used by + the :meth:`~flask.Flask.test_client` for example to implement the + deferred cleanup functionality. + + You might find this helpful for unittests where you need the + information from the context local around for a little longer. Make + sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in + that situation, otherwise your unittests will leak memory. + """ + + def __init__(self, app, environ, request=None): + self.app = app + if request is None: + request = app.request_class(environ) + self.request = request + self.url_adapter = app.create_url_adapter(self.request) + self.flashes = None + self.session = None + + # Request contexts can be pushed multiple times and interleaved with + # other request contexts. Now only if the last level is popped we + # get rid of them. Additionally if an application context is missing + # one is created implicitly so for each level we add this information + self._implicit_app_ctx_stack = [] + + # indicator if the context was preserved. Next time another context + # is pushed the preserved context is popped. + self.preserved = False + + # remembers the exception for pop if there is one in case the context + # preservation kicks in. + self._preserved_exc = None + + # Functions that should be executed after the request on the response + # object. These will be called before the regular "after_request" + # functions. + self._after_request_functions = [] + + self.match_request() + + def _get_g(self): + return _app_ctx_stack.top.g + def _set_g(self, value): + _app_ctx_stack.top.g = value + g = property(_get_g, _set_g) + del _get_g, _set_g + + def copy(self): + """Creates a copy of this request context with the same request object. + This can be used to move a request context to a different greenlet. + Because the actual request object is the same this cannot be used to + move a request context to a different thread unless access to the + request object is locked. + + .. versionadded:: 0.10 + """ + return self.__class__(self.app, + environ=self.request.environ, + request=self.request + ) + + def match_request(self): + """Can be overridden by a subclass to hook into the matching + of the request. + """ + try: + url_rule, self.request.view_args = \ + self.url_adapter.match(return_rule=True) + self.request.url_rule = url_rule + except HTTPException as e: + self.request.routing_exception = e + + def push(self): + """Binds the request context to the current context.""" + # If an exception occurs in debug mode or if context preservation is + # activated under exception situations exactly one context stays + # on the stack. The rationale is that you want to access that + # information under debug situations. However if someone forgets to + # pop that context again we want to make sure that on the next push + # it's invalidated, otherwise we run at risk that something leaks + # memory. This is usually only a problem in test suite since this + # functionality is not active in production environments. + top = _request_ctx_stack.top + if top is not None and top.preserved: + top.pop(top._preserved_exc) + + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _app_ctx_stack.top + if app_ctx is None or app_ctx.app != self.app: + app_ctx = self.app.app_context() + app_ctx.push() + self._implicit_app_ctx_stack.append(app_ctx) + else: + self._implicit_app_ctx_stack.append(None) + + if hasattr(sys, 'exc_clear'): + sys.exc_clear() + + _request_ctx_stack.push(self) + + # Open the session at the moment that the request context is available. + # This allows a custom open_session method to use the request context. + # Only open a new session if this is the first time the request was + # pushed, otherwise stream_with_context loses the session. + if self.session is None: + session_interface = self.app.session_interface + self.session = session_interface.open_session( + self.app, self.request + ) + + if self.session is None: + self.session = session_interface.make_null_session(self.app) + + def pop(self, exc=_sentinel): + """Pops the request context and unbinds it by doing that. This will + also trigger the execution of functions registered by the + :meth:`~flask.Flask.teardown_request` decorator. + + .. versionchanged:: 0.9 + Added the `exc` argument. + """ + app_ctx = self._implicit_app_ctx_stack.pop() + + try: + clear_request = False + if not self._implicit_app_ctx_stack: + self.preserved = False + self._preserved_exc = None + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_request(exc) + + # If this interpreter supports clearing the exception information + # we do that now. This will only go into effect on Python 2.x, + # on 3.x it disappears automatically at the end of the exception + # stack. + if hasattr(sys, 'exc_clear'): + sys.exc_clear() + + request_close = getattr(self.request, 'close', None) + if request_close is not None: + request_close() + clear_request = True + finally: + rv = _request_ctx_stack.pop() + + # get rid of circular dependencies at the end of the request + # so that we don't require the GC to be active. + if clear_request: + rv.request.environ['werkzeug.request'] = None + + # Get rid of the app as well if necessary. + if app_ctx is not None: + app_ctx.pop(exc) + + assert rv is self, 'Popped wrong request context. ' \ + '(%r instead of %r)' % (rv, self) + + def auto_pop(self, exc): + if self.request.environ.get('flask._preserve_context') or \ + (exc is not None and self.app.preserve_context_on_exception): + self.preserved = True + self._preserved_exc = exc + else: + self.pop(exc) + + def __enter__(self): + self.push() + return self + + def __exit__(self, exc_type, exc_value, tb): + # do not pop the request stack if we are in debug mode and an + # exception happened. This will allow the debugger to still + # access the request object in the interactive shell. Furthermore + # the context can be force kept alive for the test client. + # See flask.testing for how this works. + self.auto_pop(exc_value) + + if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None: + reraise(exc_type, exc_value, tb) + + def __repr__(self): + return '<%s \'%s\' [%s] of %s>' % ( + self.__class__.__name__, + self.request.url, + self.request.method, + self.app.name, + ) diff --git a/Lib/site-packages/flask/debughelpers.py b/Lib/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..e9765f2 --- /dev/null +++ b/Lib/site-packages/flask/debughelpers.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +""" + flask.debughelpers + ~~~~~~~~~~~~~~~~~~ + + Various helpers to make the development experience better. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +from warnings import warn + +from ._compat import implements_to_string, text_type +from .app import Flask +from .blueprints import Blueprint +from .globals import _request_ctx_stack + + +class UnexpectedUnicodeError(AssertionError, UnicodeError): + """Raised in places where we want some better error reporting for + unexpected unicode or binary data. + """ + + +@implements_to_string +class DebugFilesKeyError(KeyError, AssertionError): + """Raised from request.files during debugging. The idea is that it can + provide a better error message than just a generic KeyError/BadRequest. + """ + + def __init__(self, request, key): + form_matches = request.form.getlist(key) + buf = ['You tried to access the file "%s" in the request.files ' + 'dictionary but it does not exist. The mimetype for the request ' + 'is "%s" instead of "multipart/form-data" which means that no ' + 'file contents were transmitted. To fix this error you should ' + 'provide enctype="multipart/form-data" in your form.' % + (key, request.mimetype)] + if form_matches: + buf.append('\n\nThe browser instead transmitted some file names. ' + 'This was submitted: %s' % ', '.join('"%s"' % x + for x in form_matches)) + self.msg = ''.join(buf) + + def __str__(self): + return self.msg + + +class FormDataRoutingRedirect(AssertionError): + """This exception is raised by Flask in debug mode if it detects a + redirect caused by the routing system when the request method is not + GET, HEAD or OPTIONS. Reasoning: form data will be dropped. + """ + + def __init__(self, request): + exc = request.routing_exception + buf = ['A request was sent to this URL (%s) but a redirect was ' + 'issued automatically by the routing system to "%s".' + % (request.url, exc.new_url)] + + # In case just a slash was appended we can be extra helpful + if request.base_url + '/' == exc.new_url.split('?')[0]: + buf.append(' The URL was defined with a trailing slash so ' + 'Flask will automatically redirect to the URL ' + 'with the trailing slash if it was accessed ' + 'without one.') + + buf.append(' Make sure to directly send your %s-request to this URL ' + 'since we can\'t make browsers or HTTP clients redirect ' + 'with form data reliably or without user interaction.' % + request.method) + buf.append('\n\nNote: this exception is only raised in debug mode') + AssertionError.__init__(self, ''.join(buf).encode('utf-8')) + + +def attach_enctype_error_multidict(request): + """Since Flask 0.8 we're monkeypatching the files object in case a + request is detected that does not use multipart form data but the files + object is accessed. + """ + oldcls = request.files.__class__ + class newcls(oldcls): + def __getitem__(self, key): + try: + return oldcls.__getitem__(self, key) + except KeyError: + if key not in request.form: + raise + raise DebugFilesKeyError(request, key) + newcls.__name__ = oldcls.__name__ + newcls.__module__ = oldcls.__module__ + request.files.__class__ = newcls + + +def _dump_loader_info(loader): + yield 'class: %s.%s' % (type(loader).__module__, type(loader).__name__) + for key, value in sorted(loader.__dict__.items()): + if key.startswith('_'): + continue + if isinstance(value, (tuple, list)): + if not all(isinstance(x, (str, text_type)) for x in value): + continue + yield '%s:' % key + for item in value: + yield ' - %s' % item + continue + elif not isinstance(value, (str, text_type, int, float, bool)): + continue + yield '%s: %r' % (key, value) + + +def explain_template_loading_attempts(app, template, attempts): + """This should help developers understand what failed""" + info = ['Locating template "%s":' % template] + total_found = 0 + blueprint = None + reqctx = _request_ctx_stack.top + if reqctx is not None and reqctx.request.blueprint is not None: + blueprint = reqctx.request.blueprint + + for idx, (loader, srcobj, triple) in enumerate(attempts): + if isinstance(srcobj, Flask): + src_info = 'application "%s"' % srcobj.import_name + elif isinstance(srcobj, Blueprint): + src_info = 'blueprint "%s" (%s)' % (srcobj.name, + srcobj.import_name) + else: + src_info = repr(srcobj) + + info.append('% 5d: trying loader of %s' % ( + idx + 1, src_info)) + + for line in _dump_loader_info(loader): + info.append(' %s' % line) + + if triple is None: + detail = 'no match' + else: + detail = 'found (%r)' % (triple[1] or '') + total_found += 1 + info.append(' -> %s' % detail) + + seems_fishy = False + if total_found == 0: + info.append('Error: the template could not be found.') + seems_fishy = True + elif total_found > 1: + info.append('Warning: multiple loaders returned a match for the template.') + seems_fishy = True + + if blueprint is not None and seems_fishy: + info.append(' The template was looked up from an endpoint that ' + 'belongs to the blueprint "%s".' % blueprint) + info.append(' Maybe you did not place a template in the right folder?') + info.append(' See http://flask.pocoo.org/docs/blueprints/#templates') + + app.logger.info('\n'.join(info)) + + +def explain_ignored_app_run(): + if os.environ.get('WERKZEUG_RUN_MAIN') != 'true': + warn(Warning('Silently ignoring app.run() because the ' + 'application is run from the flask command line ' + 'executable. Consider putting app.run() behind an ' + 'if __name__ == "__main__" guard to silence this ' + 'warning.'), stacklevel=3) diff --git a/Lib/site-packages/flask/globals.py b/Lib/site-packages/flask/globals.py new file mode 100644 index 0000000..7d50a6f --- /dev/null +++ b/Lib/site-packages/flask/globals.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" + flask.globals + ~~~~~~~~~~~~~ + + Defines all the global objects that are proxies to the current + active context. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +from functools import partial +from werkzeug.local import LocalStack, LocalProxy + + +_request_ctx_err_msg = '''\ +Working outside of request context. + +This typically means that you attempted to use functionality that needed +an active HTTP request. Consult the documentation on testing for +information about how to avoid this problem.\ +''' +_app_ctx_err_msg = '''\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +to interface with the current application object in some way. To solve +this, set up an application context with app.app_context(). See the +documentation for more information.\ +''' + + +def _lookup_req_object(name): + top = _request_ctx_stack.top + if top is None: + raise RuntimeError(_request_ctx_err_msg) + return getattr(top, name) + + +def _lookup_app_object(name): + top = _app_ctx_stack.top + if top is None: + raise RuntimeError(_app_ctx_err_msg) + return getattr(top, name) + + +def _find_app(): + top = _app_ctx_stack.top + if top is None: + raise RuntimeError(_app_ctx_err_msg) + return top.app + + +# context locals +_request_ctx_stack = LocalStack() +_app_ctx_stack = LocalStack() +current_app = LocalProxy(_find_app) +request = LocalProxy(partial(_lookup_req_object, 'request')) +session = LocalProxy(partial(_lookup_req_object, 'session')) +g = LocalProxy(partial(_lookup_app_object, 'g')) diff --git a/Lib/site-packages/flask/helpers.py b/Lib/site-packages/flask/helpers.py new file mode 100644 index 0000000..df0b91f --- /dev/null +++ b/Lib/site-packages/flask/helpers.py @@ -0,0 +1,1044 @@ +# -*- coding: utf-8 -*- +""" + flask.helpers + ~~~~~~~~~~~~~ + + Implements various helpers. + + :copyright: © 2010 by the Pallets team. + :license: BSD, see LICENSE for more details. +""" + +import os +import socket +import sys +import pkgutil +import posixpath +import mimetypes +from time import time +from zlib import adler32 +from threading import RLock +import unicodedata +from werkzeug.routing import BuildError +from functools import update_wrapper + +from werkzeug.urls import url_quote +from werkzeug.datastructures import Headers, Range +from werkzeug.exceptions import BadRequest, NotFound, \ + RequestedRangeNotSatisfiable + +from werkzeug.wsgi import wrap_file +from jinja2 import FileSystemLoader + +from .signals import message_flashed +from .globals import session, _request_ctx_stack, _app_ctx_stack, \ + current_app, request +from ._compat import string_types, text_type, PY2 + +# sentinel +_missing = object() + + +# what separators does this operating system provide that are not a slash? +# this is used by the send_from_directory function to ensure that nobody is +# able to access files from outside the filesystem. +_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep] + if sep not in (None, '/')) + + +def get_env(): + """Get the environment the app is running in, indicated by the + :envvar:`FLASK_ENV` environment variable. The default is + ``'production'``. + """ + return os.environ.get('FLASK_ENV') or 'production' + + +def get_debug_flag(): + """Get whether debug mode should be enabled for the app, indicated + by the :envvar:`FLASK_DEBUG` environment variable. The default is + ``True`` if :func:`.get_env` returns ``'development'``, or ``False`` + otherwise. + """ + val = os.environ.get('FLASK_DEBUG') + + if not val: + return get_env() == 'development' + + return val.lower() not in ('0', 'false', 'no') + + +def get_load_dotenv(default=True): + """Get whether the user has disabled loading dotenv files by setting + :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load the + files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get('FLASK_SKIP_DOTENV') + + if not val: + return default + + return val.lower() in ('0', 'false', 'no') + + +def _endpoint_from_view_func(view_func): + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, 'expected view func if endpoint ' \ + 'is not provided.' + return view_func.__name__ + + +def stream_with_context(generator_or_function): + """Request contexts disappear when the response is started on the server. + This is done for efficiency reasons and to make it less likely to encounter + memory leaks with badly written WSGI middlewares. The downside is that if + you are using streamed responses, the generator cannot access request bound + information any more. + + This function however can help you keep the context around for longer:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + @stream_with_context + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(generate()) + + Alternatively it can also be used around a specific generator:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(stream_with_context(generate())) + + .. versionadded:: 0.9 + """ + try: + gen = iter(generator_or_function) + except TypeError: + def decorator(*args, **kwargs): + gen = generator_or_function(*args, **kwargs) + return stream_with_context(gen) + return update_wrapper(decorator, generator_or_function) + + def generator(): + ctx = _request_ctx_stack.top + if ctx is None: + raise RuntimeError('Attempted to stream with context but ' + 'there was no context in the first place to keep around.') + with ctx: + # Dummy sentinel. Has to be inside the context block or we're + # not actually keeping the context around. + yield None + + # The try/finally is here so that if someone passes a WSGI level + # iterator in we're still running the cleanup logic. Generators + # don't need that because they are closed on their destruction + # automatically. + try: + for item in gen: + yield item + finally: + if hasattr(gen, 'close'): + gen.close() + + # The trick is to start the generator. Then the code execution runs until + # the first dummy None is yielded at which point the context was already + # pushed. This item is discarded. Then when the iteration continues the + # real generator is executed. + wrapped_g = generator() + next(wrapped_g) + return wrapped_g + + +def make_response(*args): + """Sometimes it is necessary to set additional headers in a view. Because + views do not have to return response objects but can return a value that + is converted into a response object by Flask itself, it becomes tricky to + add headers to it. This function can be called instead of using a return + and you will get a response object which you can use to attach headers. + + If view looked like this and you want to add a new header:: + + def index(): + return render_template('index.html', foo=42) + + You can now do something like this:: + + def index(): + response = make_response(render_template('index.html', foo=42)) + response.headers['X-Parachutes'] = 'parachutes are cool' + return response + + This function accepts the very same arguments you can return from a + view function. This for example creates a response with a 404 error + code:: + + response = make_response(render_template('not_found.html'), 404) + + The other use case of this function is to force the return value of a + view function into a response which is helpful with view + decorators:: + + response = make_response(view_function()) + response.headers['X-Parachutes'] = 'parachutes are cool' + + Internally this function does the following things: + + - if no arguments are passed, it creates a new response argument + - if one argument is passed, :meth:`flask.Flask.make_response` + is invoked with it. + - if more than one argument is passed, the arguments are passed + to the :meth:`flask.Flask.make_response` function as tuple. + + .. versionadded:: 0.6 + """ + if not args: + return current_app.response_class() + if len(args) == 1: + args = args[0] + return current_app.make_response(args) + + +def url_for(endpoint, **values): + """Generates a URL to the given endpoint with the method provided. + + Variable arguments that are unknown to the target endpoint are appended + to the generated URL as query arguments. If the value of a query argument + is ``None``, the whole pair is skipped. In case blueprints are active + you can shortcut references to the same blueprint by prefixing the + local endpoint with a dot (``.``). + + This will reference the index function local to the current blueprint:: + + url_for('.index') + + For more information, head over to the :ref:`Quickstart `. + + To integrate applications, :class:`Flask` has a hook to intercept URL build + errors through :attr:`Flask.url_build_error_handlers`. The `url_for` + function results in a :exc:`~werkzeug.routing.BuildError` when the current + app does not have a URL for the given endpoint and values. When it does, the + :data:`~flask.current_app` calls its :attr:`~Flask.url_build_error_handlers` if + it is not ``None``, which can return a string to use as the result of + `url_for` (instead of `url_for`'s default to raise the + :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. + An example:: + + def external_url_handler(error, endpoint, values): + "Looks up an external URL when `url_for` cannot build a URL." + # This is an example of hooking the build_error_handler. + # Here, lookup_url is some utility function you've built + # which looks up the endpoint in some external URL registry. + url = lookup_url(endpoint, **values) + if url is None: + # External lookup did not have a URL. + # Re-raise the BuildError, in context of original traceback. + exc_type, exc_value, tb = sys.exc_info() + if exc_value is error: + raise exc_type, exc_value, tb + else: + raise error + # url_for will use this result, instead of raising BuildError. + return url + + app.url_build_error_handlers.append(external_url_handler) + + Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and + `endpoint` and `values` are the arguments passed into `url_for`. Note + that this is for building URLs outside the current application, and not for + handling 404 NotFound errors. + + .. versionadded:: 0.10 + The `_scheme` parameter was added. + + .. versionadded:: 0.9 + The `_anchor` and `_method` parameters were added. + + .. versionadded:: 0.9 + Calls :meth:`Flask.handle_build_error` on + :exc:`~werkzeug.routing.BuildError`. + + :param endpoint: the endpoint of the URL (name of the function) + :param values: the variable arguments of the URL rule + :param _external: if set to ``True``, an absolute URL is generated. Server + address can be changed via ``SERVER_NAME`` configuration variable which + defaults to `localhost`. + :param _scheme: a string specifying the desired URL scheme. The `_external` + parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default + behavior uses the same scheme as the current request, or + ``PREFERRED_URL_SCHEME`` from the :ref:`app configuration ` if no + request context is available. As of Werkzeug 0.10, this also can be set + to an empty string to build protocol-relative URLs. + :param _anchor: if provided this is added as anchor to the URL. + :param _method: if provided this explicitly specifies an HTTP method. + """ + appctx = _app_ctx_stack.top + reqctx = _request_ctx_stack.top + + if appctx is None: + raise RuntimeError( + 'Attempted to generate a URL without the application context being' + ' pushed. This has to be executed when application context is' + ' available.' + ) + + # If request specific information is available we have some extra + # features that support "relative" URLs. + if reqctx is not None: + url_adapter = reqctx.url_adapter + blueprint_name = request.blueprint + + if endpoint[:1] == '.': + if blueprint_name is not None: + endpoint = blueprint_name + endpoint + else: + endpoint = endpoint[1:] + + external = values.pop('_external', False) + + # Otherwise go with the url adapter from the appctx and make + # the URLs external by default. + else: + url_adapter = appctx.url_adapter + + if url_adapter is None: + raise RuntimeError( + 'Application was not able to create a URL adapter for request' + ' independent URL generation. You might be able to fix this by' + ' setting the SERVER_NAME config variable.' + ) + + external = values.pop('_external', True) + + anchor = values.pop('_anchor', None) + method = values.pop('_method', None) + scheme = values.pop('_scheme', None) + appctx.app.inject_url_defaults(endpoint, values) + + # This is not the best way to deal with this but currently the + # underlying Werkzeug router does not support overriding the scheme on + # a per build call basis. + old_scheme = None + if scheme is not None: + if not external: + raise ValueError('When specifying _scheme, _external must be True') + old_scheme = url_adapter.url_scheme + url_adapter.url_scheme = scheme + + try: + try: + rv = url_adapter.build(endpoint, values, method=method, + force_external=external) + finally: + if old_scheme is not None: + url_adapter.url_scheme = old_scheme + except BuildError as error: + # We need to inject the values again so that the app callback can + # deal with that sort of stuff. + values['_external'] = external + values['_anchor'] = anchor + values['_method'] = method + values['_scheme'] = scheme + return appctx.app.handle_url_build_error(error, endpoint, values) + + if anchor is not None: + rv += '#' + url_quote(anchor) + return rv + + +def get_template_attribute(template_name, attribute): + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + return getattr(current_app.jinja_env.get_template(template_name).module, + attribute) + + +def flash(message, category='message'): + """Flashes a message to the next request. In order to remove the + flashed message from the session and to display it to the user, + the template has to call :func:`get_flashed_messages`. + + .. versionchanged:: 0.3 + `category` parameter added. + + :param message: the message to be flashed. + :param category: the category for the message. The following values + are recommended: ``'message'`` for any kind of message, + ``'error'`` for errors, ``'info'`` for information + messages and ``'warning'`` for warnings. However any + kind of string can be used as category. + """ + # Original implementation: + # + # session.setdefault('_flashes', []).append((category, message)) + # + # This assumed that changes made to mutable structures in the session are + # always in sync with the session object, which is not true for session + # implementations that use external storage for keeping their keys/values. + flashes = session.get('_flashes', []) + flashes.append((category, message)) + session['_flashes'] = flashes + message_flashed.send(current_app._get_current_object(), + message=message, category=category) + + +def get_flashed_messages(with_categories=False, category_filter=[]): + """Pulls all flashed messages from the session and returns them. + Further calls in the same request to the function will return + the same messages. By default just the messages are returned, + but when `with_categories` is set to ``True``, the return value will + be a list of tuples in the form ``(category, message)`` instead. + + Filter the flashed messages to one or more categories by providing those + categories in `category_filter`. This allows rendering categories in + separate html blocks. The `with_categories` and `category_filter` + arguments are distinct: + + * `with_categories` controls whether categories are returned with message + text (``True`` gives a tuple, where ``False`` gives just the message text). + * `category_filter` filters the messages down to only those matching the + provided categories. + + See :ref:`message-flashing-pattern` for examples. + + .. versionchanged:: 0.3 + `with_categories` parameter added. + + .. versionchanged:: 0.9 + `category_filter` parameter added. + + :param with_categories: set to ``True`` to also receive categories. + :param category_filter: whitelist of categories to limit return values + """ + flashes = _request_ctx_stack.top.flashes + if flashes is None: + _request_ctx_stack.top.flashes = flashes = session.pop('_flashes') \ + if '_flashes' in session else [] + if category_filter: + flashes = list(filter(lambda f: f[0] in category_filter, flashes)) + if not with_categories: + return [x[1] for x in flashes] + return flashes + + +def send_file(filename_or_fp, mimetype=None, as_attachment=False, + attachment_filename=None, add_etags=True, + cache_timeout=None, conditional=False, last_modified=None): + """Sends the contents of a file to the client. This will use the + most efficient method available and configured. By default it will + try to use the WSGI server's file_wrapper support. Alternatively + you can set the application's :attr:`~Flask.use_x_sendfile` attribute + to ``True`` to directly emit an ``X-Sendfile`` header. This however + requires support of the underlying webserver for ``X-Sendfile``. + + By default it will try to guess the mimetype for you, but you can + also explicitly provide one. For extra security you probably want + to send certain files as attachment (HTML for instance). The mimetype + guessing requires a `filename` or an `attachment_filename` to be + provided. + + ETags will also be attached automatically if a `filename` is provided. You + can turn this off by setting `add_etags=False`. + + If `conditional=True` and `filename` is provided, this method will try to + upgrade the response stream to support range requests. This will allow + the request to be answered with partial content response. + + Please never pass filenames to this function from user sources; + you should use :func:`send_from_directory` instead. + + .. versionadded:: 0.2 + + .. versionadded:: 0.5 + The `add_etags`, `cache_timeout` and `conditional` parameters were + added. The default behavior is now to attach etags. + + .. versionchanged:: 0.7 + mimetype guessing and etag support for file objects was + deprecated because it was unreliable. Pass a filename if you are + able to, otherwise attach an etag yourself. This functionality + will be removed in Flask 1.0 + + .. versionchanged:: 0.9 + cache_timeout pulls its default from application config, when None. + + .. versionchanged:: 0.12 + The filename is no longer automatically inferred from file objects. If + you want to use automatic mimetype and etag support, pass a filepath via + `filename_or_fp` or `attachment_filename`. + + .. versionchanged:: 0.12 + The `attachment_filename` is preferred over `filename` for MIME-type + detection. + + .. versionchanged:: 1.0 + UTF-8 filenames, as specified in `RFC 2231`_, are supported. + + .. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4 + + :param filename_or_fp: the filename of the file to send. + This is relative to the :attr:`~Flask.root_path` + if a relative path is specified. + Alternatively a file object might be provided in + which case ``X-Sendfile`` might not work and fall + back to the traditional method. Make sure that the + file pointer is positioned at the start of data to + send before calling :func:`send_file`. + :param mimetype: the mimetype of the file if provided. If a file path is + given, auto detection happens as fallback, otherwise an + error will be raised. + :param as_attachment: set to ``True`` if you want to send this file with + a ``Content-Disposition: attachment`` header. + :param attachment_filename: the filename for the attachment if it + differs from the file's filename. + :param add_etags: set to ``False`` to disable attaching of etags. + :param conditional: set to ``True`` to enable conditional responses. + + :param cache_timeout: the timeout in seconds for the headers. When ``None`` + (default), this value is set by + :meth:`~Flask.get_send_file_max_age` of + :data:`~flask.current_app`. + :param last_modified: set the ``Last-Modified`` header to this value, + a :class:`~datetime.datetime` or timestamp. + If a file was passed, this overrides its mtime. + """ + mtime = None + fsize = None + if isinstance(filename_or_fp, string_types): + filename = filename_or_fp + if not os.path.isabs(filename): + filename = os.path.join(current_app.root_path, filename) + file = None + if attachment_filename is None: + attachment_filename = os.path.basename(filename) + else: + file = filename_or_fp + filename = None + + if mimetype is None: + if attachment_filename is not None: + mimetype = mimetypes.guess_type(attachment_filename)[0] \ + or 'application/octet-stream' + + if mimetype is None: + raise ValueError( + 'Unable to infer MIME-type because no filename is available. ' + 'Please set either `attachment_filename`, pass a filepath to ' + '`filename_or_fp` or set your own MIME-type via `mimetype`.' + ) + + headers = Headers() + if as_attachment: + if attachment_filename is None: + raise TypeError('filename unavailable, required for ' + 'sending as attachment') + + try: + attachment_filename = attachment_filename.encode('latin-1') + except UnicodeEncodeError: + filenames = { + 'filename': unicodedata.normalize( + 'NFKD', attachment_filename).encode('latin-1', 'ignore'), + 'filename*': "UTF-8''%s" % url_quote(attachment_filename), + } + else: + filenames = {'filename': attachment_filename} + + headers.add('Content-Disposition', 'attachment', **filenames) + + if current_app.use_x_sendfile and filename: + if file is not None: + file.close() + headers['X-Sendfile'] = filename + fsize = os.path.getsize(filename) + headers['Content-Length'] = fsize + data = None + else: + if file is None: + file = open(filename, 'rb') + mtime = os.path.getmtime(filename) + fsize = os.path.getsize(filename) + headers['Content-Length'] = fsize + data = wrap_file(request.environ, file) + + rv = current_app.response_class(data, mimetype=mimetype, headers=headers, + direct_passthrough=True) + + if last_modified is not None: + rv.last_modified = last_modified + elif mtime is not None: + rv.last_modified = mtime + + rv.cache_control.public = True + if cache_timeout is None: + cache_timeout = current_app.get_send_file_max_age(filename) + if cache_timeout is not None: + rv.cache_control.max_age = cache_timeout + rv.expires = int(time() + cache_timeout) + + if add_etags and filename is not None: + from warnings import warn + + try: + rv.set_etag('%s-%s-%s' % ( + os.path.getmtime(filename), + os.path.getsize(filename), + adler32( + filename.encode('utf-8') if isinstance(filename, text_type) + else filename + ) & 0xffffffff + )) + except OSError: + warn('Access %s failed, maybe it does not exist, so ignore etags in ' + 'headers' % filename, stacklevel=2) + + if conditional: + try: + rv = rv.make_conditional(request, accept_ranges=True, + complete_length=fsize) + except RequestedRangeNotSatisfiable: + if file is not None: + file.close() + raise + # make sure we don't send x-sendfile for servers that + # ignore the 304 status code for x-sendfile. + if rv.status_code == 304: + rv.headers.pop('x-sendfile', None) + return rv + + +def safe_join(directory, *pathnames): + """Safely join `directory` and zero or more untrusted `pathnames` + components. + + Example usage:: + + @app.route('/wiki/') + def wiki_page(filename): + filename = safe_join(app.config['WIKI_FOLDER'], filename) + with open(filename, 'rb') as fd: + content = fd.read() # Read and process the file content... + + :param directory: the trusted base directory. + :param pathnames: the untrusted pathnames relative to that directory. + :raises: :class:`~werkzeug.exceptions.NotFound` if one or more passed + paths fall out of its boundaries. + """ + + parts = [directory] + + for filename in pathnames: + if filename != '': + filename = posixpath.normpath(filename) + + if ( + any(sep in filename for sep in _os_alt_seps) + or os.path.isabs(filename) + or filename == '..' + or filename.startswith('../') + ): + raise NotFound() + + parts.append(filename) + + return posixpath.join(*parts) + + +def send_from_directory(directory, filename, **options): + """Send a file from a given directory with :func:`send_file`. This + is a secure way to quickly expose static files from an upload folder + or something similar. + + Example usage:: + + @app.route('/uploads/') + def download_file(filename): + return send_from_directory(app.config['UPLOAD_FOLDER'], + filename, as_attachment=True) + + .. admonition:: Sending files and Performance + + It is strongly recommended to activate either ``X-Sendfile`` support in + your webserver or (if no authentication happens) to tell the webserver + to serve files for the given path on its own without calling into the + web application for improved performance. + + .. versionadded:: 0.5 + + :param directory: the directory where all the files are stored. + :param filename: the filename relative to that directory to + download. + :param options: optional keyword arguments that are directly + forwarded to :func:`send_file`. + """ + filename = safe_join(directory, filename) + if not os.path.isabs(filename): + filename = os.path.join(current_app.root_path, filename) + try: + if not os.path.isfile(filename): + raise NotFound() + except (TypeError, ValueError): + raise BadRequest() + options.setdefault('conditional', True) + return send_file(filename, **options) + + +def get_root_path(import_name): + """Returns the path to a package or cwd if that cannot be found. This + returns the path of a package or the folder that contains a module. + + Not to be confused with the package path returned by :func:`find_package`. + """ + # Module already imported and has a file attribute. Use that first. + mod = sys.modules.get(import_name) + if mod is not None and hasattr(mod, '__file__'): + return os.path.dirname(os.path.abspath(mod.__file__)) + + # Next attempt: check the loader. + loader = pkgutil.get_loader(import_name) + + # Loader does not exist or we're referring to an unloaded main module + # or a main module without path (interactive sessions), go with the + # current working directory. + if loader is None or import_name == '__main__': + return os.getcwd() + + # For .egg, zipimporter does not have get_filename until Python 2.7. + # Some other loaders might exhibit the same behavior. + if hasattr(loader, 'get_filename'): + filepath = loader.get_filename(import_name) + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, '__file__', None) + + # If we don't have a filepath it might be because we are a + # namespace package. In this case we pick the root path from the + # first module that is contained in our package. + if filepath is None: + raise RuntimeError('No root path can be found for the provided ' + 'module "%s". This can happen because the ' + 'module came from an import hook that does ' + 'not provide file name information or because ' + 'it\'s a namespace package. In this case ' + 'the root path needs to be explicitly ' + 'provided.' % import_name) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) + + +def _matching_loader_thinks_module_is_package(loader, mod_name): + """Given the loader that loaded a module and the module this function + attempts to figure out if the given module is actually a package. + """ + # If the loader can tell us if something is a package, we can + # directly ask the loader. + if hasattr(loader, 'is_package'): + return loader.is_package(mod_name) + # importlib's namespace loaders do not have this functionality but + # all the modules it loads are packages, so we can take advantage of + # this information. + elif (loader.__class__.__module__ == '_frozen_importlib' and + loader.__class__.__name__ == 'NamespaceLoader'): + return True + # Otherwise we need to fail with an error that explains what went + # wrong. + raise AttributeError( + ('%s.is_package() method is missing but is required by Flask of ' + 'PEP 302 import hooks. If you do not use import hooks and ' + 'you encounter this error please file a bug against Flask.') % + loader.__class__.__name__) + + +def find_package(import_name): + """Finds a package and returns the prefix (or None if the package is + not installed) as well as the folder that contains the package or + module as a tuple. The package path returned is the module that would + have to be added to the pythonpath in order to make it possible to + import the module. The prefix is the path below which a UNIX like + folder structure exists (lib, share etc.). + """ + root_mod_name = import_name.split('.')[0] + loader = pkgutil.get_loader(root_mod_name) + if loader is None or import_name == '__main__': + # import name is not found, or interactive/main module + package_path = os.getcwd() + else: + # For .egg, zipimporter does not have get_filename until Python 2.7. + if hasattr(loader, 'get_filename'): + filename = loader.get_filename(root_mod_name) + elif hasattr(loader, 'archive'): + # zipimporter's loader.archive points to the .egg or .zip + # archive filename is dropped in call to dirname below. + filename = loader.archive + else: + # At least one loader is missing both get_filename and archive: + # Google App Engine's HardenedModulesHook + # + # Fall back to imports. + __import__(import_name) + filename = sys.modules[import_name].__file__ + package_path = os.path.abspath(os.path.dirname(filename)) + + # In case the root module is a package we need to chop of the + # rightmost part. This needs to go through a helper function + # because of python 3.3 namespace packages. + if _matching_loader_thinks_module_is_package( + loader, root_mod_name): + package_path = os.path.dirname(package_path) + + site_parent, site_folder = os.path.split(package_path) + py_prefix = os.path.abspath(sys.prefix) + if package_path.startswith(py_prefix): + return py_prefix, package_path + elif site_folder.lower() == 'site-packages': + parent, folder = os.path.split(site_parent) + # Windows like installations + if folder.lower() == 'lib': + base_dir = parent + # UNIX like installations + elif os.path.basename(parent).lower() == 'lib': + base_dir = os.path.dirname(parent) + else: + base_dir = site_parent + return base_dir, package_path + return None, package_path + + +class locked_cached_property(object): + """A decorator that converts a function into a lazy property. The + function wrapped is called the first time to retrieve the result + and then that calculated result is used the next time you access + the value. Works like the one in Werkzeug but has a lock for + thread safety. + """ + + def __init__(self, func, name=None, doc=None): + self.__name__ = name or func.__name__ + self.__module__ = func.__module__ + self.__doc__ = doc or func.__doc__ + self.func = func + self.lock = RLock() + + def __get__(self, obj, type=None): + if obj is None: + return self + with self.lock: + value = obj.__dict__.get(self.__name__, _missing) + if value is _missing: + value = self.func(obj) + obj.__dict__[self.__name__] = value + return value + + +class _PackageBoundObject(object): + #: The name of the package or module that this app belongs to. Do not + #: change this once it is set by the constructor. + import_name = None + + #: Location of the template files to be added to the template lookup. + #: ``None`` if templates should not be added. + template_folder = None + + #: Absolute path to the package on the filesystem. Used to look up + #: resources contained in the package. + root_path = None + + def __init__(self, import_name, template_folder=None, root_path=None): + self.import_name = import_name + self.template_folder = template_folder + + if root_path is None: + root_path = get_root_path(self.import_name) + + self.root_path = root_path + self._static_folder = None + self._static_url_path = None + + def _get_static_folder(self): + if self._static_folder is not None: + return os.path.join(self.root_path, self._static_folder) + + def _set_static_folder(self, value): + self._static_folder = value + + static_folder = property( + _get_static_folder, _set_static_folder, + doc='The absolute path to the configured static folder.' + ) + del _get_static_folder, _set_static_folder + + def _get_static_url_path(self): + if self._static_url_path is not None: + return self._static_url_path + + if self.static_folder is not None: + return '/' + os.path.basename(self.static_folder) + + def _set_static_url_path(self, value): + self._static_url_path = value + + static_url_path = property( + _get_static_url_path, _set_static_url_path, + doc='The URL prefix that the static route will be registered for.' + ) + del _get_static_url_path, _set_static_url_path + + @property + def has_static_folder(self): + """This is ``True`` if the package bound object's container has a + folder for static files. + + .. versionadded:: 0.5 + """ + return self.static_folder is not None + + @locked_cached_property + def jinja_loader(self): + """The Jinja loader for this package bound object. + + .. versionadded:: 0.5 + """ + if self.template_folder is not None: + return FileSystemLoader(os.path.join(self.root_path, + self.template_folder)) + + def get_send_file_max_age(self, filename): + """Provides default cache_timeout for the :func:`send_file` functions. + + By default, this function returns ``SEND_FILE_MAX_AGE_DEFAULT`` from + the configuration of :data:`~flask.current_app`. + + Static file functions such as :func:`send_from_directory` use this + function, and :func:`send_file` calls this function on + :data:`~flask.current_app` when the given cache_timeout is ``None``. If a + cache_timeout is given in :func:`send_file`, that timeout is used; + otherwise, this method is called. + + This allows subclasses to change the behavior when sending files based + on the filename. For example, to set the cache timeout for .js files + to 60 seconds:: + + class MyFlask(flask.Flask): + def get_send_file_max_age(self, name): + if name.lower().endswith('.js'): + return 60 + return flask.Flask.get_send_file_max_age(self, name) + + .. versionadded:: 0.9 + """ + return total_seconds(current_app.send_file_max_age_default) + + def send_static_file(self, filename): + """Function used internally to send static files from the static + folder to the browser. + + .. versionadded:: 0.5 + """ + if not self.has_static_folder: + raise RuntimeError('No static folder for this object') + # Ensure get_send_file_max_age is called in all cases. + # Here, we ensure get_send_file_max_age is called for Blueprints. + cache_timeout = self.get_send_file_max_age(filename) + return send_from_directory(self.static_folder, filename, + cache_timeout=cache_timeout) + + def open_resource(self, resource, mode='rb'): + """Opens a resource from the application's resource folder. To see + how this works, consider the following folder structure:: + + /myapplication.py + /schema.sql + /static + /style.css + /templates + /layout.html + /index.html + + If you want to open the :file:`schema.sql` file you would do the + following:: + + with app.open_resource('schema.sql') as f: + contents = f.read() + do_something_with(contents) + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + if mode not in ('r', 'rb'): + raise ValueError('Resources can only be opened for reading') + return open(os.path.join(self.root_path, resource), mode) + + +def total_seconds(td): + """Returns the total seconds from a timedelta object. + + :param timedelta td: the timedelta to be converted in seconds + + :returns: number of seconds + :rtype: int + """ + return td.days * 60 * 60 * 24 + td.seconds + + +def is_ip(value): + """Determine if the given string is an IP address. + + Python 2 on Windows doesn't provide ``inet_pton``, so this only + checks IPv4 addresses in that environment. + + :param value: value to check + :type value: str + + :return: True if string is an IP address + :rtype: bool + """ + if PY2 and os.name == 'nt': + try: + socket.inet_aton(value) + return True + except socket.error: + return False + + for family in (socket.AF_INET, socket.AF_INET6): + try: + socket.inet_pton(family, value) + except socket.error: + pass + else: + return True + + return False diff --git a/Lib/site-packages/flask/json/__init__.py b/Lib/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..fbe6b92 --- /dev/null +++ b/Lib/site-packages/flask/json/__init__.py @@ -0,0 +1,327 @@ +# -*- coding: utf-8 -*- +""" +flask.json +~~~~~~~~~~ + +:copyright: © 2010 by the Pallets team. +:license: BSD, see LICENSE for more details. +""" +import codecs +import io +import uuid +from datetime import date, datetime +from flask.globals import current_app, request +from flask._compat import text_type, PY2 + +from werkzeug.http import http_date +from jinja2 import Markup + +# Use the same json implementation as itsdangerous on which we +# depend anyways. +from itsdangerous import json as _json + + +# Figure out if simplejson escapes slashes. This behavior was changed +# from one version to another without reason. +_slash_escape = '\\/' not in _json.dumps('/') + + +__all__ = ['dump', 'dumps', 'load', 'loads', 'htmlsafe_dump', + 'htmlsafe_dumps', 'JSONDecoder', 'JSONEncoder', + 'jsonify'] + + +def _wrap_reader_for_text(fp, encoding): + if isinstance(fp.read(0), bytes): + fp = io.TextIOWrapper(io.BufferedReader(fp), encoding) + return fp + + +def _wrap_writer_for_text(fp, encoding): + try: + fp.write('') + except TypeError: + fp = io.TextIOWrapper(fp, encoding) + return fp + + +class JSONEncoder(_json.JSONEncoder): + """The default Flask JSON encoder. This one extends the default simplejson + encoder by also supporting ``datetime`` objects, ``UUID`` as well as + ``Markup`` objects which are serialized as RFC 822 datetime strings (same + as the HTTP date format). In order to support more data types override the + :meth:`default` method. + """ + + def default(self, o): + """Implement this method in a subclass such that it returns a + serializable object for ``o``, or calls the base implementation (to + raise a :exc:`TypeError`). + + For example, to support arbitrary iterators, you could implement + default like this:: + + def default(self, o): + try: + iterable = iter(o) + except TypeError: + pass + else: + return list(iterable) + return JSONEncoder.default(self, o) + """ + if isinstance(o, datetime): + return http_date(o.utctimetuple()) + if isinstance(o, date): + return http_date(o.timetuple()) + if isinstance(o, uuid.UUID): + return str(o) + if hasattr(o, '__html__'): + return text_type(o.__html__()) + return _json.JSONEncoder.default(self, o) + + +class JSONDecoder(_json.JSONDecoder): + """The default JSON decoder. This one does not change the behavior from + the default simplejson decoder. Consult the :mod:`json` documentation + for more information. This decoder is not only used for the load + functions of this module but also :attr:`~flask.Request`. + """ + + +def _dump_arg_defaults(kwargs): + """Inject default arguments for dump functions.""" + if current_app: + bp = current_app.blueprints.get(request.blueprint) if request else None + kwargs.setdefault( + 'cls', + bp.json_encoder if bp and bp.json_encoder + else current_app.json_encoder + ) + + if not current_app.config['JSON_AS_ASCII']: + kwargs.setdefault('ensure_ascii', False) + + kwargs.setdefault('sort_keys', current_app.config['JSON_SORT_KEYS']) + else: + kwargs.setdefault('sort_keys', True) + kwargs.setdefault('cls', JSONEncoder) + + +def _load_arg_defaults(kwargs): + """Inject default arguments for load functions.""" + if current_app: + bp = current_app.blueprints.get(request.blueprint) if request else None + kwargs.setdefault( + 'cls', + bp.json_decoder if bp and bp.json_decoder + else current_app.json_decoder + ) + else: + kwargs.setdefault('cls', JSONDecoder) + + +def detect_encoding(data): + """Detect which UTF codec was used to encode the given bytes. + + The latest JSON standard (:rfc:`8259`) suggests that only UTF-8 is + accepted. Older documents allowed 8, 16, or 32. 16 and 32 can be big + or little endian. Some editors or libraries may prepend a BOM. + + :param data: Bytes in unknown UTF encoding. + :return: UTF encoding name + """ + head = data[:4] + + if head[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' + + if b'\x00' not in head: + return 'utf-8' + + if head in (codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE): + return 'utf-32' + + if head[:2] in (codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE): + return 'utf-16' + + if len(head) == 4: + if head[:3] == b'\x00\x00\x00': + return 'utf-32-be' + + if head[::2] == b'\x00\x00': + return 'utf-16-be' + + if head[1:] == b'\x00\x00\x00': + return 'utf-32-le' + + if head[1::2] == b'\x00\x00': + return 'utf-16-le' + + if len(head) == 2: + return 'utf-16-be' if head.startswith(b'\x00') else 'utf-16-le' + + return 'utf-8' + + +def dumps(obj, **kwargs): + """Serialize ``obj`` to a JSON formatted ``str`` by using the application's + configured encoder (:attr:`~flask.Flask.json_encoder`) if there is an + application on the stack. + + This function can return ``unicode`` strings or ascii-only bytestrings by + default which coerce into unicode strings automatically. That behavior by + default is controlled by the ``JSON_AS_ASCII`` configuration variable + and can be overridden by the simplejson ``ensure_ascii`` parameter. + """ + _dump_arg_defaults(kwargs) + encoding = kwargs.pop('encoding', None) + rv = _json.dumps(obj, **kwargs) + if encoding is not None and isinstance(rv, text_type): + rv = rv.encode(encoding) + return rv + + +def dump(obj, fp, **kwargs): + """Like :func:`dumps` but writes into a file object.""" + _dump_arg_defaults(kwargs) + encoding = kwargs.pop('encoding', None) + if encoding is not None: + fp = _wrap_writer_for_text(fp, encoding) + _json.dump(obj, fp, **kwargs) + + +def loads(s, **kwargs): + """Unserialize a JSON object from a string ``s`` by using the application's + configured decoder (:attr:`~flask.Flask.json_decoder`) if there is an + application on the stack. + """ + _load_arg_defaults(kwargs) + if isinstance(s, bytes): + encoding = kwargs.pop('encoding', None) + if encoding is None: + encoding = detect_encoding(s) + s = s.decode(encoding) + return _json.loads(s, **kwargs) + + +def load(fp, **kwargs): + """Like :func:`loads` but reads from a file object. + """ + _load_arg_defaults(kwargs) + if not PY2: + fp = _wrap_reader_for_text(fp, kwargs.pop('encoding', None) or 'utf-8') + return _json.load(fp, **kwargs) + + +def htmlsafe_dumps(obj, **kwargs): + """Works exactly like :func:`dumps` but is safe for use in `` +
+''' + +__all__ = ["RecaptchaWidget"] + + +class RecaptchaWidget(object): + + def recaptcha_html(self, public_key): + html = current_app.config.get('RECAPTCHA_HTML') + if html: + return Markup(html) + params = current_app.config.get('RECAPTCHA_PARAMETERS') + script = RECAPTCHA_SCRIPT + if params: + script += u'?' + url_encode(params) + + attrs = current_app.config.get('RECAPTCHA_DATA_ATTRS', {}) + attrs['sitekey'] = public_key + snippet = u' '.join([u'data-%s="%s"' % (k, attrs[k]) for k in attrs]) + return Markup(RECAPTCHA_TEMPLATE % (script, snippet)) + + def __call__(self, field, error=None, **kwargs): + """Returns the recaptcha input HTML.""" + + try: + public_key = current_app.config['RECAPTCHA_PUBLIC_KEY'] + except KeyError: + raise RuntimeError("RECAPTCHA_PUBLIC_KEY config not set") + + return self.recaptcha_html(public_key) diff --git a/Lib/site-packages/itsdangerous-0.24.dist-info/INSTALLER b/Lib/site-packages/itsdangerous-0.24.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Lib/site-packages/itsdangerous-0.24.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Lib/site-packages/itsdangerous-0.24.dist-info/METADATA b/Lib/site-packages/itsdangerous-0.24.dist-info/METADATA new file mode 100644 index 0000000..d5d5a4b --- /dev/null +++ b/Lib/site-packages/itsdangerous-0.24.dist-info/METADATA @@ -0,0 +1,16 @@ +Metadata-Version: 2.1 +Name: itsdangerous +Version: 0.24 +Summary: Various helpers to pass trusted data to untrusted environments and back. +Home-page: http://github.com/mitsuhiko/itsdangerous +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +License: UNKNOWN +Platform: UNKNOWN +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 + +UNKNOWN + + diff --git a/Lib/site-packages/itsdangerous-0.24.dist-info/RECORD b/Lib/site-packages/itsdangerous-0.24.dist-info/RECORD new file mode 100644 index 0000000..f4bbf3b --- /dev/null +++ b/Lib/site-packages/itsdangerous-0.24.dist-info/RECORD @@ -0,0 +1,7 @@ +itsdangerous.py,sha256=l7u6oqIepEllYDR7hRmoE7z47Ry6vtFCF6EAbJt-ilI,31840 +itsdangerous-0.24.dist-info/METADATA,sha256=tJAkye-qlTNrpCXDxr7qS7b3nIfngUCledu1wTRsfrQ,442 +itsdangerous-0.24.dist-info/RECORD,, +itsdangerous-0.24.dist-info/WHEEL,sha256=IHnEIVcGZmRy_cnQluwuoqp98bayJ8Ap2I77tUv6qjc,98 +itsdangerous-0.24.dist-info/top_level.txt,sha256=gKN1OKLk81i7fbWWildJA88EQ9NhnGMSvZqhfz9ICjk,13 +itsdangerous-0.24.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +__pycache__/itsdangerous.cpython-37.pyc,, diff --git a/Lib/site-packages/itsdangerous-0.24.dist-info/WHEEL b/Lib/site-packages/itsdangerous-0.24.dist-info/WHEEL new file mode 100644 index 0000000..d7e7a45 --- /dev/null +++ b/Lib/site-packages/itsdangerous-0.24.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.1) +Root-Is-Purelib: true +Tag: cp37-none-any + diff --git a/Lib/site-packages/itsdangerous-0.24.dist-info/top_level.txt b/Lib/site-packages/itsdangerous-0.24.dist-info/top_level.txt new file mode 100644 index 0000000..e163955 --- /dev/null +++ b/Lib/site-packages/itsdangerous-0.24.dist-info/top_level.txt @@ -0,0 +1 @@ +itsdangerous diff --git a/Lib/site-packages/itsdangerous.py b/Lib/site-packages/itsdangerous.py new file mode 100644 index 0000000..228d101 --- /dev/null +++ b/Lib/site-packages/itsdangerous.py @@ -0,0 +1,872 @@ +# -*- coding: utf-8 -*- +""" + itsdangerous + ~~~~~~~~~~~~ + + A module that implements various functions to deal with untrusted + sources. Mainly useful for web applications. + + :copyright: (c) 2014 by Armin Ronacher and the Django Software Foundation. + :license: BSD, see LICENSE for more details. +""" + +import sys +import hmac +import zlib +import time +import base64 +import hashlib +import operator +from datetime import datetime + + +PY2 = sys.version_info[0] == 2 +if PY2: + from itertools import izip + text_type = unicode + int_to_byte = chr + number_types = (int, long, float) +else: + from functools import reduce + izip = zip + text_type = str + int_to_byte = operator.methodcaller('to_bytes', 1, 'big') + number_types = (int, float) + + +try: + import simplejson as json +except ImportError: + import json + + +class _CompactJSON(object): + """Wrapper around simplejson that strips whitespace. + """ + + def loads(self, payload): + return json.loads(payload) + + def dumps(self, obj): + return json.dumps(obj, separators=(',', ':')) + + +compact_json = _CompactJSON() + + +# 2011/01/01 in UTC +EPOCH = 1293840000 + + +def want_bytes(s, encoding='utf-8', errors='strict'): + if isinstance(s, text_type): + s = s.encode(encoding, errors) + return s + + +def is_text_serializer(serializer): + """Checks wheather a serializer generates text or binary.""" + return isinstance(serializer.dumps({}), text_type) + + +# Starting with 3.3 the standard library has a c-implementation for +# constant time string compares. +_builtin_constant_time_compare = getattr(hmac, 'compare_digest', None) + + +def constant_time_compare(val1, val2): + """Returns True if the two strings are equal, False otherwise. + + The time taken is independent of the number of characters that match. Do + not use this function for anything else than comparision with known + length targets. + + This is should be implemented in C in order to get it completely right. + """ + if _builtin_constant_time_compare is not None: + return _builtin_constant_time_compare(val1, val2) + len_eq = len(val1) == len(val2) + if len_eq: + result = 0 + left = val1 + else: + result = 1 + left = val2 + for x, y in izip(bytearray(left), bytearray(val2)): + result |= x ^ y + return result == 0 + + +class BadData(Exception): + """Raised if bad data of any sort was encountered. This is the + base for all exceptions that itsdangerous is currently using. + + .. versionadded:: 0.15 + """ + message = None + + def __init__(self, message): + Exception.__init__(self, message) + self.message = message + + def __str__(self): + return text_type(self.message) + + if PY2: + __unicode__ = __str__ + def __str__(self): + return self.__unicode__().encode('utf-8') + + +class BadPayload(BadData): + """This error is raised in situations when payload is loaded without + checking the signature first and an exception happend as a result of + that. The original exception that caused that will be stored on the + exception as :attr:`original_error`. + + This can also happen with a :class:`JSONWebSignatureSerializer` that + is subclassed and uses a different serializer for the payload than + the expected one. + + .. versionadded:: 0.15 + """ + + def __init__(self, message, original_error=None): + BadData.__init__(self, message) + #: If available, the error that indicates why the payload + #: was not valid. This might be `None`. + self.original_error = original_error + + +class BadSignature(BadData): + """This error is raised if a signature does not match. As of + itsdangerous 0.14 there are helpful attributes on the exception + instances. You can also catch down the baseclass :exc:`BadData`. + """ + + def __init__(self, message, payload=None): + BadData.__init__(self, message) + #: The payload that failed the signature test. In some + #: situations you might still want to inspect this, even if + #: you know it was tampered with. + #: + #: .. versionadded:: 0.14 + self.payload = payload + + +class BadTimeSignature(BadSignature): + """Raised for time based signatures that fail. This is a subclass + of :class:`BadSignature` so you can catch those down as well. + """ + + def __init__(self, message, payload=None, date_signed=None): + BadSignature.__init__(self, message, payload) + + #: If the signature expired this exposes the date of when the + #: signature was created. This can be helpful in order to + #: tell the user how long a link has been gone stale. + #: + #: .. versionadded:: 0.14 + self.date_signed = date_signed + + +class BadHeader(BadSignature): + """Raised if a signed header is invalid in some form. This only + happens for serializers that have a header that goes with the + signature. + + .. versionadded:: 0.24 + """ + + def __init__(self, message, payload=None, header=None, + original_error=None): + BadSignature.__init__(self, message, payload) + + #: If the header is actually available but just malformed it + #: might be stored here. + self.header = header + + #: If available, the error that indicates why the payload + #: was not valid. This might be `None`. + self.original_error = original_error + + +class SignatureExpired(BadTimeSignature): + """Signature timestamp is older than required max_age. This is a + subclass of :exc:`BadTimeSignature` so you can use the baseclass for + catching the error. + """ + + +def base64_encode(string): + """base64 encodes a single bytestring (and is tolerant to getting + called with a unicode string). + The resulting bytestring is safe for putting into URLs. + """ + string = want_bytes(string) + return base64.urlsafe_b64encode(string).strip(b'=') + + +def base64_decode(string): + """base64 decodes a single bytestring (and is tolerant to getting + called with a unicode string). + The result is also a bytestring. + """ + string = want_bytes(string, encoding='ascii', errors='ignore') + return base64.urlsafe_b64decode(string + b'=' * (-len(string) % 4)) + + +def int_to_bytes(num): + assert num >= 0 + rv = [] + while num: + rv.append(int_to_byte(num & 0xff)) + num >>= 8 + return b''.join(reversed(rv)) + + +def bytes_to_int(bytestr): + return reduce(lambda a, b: a << 8 | b, bytearray(bytestr), 0) + + +class SigningAlgorithm(object): + """Subclasses of `SigningAlgorithm` have to implement `get_signature` to + provide signature generation functionality. + """ + + def get_signature(self, key, value): + """Returns the signature for the given key and value""" + raise NotImplementedError() + + def verify_signature(self, key, value, sig): + """Verifies the given signature matches the expected signature""" + return constant_time_compare(sig, self.get_signature(key, value)) + + +class NoneAlgorithm(SigningAlgorithm): + """This class provides a algorithm that does not perform any signing and + returns an empty signature. + """ + + def get_signature(self, key, value): + return b'' + + +class HMACAlgorithm(SigningAlgorithm): + """This class provides signature generation using HMACs.""" + + #: The digest method to use with the MAC algorithm. This defaults to sha1 + #: but can be changed for any other function in the hashlib module. + default_digest_method = staticmethod(hashlib.sha1) + + def __init__(self, digest_method=None): + if digest_method is None: + digest_method = self.default_digest_method + self.digest_method = digest_method + + def get_signature(self, key, value): + mac = hmac.new(key, msg=value, digestmod=self.digest_method) + return mac.digest() + + +class Signer(object): + """This class can sign bytes and unsign it and validate the signature + provided. + + Salt can be used to namespace the hash, so that a signed string is only + valid for a given namespace. Leaving this at the default value or re-using + a salt value across different parts of your application where the same + signed value in one part can mean something different in another part + is a security risk. + + See :ref:`the-salt` for an example of what the salt is doing and how you + can utilize it. + + .. versionadded:: 0.14 + `key_derivation` and `digest_method` were added as arguments to the + class constructor. + + .. versionadded:: 0.18 + `algorithm` was added as an argument to the class constructor. + """ + + #: The digest method to use for the signer. This defaults to sha1 but can + #: be changed for any other function in the hashlib module. + #: + #: .. versionchanged:: 0.14 + default_digest_method = staticmethod(hashlib.sha1) + + #: Controls how the key is derived. The default is Django style + #: concatenation. Possible values are ``concat``, ``django-concat`` + #: and ``hmac``. This is used for deriving a key from the secret key + #: with an added salt. + #: + #: .. versionadded:: 0.14 + default_key_derivation = 'django-concat' + + def __init__(self, secret_key, salt=None, sep='.', key_derivation=None, + digest_method=None, algorithm=None): + self.secret_key = want_bytes(secret_key) + self.sep = sep + self.salt = 'itsdangerous.Signer' if salt is None else salt + if key_derivation is None: + key_derivation = self.default_key_derivation + self.key_derivation = key_derivation + if digest_method is None: + digest_method = self.default_digest_method + self.digest_method = digest_method + if algorithm is None: + algorithm = HMACAlgorithm(self.digest_method) + self.algorithm = algorithm + + def derive_key(self): + """This method is called to derive the key. If you're unhappy with + the default key derivation choices you can override them here. + Keep in mind that the key derivation in itsdangerous is not intended + to be used as a security method to make a complex key out of a short + password. Instead you should use large random secret keys. + """ + salt = want_bytes(self.salt) + if self.key_derivation == 'concat': + return self.digest_method(salt + self.secret_key).digest() + elif self.key_derivation == 'django-concat': + return self.digest_method(salt + b'signer' + + self.secret_key).digest() + elif self.key_derivation == 'hmac': + mac = hmac.new(self.secret_key, digestmod=self.digest_method) + mac.update(salt) + return mac.digest() + elif self.key_derivation == 'none': + return self.secret_key + else: + raise TypeError('Unknown key derivation method') + + def get_signature(self, value): + """Returns the signature for the given value""" + value = want_bytes(value) + key = self.derive_key() + sig = self.algorithm.get_signature(key, value) + return base64_encode(sig) + + def sign(self, value): + """Signs the given string.""" + return value + want_bytes(self.sep) + self.get_signature(value) + + def verify_signature(self, value, sig): + """Verifies the signature for the given value.""" + key = self.derive_key() + try: + sig = base64_decode(sig) + except Exception: + return False + return self.algorithm.verify_signature(key, value, sig) + + def unsign(self, signed_value): + """Unsigns the given string.""" + signed_value = want_bytes(signed_value) + sep = want_bytes(self.sep) + if sep not in signed_value: + raise BadSignature('No %r found in value' % self.sep) + value, sig = signed_value.rsplit(sep, 1) + if self.verify_signature(value, sig): + return value + raise BadSignature('Signature %r does not match' % sig, + payload=value) + + def validate(self, signed_value): + """Just validates the given signed value. Returns `True` if the + signature exists and is valid, `False` otherwise.""" + try: + self.unsign(signed_value) + return True + except BadSignature: + return False + + +class TimestampSigner(Signer): + """Works like the regular :class:`Signer` but also records the time + of the signing and can be used to expire signatures. The unsign + method can rause a :exc:`SignatureExpired` method if the unsigning + failed because the signature is expired. This exception is a subclass + of :exc:`BadSignature`. + """ + + def get_timestamp(self): + """Returns the current timestamp. This implementation returns the + seconds since 1/1/2011. The function must return an integer. + """ + return int(time.time() - EPOCH) + + def timestamp_to_datetime(self, ts): + """Used to convert the timestamp from `get_timestamp` into a + datetime object. + """ + return datetime.utcfromtimestamp(ts + EPOCH) + + def sign(self, value): + """Signs the given string and also attaches a time information.""" + value = want_bytes(value) + timestamp = base64_encode(int_to_bytes(self.get_timestamp())) + sep = want_bytes(self.sep) + value = value + sep + timestamp + return value + sep + self.get_signature(value) + + def unsign(self, value, max_age=None, return_timestamp=False): + """Works like the regular :meth:`~Signer.unsign` but can also + validate the time. See the base docstring of the class for + the general behavior. If `return_timestamp` is set to `True` + the timestamp of the signature will be returned as naive + :class:`datetime.datetime` object in UTC. + """ + try: + result = Signer.unsign(self, value) + sig_error = None + except BadSignature as e: + sig_error = e + result = e.payload or b'' + sep = want_bytes(self.sep) + + # If there is no timestamp in the result there is something + # seriously wrong. In case there was a signature error, we raise + # that one directly, otherwise we have a weird situation in which + # we shouldn't have come except someone uses a time-based serializer + # on non-timestamp data, so catch that. + if not sep in result: + if sig_error: + raise sig_error + raise BadTimeSignature('timestamp missing', payload=result) + + value, timestamp = result.rsplit(sep, 1) + try: + timestamp = bytes_to_int(base64_decode(timestamp)) + except Exception: + timestamp = None + + # Signature is *not* okay. Raise a proper error now that we have + # split the value and the timestamp. + if sig_error is not None: + raise BadTimeSignature(text_type(sig_error), payload=value, + date_signed=timestamp) + + # Signature was okay but the timestamp is actually not there or + # malformed. Should not happen, but well. We handle it nonetheless + if timestamp is None: + raise BadTimeSignature('Malformed timestamp', payload=value) + + # Check timestamp is not older than max_age + if max_age is not None: + age = self.get_timestamp() - timestamp + if age > max_age: + raise SignatureExpired( + 'Signature age %s > %s seconds' % (age, max_age), + payload=value, + date_signed=self.timestamp_to_datetime(timestamp)) + + if return_timestamp: + return value, self.timestamp_to_datetime(timestamp) + return value + + def validate(self, signed_value, max_age=None): + """Just validates the given signed value. Returns `True` if the + signature exists and is valid, `False` otherwise.""" + try: + self.unsign(signed_value, max_age=max_age) + return True + except BadSignature: + return False + + +class Serializer(object): + """This class provides a serialization interface on top of the + signer. It provides a similar API to json/pickle and other modules but is + slightly differently structured internally. If you want to change the + underlying implementation for parsing and loading you have to override the + :meth:`load_payload` and :meth:`dump_payload` functions. + + This implementation uses simplejson if available for dumping and loading + and will fall back to the standard library's json module if it's not + available. + + Starting with 0.14 you do not need to subclass this class in order to + switch out or customer the :class:`Signer`. You can instead also pass a + different class to the constructor as well as keyword arguments as + dictionary that should be forwarded:: + + s = Serializer(signer_kwargs={'key_derivation': 'hmac'}) + + .. versionchanged:: 0.14: + The `signer` and `signer_kwargs` parameters were added to the + constructor. + """ + + #: If a serializer module or class is not passed to the constructor + #: this one is picked up. This currently defaults to :mod:`json`. + default_serializer = json + + #: The default :class:`Signer` class that is being used by this + #: serializer. + #: + #: .. versionadded:: 0.14 + default_signer = Signer + + def __init__(self, secret_key, salt=b'itsdangerous', serializer=None, + signer=None, signer_kwargs=None): + self.secret_key = want_bytes(secret_key) + self.salt = want_bytes(salt) + if serializer is None: + serializer = self.default_serializer + self.serializer = serializer + self.is_text_serializer = is_text_serializer(serializer) + if signer is None: + signer = self.default_signer + self.signer = signer + self.signer_kwargs = signer_kwargs or {} + + def load_payload(self, payload, serializer=None): + """Loads the encoded object. This function raises :class:`BadPayload` + if the payload is not valid. The `serializer` parameter can be used to + override the serializer stored on the class. The encoded payload is + always byte based. + """ + if serializer is None: + serializer = self.serializer + is_text = self.is_text_serializer + else: + is_text = is_text_serializer(serializer) + try: + if is_text: + payload = payload.decode('utf-8') + return serializer.loads(payload) + except Exception as e: + raise BadPayload('Could not load the payload because an ' + 'exception occurred on unserializing the data', + original_error=e) + + def dump_payload(self, obj): + """Dumps the encoded object. The return value is always a + bytestring. If the internal serializer is text based the value + will automatically be encoded to utf-8. + """ + return want_bytes(self.serializer.dumps(obj)) + + def make_signer(self, salt=None): + """A method that creates a new instance of the signer to be used. + The default implementation uses the :class:`Signer` baseclass. + """ + if salt is None: + salt = self.salt + return self.signer(self.secret_key, salt=salt, **self.signer_kwargs) + + def dumps(self, obj, salt=None): + """Returns a signed string serialized with the internal serializer. + The return value can be either a byte or unicode string depending + on the format of the internal serializer. + """ + payload = want_bytes(self.dump_payload(obj)) + rv = self.make_signer(salt).sign(payload) + if self.is_text_serializer: + rv = rv.decode('utf-8') + return rv + + def dump(self, obj, f, salt=None): + """Like :meth:`dumps` but dumps into a file. The file handle has + to be compatible with what the internal serializer expects. + """ + f.write(self.dumps(obj, salt)) + + def loads(self, s, salt=None): + """Reverse of :meth:`dumps`, raises :exc:`BadSignature` if the + signature validation fails. + """ + s = want_bytes(s) + return self.load_payload(self.make_signer(salt).unsign(s)) + + def load(self, f, salt=None): + """Like :meth:`loads` but loads from a file.""" + return self.loads(f.read(), salt) + + def loads_unsafe(self, s, salt=None): + """Like :meth:`loads` but without verifying the signature. This is + potentially very dangerous to use depending on how your serializer + works. The return value is ``(signature_okay, payload)`` instead of + just the payload. The first item will be a boolean that indicates + if the signature is okay (``True``) or if it failed. This function + never fails. + + Use it for debugging only and if you know that your serializer module + is not exploitable (eg: do not use it with a pickle serializer). + + .. versionadded:: 0.15 + """ + return self._loads_unsafe_impl(s, salt) + + def _loads_unsafe_impl(self, s, salt, load_kwargs=None, + load_payload_kwargs=None): + """Lowlevel helper function to implement :meth:`loads_unsafe` in + serializer subclasses. + """ + try: + return True, self.loads(s, salt=salt, **(load_kwargs or {})) + except BadSignature as e: + if e.payload is None: + return False, None + try: + return False, self.load_payload(e.payload, + **(load_payload_kwargs or {})) + except BadPayload: + return False, None + + def load_unsafe(self, f, *args, **kwargs): + """Like :meth:`loads_unsafe` but loads from a file. + + .. versionadded:: 0.15 + """ + return self.loads_unsafe(f.read(), *args, **kwargs) + + +class TimedSerializer(Serializer): + """Uses the :class:`TimestampSigner` instead of the default + :meth:`Signer`. + """ + + default_signer = TimestampSigner + + def loads(self, s, max_age=None, return_timestamp=False, salt=None): + """Reverse of :meth:`dumps`, raises :exc:`BadSignature` if the + signature validation fails. If a `max_age` is provided it will + ensure the signature is not older than that time in seconds. In + case the signature is outdated, :exc:`SignatureExpired` is raised + which is a subclass of :exc:`BadSignature`. All arguments are + forwarded to the signer's :meth:`~TimestampSigner.unsign` method. + """ + base64d, timestamp = self.make_signer(salt) \ + .unsign(s, max_age, return_timestamp=True) + payload = self.load_payload(base64d) + if return_timestamp: + return payload, timestamp + return payload + + def loads_unsafe(self, s, max_age=None, salt=None): + load_kwargs = {'max_age': max_age} + load_payload_kwargs = {} + return self._loads_unsafe_impl(s, salt, load_kwargs, load_payload_kwargs) + + +class JSONWebSignatureSerializer(Serializer): + """This serializer implements JSON Web Signature (JWS) support. Only + supports the JWS Compact Serialization. + """ + + jws_algorithms = { + 'HS256': HMACAlgorithm(hashlib.sha256), + 'HS384': HMACAlgorithm(hashlib.sha384), + 'HS512': HMACAlgorithm(hashlib.sha512), + 'none': NoneAlgorithm(), + } + + #: The default algorithm to use for signature generation + default_algorithm = 'HS256' + + default_serializer = compact_json + + def __init__(self, secret_key, salt=None, serializer=None, + signer=None, signer_kwargs=None, algorithm_name=None): + Serializer.__init__(self, secret_key, salt, serializer, + signer, signer_kwargs) + if algorithm_name is None: + algorithm_name = self.default_algorithm + self.algorithm_name = algorithm_name + self.algorithm = self.make_algorithm(algorithm_name) + + def load_payload(self, payload, return_header=False): + payload = want_bytes(payload) + if b'.' not in payload: + raise BadPayload('No "." found in value') + base64d_header, base64d_payload = payload.split(b'.', 1) + try: + json_header = base64_decode(base64d_header) + except Exception as e: + raise BadHeader('Could not base64 decode the header because of ' + 'an exception', original_error=e) + try: + json_payload = base64_decode(base64d_payload) + except Exception as e: + raise BadPayload('Could not base64 decode the payload because of ' + 'an exception', original_error=e) + try: + header = Serializer.load_payload(self, json_header, + serializer=json) + except BadData as e: + raise BadHeader('Could not unserialize header because it was ' + 'malformed', original_error=e) + if not isinstance(header, dict): + raise BadHeader('Header payload is not a JSON object', + header=header) + payload = Serializer.load_payload(self, json_payload) + if return_header: + return payload, header + return payload + + def dump_payload(self, header, obj): + base64d_header = base64_encode(self.serializer.dumps(header)) + base64d_payload = base64_encode(self.serializer.dumps(obj)) + return base64d_header + b'.' + base64d_payload + + def make_algorithm(self, algorithm_name): + try: + return self.jws_algorithms[algorithm_name] + except KeyError: + raise NotImplementedError('Algorithm not supported') + + def make_signer(self, salt=None, algorithm=None): + if salt is None: + salt = self.salt + key_derivation = 'none' if salt is None else None + if algorithm is None: + algorithm = self.algorithm + return self.signer(self.secret_key, salt=salt, sep='.', + key_derivation=key_derivation, algorithm=algorithm) + + def make_header(self, header_fields): + header = header_fields.copy() if header_fields else {} + header['alg'] = self.algorithm_name + return header + + def dumps(self, obj, salt=None, header_fields=None): + """Like :meth:`~Serializer.dumps` but creates a JSON Web Signature. It + also allows for specifying additional fields to be included in the JWS + Header. + """ + header = self.make_header(header_fields) + signer = self.make_signer(salt, self.algorithm) + return signer.sign(self.dump_payload(header, obj)) + + def loads(self, s, salt=None, return_header=False): + """Reverse of :meth:`dumps`. If requested via `return_header` it will + return a tuple of payload and header. + """ + payload, header = self.load_payload( + self.make_signer(salt, self.algorithm).unsign(want_bytes(s)), + return_header=True) + if header.get('alg') != self.algorithm_name: + raise BadHeader('Algorithm mismatch', header=header, + payload=payload) + if return_header: + return payload, header + return payload + + def loads_unsafe(self, s, salt=None, return_header=False): + kwargs = {'return_header': return_header} + return self._loads_unsafe_impl(s, salt, kwargs, kwargs) + + +class TimedJSONWebSignatureSerializer(JSONWebSignatureSerializer): + """Works like the regular :class:`JSONWebSignatureSerializer` but also + records the time of the signing and can be used to expire signatures. + + JWS currently does not specify this behavior but it mentions a possibility + extension like this in the spec. Expiry date is encoded into the header + similarily as specified in `draft-ietf-oauth-json-web-token + 0): + raise BadSignature('expiry date is not an IntDate', + payload=payload) + + if header['exp'] < self.now(): + raise SignatureExpired('Signature expired', payload=payload, + date_signed=self.get_issue_date(header)) + + if return_header: + return payload, header + return payload + + def get_issue_date(self, header): + rv = header.get('iat') + if isinstance(rv, number_types): + return datetime.utcfromtimestamp(int(rv)) + + def now(self): + return int(time.time()) + + +class URLSafeSerializerMixin(object): + """Mixed in with a regular serializer it will attempt to zlib compress + the string to make it shorter if necessary. It will also base64 encode + the string so that it can safely be placed in a URL. + """ + + def load_payload(self, payload): + decompress = False + if payload.startswith(b'.'): + payload = payload[1:] + decompress = True + try: + json = base64_decode(payload) + except Exception as e: + raise BadPayload('Could not base64 decode the payload because of ' + 'an exception', original_error=e) + if decompress: + try: + json = zlib.decompress(json) + except Exception as e: + raise BadPayload('Could not zlib decompress the payload before ' + 'decoding the payload', original_error=e) + return super(URLSafeSerializerMixin, self).load_payload(json) + + def dump_payload(self, obj): + json = super(URLSafeSerializerMixin, self).dump_payload(obj) + is_compressed = False + compressed = zlib.compress(json) + if len(compressed) < (len(json) - 1): + json = compressed + is_compressed = True + base64d = base64_encode(json) + if is_compressed: + base64d = b'.' + base64d + return base64d + + +class URLSafeSerializer(URLSafeSerializerMixin, Serializer): + """Works like :class:`Serializer` but dumps and loads into a URL + safe string consisting of the upper and lowercase character of the + alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ + default_serializer = compact_json + + +class URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer): + """Works like :class:`TimedSerializer` but dumps and loads into a URL + safe string consisting of the upper and lowercase character of the + alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ + default_serializer = compact_json diff --git a/Lib/site-packages/jinja2/__init__.py b/Lib/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..42aa763 --- /dev/null +++ b/Lib/site-packages/jinja2/__init__.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +""" + jinja2 + ~~~~~~ + + Jinja2 is a template engine written in pure Python. It provides a + Django inspired non-XML syntax but supports inline expressions and + an optional sandboxed environment. + + Nutshell + -------- + + Here a small example of a Jinja2 template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} +
+ {% endblock %} + + + :copyright: (c) 2017 by the Jinja Team. + :license: BSD, see LICENSE for more details. +""" +__docformat__ = 'restructuredtext en' +__version__ = '2.10' + +# high level interface +from jinja2.environment import Environment, Template + +# loaders +from jinja2.loaders import BaseLoader, FileSystemLoader, PackageLoader, \ + DictLoader, FunctionLoader, PrefixLoader, ChoiceLoader, \ + ModuleLoader + +# bytecode caches +from jinja2.bccache import BytecodeCache, FileSystemBytecodeCache, \ + MemcachedBytecodeCache + +# undefined types +from jinja2.runtime import Undefined, DebugUndefined, StrictUndefined, \ + make_logging_undefined + +# exceptions +from jinja2.exceptions import TemplateError, UndefinedError, \ + TemplateNotFound, TemplatesNotFound, TemplateSyntaxError, \ + TemplateAssertionError, TemplateRuntimeError + +# decorators and public utilities +from jinja2.filters import environmentfilter, contextfilter, \ + evalcontextfilter +from jinja2.utils import Markup, escape, clear_caches, \ + environmentfunction, evalcontextfunction, contextfunction, \ + is_undefined, select_autoescape + +__all__ = [ + 'Environment', 'Template', 'BaseLoader', 'FileSystemLoader', + 'PackageLoader', 'DictLoader', 'FunctionLoader', 'PrefixLoader', + 'ChoiceLoader', 'BytecodeCache', 'FileSystemBytecodeCache', + 'MemcachedBytecodeCache', 'Undefined', 'DebugUndefined', + 'StrictUndefined', 'TemplateError', 'UndefinedError', 'TemplateNotFound', + 'TemplatesNotFound', 'TemplateSyntaxError', 'TemplateAssertionError', + 'TemplateRuntimeError', + 'ModuleLoader', 'environmentfilter', 'contextfilter', 'Markup', 'escape', + 'environmentfunction', 'contextfunction', 'clear_caches', 'is_undefined', + 'evalcontextfilter', 'evalcontextfunction', 'make_logging_undefined', + 'select_autoescape', +] + + +def _patch_async(): + from jinja2.utils import have_async_gen + if have_async_gen: + from jinja2.asyncsupport import patch_all + patch_all() + + +_patch_async() +del _patch_async diff --git a/Lib/site-packages/jinja2/__pycache__/__init__.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34a50f3f60ee747630a8e03c20d876c4f3117656 GIT binary patch literal 2533 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 HoF@MV3)2Vn literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/_identifier.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/_identifier.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4a53fe09177fda5da7f7387d5f24fd6f0e8d827 GIT binary patch literal 1846 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 U)_lKO_0cN(p8l)M&d;9uUoTYn#sB~S literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/bccache.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/bccache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b82d9763767d77022060684b0e27f4fe431a357 GIT binary patch literal 12715 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/compiler.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/compiler.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24a49fd2ab2ae113d5b2fe9ba7272f08487d2f4e GIT binary patch literal 46844 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 jQ7z%(4A);@v|n#Op3VN&m;bI47~kWmpFz0U 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/environment.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/environment.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96dc484723e121220ee588249d2e3567582d0cbc GIT binary patch literal 43254 zcmcJ2dvqMvdEdUVSS&!i2tGtfD@qgznuH|kX^MJKBq&j)V48$1X)R~5*cku|?gP3r z5Q+6daZM+d)5>+~wn>~v$v8>tG&yaPoSZhNN!q$ideXGbIceH-+9qw&o>QkM>1ooY zIsPN*@Aut1cV-sQ!%how@6OKLxpN=i{oda<&y9|jQuzCsY5xO_08I@zA8PPM12)9t<0z3rLmOnYB-UweOb zfBQi7fV5L+9c6=u54BHJPssUl>tuVbI@f-n`at`^>Vxfv zst>hKRZq1au0Gs;r20tv(dwg8Z?yGT`|;}I?I)^Fv_D+^aQk%iboa*>$)wAi8`+zfcGhKbo$<)s|dz|slrmE+i31<@D^UjnrjqeN2 zUS|g1&pZ2^{rG;tIp7?`_r>Q^&K=I7&!(J1?u$3G)sNu!oz7kOeV6>cdI?&Rx5I%yWuyx9dAxIak|mn*iy~aHUD(wSYx(w>cNK|uPkq&CAab-dsA6->+Lyt z-04=c;dVUtbmh6L=TB5T*R5Q-cy4~->U?FTt19iTax0GO*PAW0{&m9f!fYleDA(C+ zxWN#5;Wz88*>sTabkXbC@nG_~OCLS=k=oV8vsV^TUb(pNd@!!h%`cn}&+Ps9*((>% zK6hz8S#ipqj@6w$_tBSLnqOdRu{I~ev$2|cFI`-a78mE`hRavxFI;>zn3B_BeRFaI zU3;k}9lIKgFU-H9@16hH%kvB8=7T-w=P#Un`O;$T!o^FA^H;70qv46g`KyapgNg9x z!r7PRuUF!ey+pt8g?j|7N{)uG{h58$NC+uDTsp)qOV@J%^cpUjOQ< z*=#WUa>sF3njO~(Mmp~GT0`Fy425^+f~iHfz0tzmSGPKT{l>gfT@{RnCl|W@h3;m@ z2`0ibo;@`kp1PueQEr_r2BXdPMpyYY&sPA;pm^!Z%jfEiH8&`{R9DwFH-e#d(<8(N z1@xy;_k$sPdz)=HC^s=E)v31{7)UU-R)5p2)xE7wqlPigjs&@8yN>&tE6o<_1!et+ zn!mN-dcklL=kRIckW(Y4gCT{vX?kujg>JQ6?mDl=nspxoosOOKyJ462xE*$&hR3*_ zI{KBp{MxA?clou;uYH{;y+P>bUk0BdKF{OhEuh#M^HaCd{nYLBcKVf6XMZl`XRejh z{pl3{`PqKz3#qHAS5tl9`D?@Kk$(EBIg6U9e(FqW8+4$buH|@THrxA+E3Ut(I=}%~ zzlyhk1*~`6?xt6Xp^>>tmw-j;`3HLh7$oXrOZ zYO&$eV#D!*EOtRKyohDh@HjFb;mn}mt<`~b0QtGPT192t`qh+r3e*3Mm(QJk{blSD z@AdhGkH1!V=<(OjZfu;d`}Nl^bsP28>jc@?H<}wKn;p-uw^}D#Z>;(Ct%p`#7j$^) zb&aE6kM(A5V=K6WyYgLndxC2}i6WKHq{r~DlrE-o>G5Vwb{Kw7ma~2!iM1~X)BlFy9^G&x?@tQq%PO<%k*|fSB z-@p<%o|ReA#nU()lpDY%zFU*F&fttEEJ}tw=0}~yx!rqwKdwkGi|8@IR(k2DuNBoH z>2;=`S_gRq*k*di&dGBC3Kh(_zf~b2s&rRkot7@lEzIVE9QSXKbD9lbIv*4p^^JO? z>2HymNWH;vl-Qmg#e8xUWsc$kN5Q$~U(S4F-XFt{W@DKr2aUBPee*Jzrpdxe2P= z^ecW>*NtFTL%&{A(sd4*vm($4ijJiLml4$mr6uElIVv@QF#)ojhN}p1>M#nNb%4)+ z4nY@k!AR`RpcHkHMB3YIVMp0>gY&tkg^|_lWx-`$8IMTiasX(8^kiDSgx`s2CGg0! zR&me=R-3`pVnWk0p$l8(e)?ACHZUJ>;T$kr7P#n>`G4Z8=GCi0Gb~oy{v^W_1UO>cQFyc$eDsroUDLMbl)l<_f(Vp1;v>g>zE(pf2XJV5nD4 zOBmS*8=lW^V~N!L6Sj3^n!18u64TCI~88UARKbPdcEere_*SG-42Fr zrv(Utv9lhi16gEESSF>fp!?`mNd5PQ9Z#N~HbY3B9Utr?5b#AT<=_T85GQaoPZpyl zi{YTQ29?ZoCI>*7&Xh?zK8f=UeC*#0j-JKG`*C1;Hw95KMKKW~Vy2qIC+}pd1$+Y( zszrQ;-BNYLEmud~F?WwU?oPOq?vy+2?saF}eeQnufRl6b?m-9l<5O^Ozmr*+afY1Y zXVcX?oMEQ~0qKx4;*{}yr+e22`L{CVj5=eu|8A_zJru^?$y5&;VeDQbjNNC1u_MlN zB95i2_dDlAAWK(|y2qUJB9a08tFu}ds~&geMF>k*Kjd5x;VWG|;XE%wSGs!AdBHj2 z+>fWuIY*si=n)Lo^U=aEj^B3A9YSUPs*<+@awX3#(7G9ec1V! z^R)8}+Bxk!>zqY9PdZs_!z=2;Shf0poJyq@Nx&&c0hYkZaYJBZX-N!x7AgADe1!g& zz}Q{%Q5j4hu)oj(&0N>Hm4pql+swmuxW<+{E6vqSu(ts66X6y;QSn{R_fAL?tF7*G zy+yVVdlt`B9-m{Vi>IkHdZRafyS_zK(C%W7HbI@5E1C;jbGIsB!zyI-Oi$Qea|LJc zFwG-YuGi5mkQUtNbt@}%r3uhI_BDq>|flL~{9-rO+7zD(LW*0q>n_mFFkpXbhH@b!sZURX{if#6!YZR?P zNQmQ3>$^yemv-WeC25iu`Nvf@tZ*9=54*&NEW4}CPKUp+=JkrSf{8!xuGB%CvHIQ0 z($djS9XYzRWctX)%+rA741W4R&k}U}9#1*4J@AxWaoz`d)WEQ?2pY{})d1gmy*Uv6 z4UY9w@79ZNb-061PdqZQNSNyF!AaN+!+$GtVA|Pbaqk@%aQMV;b-eHTq4*GI2b zUNuS)bP+qu1vQiJo7doDsd$$>{piiA_wce;eu^CpmC$t-IOM3X8CYj15Xn2+7VfmO5%+ z)<`He=}VS-O167iSi{pxFNb2Z>=b}NOj@M=gZ2tctk4Y1wQ>y*Bxb=r1DtGY6Uam> zBXeMAe;03>phk@q?DbUs&0xJKOmKJasID{JJCX`vNEsPA^u_`eQ zMHRrC8=v#~rr&ivXut+W3F^EXxp?)ZOAoxT_|m0{y^ouD1zNsMcAk1-S!|en5(718 zEDo;5x>KnyW3C-Hv_4|}s&WaeJ1)EcIk7yo(Q$;2q(GnJ_ zKCpi1^aku*AZ&4DAUYkvoNL&EezFy%wd9tN3gR}H%BUweEm&1MO~65Vdn_l17R^_P zxMQosm5tC)W3Ap21BDQ5=4BDyVO_tL6cW%*RLRp=k!P0luM=m?%P;)N<=U(#nMik~>AC3`3F7PXNE| zwy3)a*?K!9np;|8&qMm5`+`OxZNmfsrWPcY?a)+ug0kw4Mh99u`4F26Crl555--+K z#^O4$+2`c!4jfM;nnkrm+oY@t#pGs(x_N>6uFR-0s(~Ja(KhT5Bg_-3<7rpMLB4bDCUqd;JL@*7i?;1EZb|e>k+*{lNuvb=R-!_~Qidn(ZEsQrBG2YfPb8(C#p{F zjrdY6Z~1^em=a~fC08p#=wN_NJ-sn2-Q{&?FpTJ>e`wePEu&As03#ud8{B}78XKz7 zE7_(YeaY61c8AmL98FG(a48^CfN#1LV6OGdZh<`oyb$ya(u<9f%S{1K^D*J`PU;~` zw+6YP*v(5C-)b}OyG@V}@d%v<4C&frm|+!;Km`W#251oQyT)4B=-ul{@S)8BBlGJ} zlGU9zp+T#!3O)qKilx51<*(s(LpaICE%JE;x+XY+1SFce56?ZuO+e$h(Q92;5WVkW z^NUc?Hugd7$3K2&@i~W&_b*WNq1CU!sDv_2V^b~DhmOCN?dMVE`URBv{t(JSzld_E zKa8^2FQFXnkDx5|%P2?sdr+49V<<=a<0!}a6DariHdO$4~`G}_tHcL zZyj1^(hIZqsn;;BU|g%lB5j7EAtaazSuH5RLp7HA1g}hnf_`)%*h^83T6O?xq^by} zh-BnCdukhM%$P_z4G2|?RQbe}Z9@fgy)EEpI zTZbCwxx8po)dY`+j5;+aXp|%-R7I;~Fc$6wz5Rm`wrw!CqRF^g+~|@ybUm@HsTX-y zIld#*EKe1ip57p06`0)zUNut6E}FXR*wp!Gd-MnG@ymh>ub$ zEI1cxmBkv1Hj1Dmn^zbK)#cd^iwzdEv+F`E%EelZO4C{m{%9%h30zFwTY&vymw#Dv zE=z-A3BO9Ll`Un1H!Zp-<`( zi-9Q`MJthQb&>PL!KCuN1Mv|jYBf+x{%F1Cus?#2_aKTJ$7x`_N$d4puV=P1uwY{w z!&sW}N-`O=VrSE0w>H!9-!L6Q<-|Kiups!4(4HLfgzRY3y$&+^d|q4sRTA-3h6c4_8oxgN|!=5)u!JZ_D+@H7*%Vg)s|8C=}9c zOI~pqJd$YCn;j77rWnK{g$0-9B<3g>f{al2eH9FWN#wz7PSyw88$X)Mo7liX_L{pD z8#n(odyO zW~9tM1+So6!29bt_zCUp?_JN|0?uF03k2u-dx7y&D2q3a`NREbS?WVr>Y43*{e6B3 zenXf15n%0^{ytggOK?z_kn^AR%l!#p^}V&xPT2=tSRd8Dnrv^+jr-AFYJHEixIb+1 z)_8yKZQQfIr#}OChaW;~BhuQx;<;M|e*(`M(fiAv?C%v9k9>U=YZNa}P5v|I3jqM^x*EC&2W&Whg{ z<3O=(K+Ud^m4$wy1#d3xw^?ryW2t(Cw?a=&ZWEbp5o7gCgQM0G>>6~0oC<3RPm(8nt@ZQ-XLGXQvdY04Xk3 z!3zqSMGl5))PvS)!Emi6Dk>a;KGDmjR#Th2W!SEJFsuhvgC8JqhC0IH28**S=2_5@ zNF)0ky?Qj2re%J1zwQ*-o^Or>zbD~UGRTPHK8faojCxb`_?%C%7$7b~Wu|in9Luwu^gF2WYD!$#v%S;L!}kVw6Ju*r>al1- zl&L_PBC=LMS;aPJR+zQt;HjC#Wpx?jSePA#6HbV;#R*4|X$(d#K^wlgq0fld7Tw%} zELeI)-zf0envx5@YRI|zi?~uP!VOe(meB_byHPy4VX7A@n0QIkc32OR%lqT%J+ zhYL?)qTl(JCfY7Xgf(C8h(pL}I54c8UNVEx+ALeUa-6})zo*hpa22JOSS?l2gA1gfwhp^zshwON4-=ooOit*J7%BFG=^9cfAq8F zwvgHXIUEofz}Gqr9%`sR1XtRky35bdd-^7P~0?(AHVnnkJkm-_{&`JHmduzIVXUmw~obc#MCb8NFh zU*B1fJNL_-!*b_Om@6q>fi$1(=Qe(}nfd~;VX6KKCgEb|O?dc&eK1}+qMp_aub@W{ zz9%5tI$Xo(FrjmUbpX3Cra}Sbrgj9z7SP&IH-Qu2GTMy&0K;v3$l-egCK|LB%s;qp zxbOiDTe_=7Tx#kNULuYvS_PSK&*7a~`2sQzUVxTgpmKe$ZOYr+Uvgdk#Wa7AL^`eu1AA=1yUAyd+h;HICgFl)2BSUR zk7%S&9i=N3sE)pPp?B)655%w`I>jzV#`U25!8&0Jq2yssi<@kFefD_waWCG8ha;L6ObX8vYGMDPp#$_Y(1?ruo7K6s}zte|JVp zu!HLRq)A#62DVu+Lgtj=3!q#-%k6d;RZ}BnaYmhlk6|%g%#7)892J55%J|pY7pG0J zHX0=J{G%*HG$@;pzSOZzm^Yg$z6n8#RzPdG34aJmu8mV>1LS&61pUN1-zx0CA1I8A zHyYYc00OYpHFQ2&nc2c_Q?91S`lVGu-_l;pUk5|k8gr?zvNq6p0Z)gaA)wgYr$He3IGbU}iH zWG8AJIF-(_InCbZ9)*JjWD9tlV^1Q~r-I0$(D-dP56_XJOAHrLK`7p{0gHpMRRM%x zW6V{5IpnJ{BIL9$*`nKIx=M}-J6I5r_{25NdV>k z7Qm#lG2PM0pn$0d3B8%4D?in}y(cb)CI+^^X$?)97F?F3?Ii)hB?C80bJ%zL(6Bni z;>S>geB6)lgy6d$Vg(#Y|`fGrPh1nrB zhwmUSqHc9qW|<X2_QX#!@QNg4P7DCy*KGfp6&gY%XYE>HypW{6j7*A ze*;u$LX%=BmWBtbw6ZfoB8Hh3jTr6>H?vm4(qzu9t*6lw$?iCo{kYUO^NqnoHoGt^ z1ib?4<@#-Un|K5Qzd9%^JOGj7bl7n{{qS9iR%(aNe~R-nhN7ParA)n@emg}QP@{LEw20yp?#e zJoKx$A;*Vuxl?%n#LVswwrmz<9*c@UjvsLjVVgP@i^%%9+qv!hjR#Q!e1e3u75ar+ zImj~U?L3qLdA|VDz;V9->!O$jw)1ZshmJQdsQfRT(=cFy!Ub!S@%9ob zuwWFz51}yueNmv>pudo8y}4L`a}2Lxe{#muUq=xXL-3Hfua4@c(-j_3(K@<|qzd zl=!$(;MEG4>rAh2$>th8|AaCa{7sdZQD|fC*$m=nJob!SmPPKtx3V9Xac2OS`)B86g`?`7!*R2sJ15=Y^%PX0pR_4dNLR z3s4IXRtgz=+hcg^g?z-|W2|?Yt=ypE#<*|M+C>*B&Se|^`t);xOkrCK5kR{MRYY9L zv4~C^;Z1ly-6iUDgs-7&R`bRInG#!e9k~}mM#T2qw$(;l8(0GoG9epD?gv<- zVxEx^&JrIo)TESYD)QNN!~^sBP)BXTCs(Gzvft*(_Ibuzo%KTmMT0Y?H_d!9co>Jq z`#aSANPUT#vn{!iwgdRgqZs_Jr3m%JPypaWaPTyt>KtlmqVcRu(|=l zToU;%PYmdfte5?fTce1A9lD(Xt}Qyl?_^gsJ|4r>J;0Sb2Pc#5A%7gWQt)kToA5zRTMcDnli}SLvW;Fw+>^A zXJO0=i;<_g-tvZ-k6D?+XA^oO$9MjU-5YH+5$?3chq5H_Z9MeEuIZqgO^?``10we zpQZ)5@>C_pLLZy8PnPTO;YS5jn==pxWeV7PaqB;Jbfw#^JoQxNkyA%^-gXQZpE~t$ zbU}Q`ceF0m9yt|Nqep8rlS!}Y0W^*oHo7yQNFWRyCt&<6?USMo8+?jc?!-dyg(QS{ z)zA>*nQ7YqPY+Z?7o18I$pHqo)?s9VJbOosm6_jNCk|-t==N0E!x16Xij%SqYv2|f?|k+ffIiMm}H?h(^x~E0OJ%9O{c+`ivCoT z4-n$;MF>X7Bbcz>ptxvuOfVT9&0DAqO#(#M!GsN&31=`UNMDs8Y%;SO zD#$H&oh`^urqw|%o}QO*Pub0sNbWcMI_%!wbR@18wA45GK~zabDt%uA5x$8GwPV1RTogN!2EaH z!>Bjx13^O<0z~f=w}(2XaW&f-+Ahg=aeJg+BC>aeZc($w|V3;`ZpT2{>-%pVfVy?!cINf$_T=`|_VgCKZf_lgx9&tAIqaP2+xhLi zAaBotyxnoF^u;t;`|TNIQmOO{Urc+8pW!_2MeP~pRAFzvn7)qWH6)VTGjGj=nN|A5 zTZizR^!8ML2(A1Io^oe@FZ_Ms4}3cVAG1+BZ)RT#KE@-r?(Xm7JUZfOhW7VMZ*Vny zM&}Ug_xC#E^hHCB1FR8V{bHKwbJ&NsGkDgYyq&#OxeePl+zj&0L0L!Yaqg%;iS2O# z9yUO8#+fPvT&?8_-Ti?C;i~JL01g%Km8)%w2dKJ|J+04!Rje!_w+D>hl1l*rpS|XW zFp?VWA}#=V512v#A_^^=wk6b~FhC!CaD-+PMRCyb5O~Mq7Rc!cF##e0-&!$$&uu}I zs^dg)U2ld8n#AZ<>EyE34s9!Ql|>{k0HcXm%9z1}Pc_f5x12D&H|QStMsWDjQC$%M zt1$w)6lr3N79PU^-&~`r9%rDT3xli>l}*l^Vc8zCriEjTsbuDnddf~h#NdbGf>{e8 zXEI$fPmfYOI^Fi3%TVmR1KoLM_r&019*$coWFlA-7|U*U@UVx-lCB z=#z<)0Gz}cKqW+LX>N(yNv)7H!?k@h#xZjr2sFasjGar5Q+JFFa3Qz~OS)@1nNTd+ zo77!XSkauxGnumj;7Dq2Ej$!n6OWBe5R~alOm(HfJrPGEVKf!wCu?Y~N{5I*g-*v? zD1iwbSPnZfy%FLN5A|5bsVj$#=r%%@0_b~HyBbi_4`pDz15q3*ZCXpy&Q$bE3z}hmjM=J>@hu!FZBu0r<9wfYs z%pzb(FEQnaTG-u@jD*<4EeKHrNAP)^8X%COD*iGlBCe%+59~(qLWtefeJseqT;J)P zh!zi0f`{2K`AN9wGJ#-)!}+_gNqYIUU)2A4BTcV+@`)!N{qV_$9-Ym6owQT^Q}%{K zNLkHVsDTtMIhEgUXH?~F=#1$GhAdmzS_*g<-|&^8f6JT?U!--IyWWPL65lA(sX-sW0a5Yn@-%B&SBM}R8G}h>z6BG$-P@sU}=)ws#$aK9RM~zL8 zqw*%m%XOr2YjqJPmKUu&a=k$-66EMX0{1#vJ<}`jv>U26H!kv5L4#_L1;Pl5C?pl5 zULmT~gOao=Xa6SGXq*!Qo&~aJdMq;y-eoM)d*}nMS=5&4!v!FI^&5Onxr*eRNalIz z?Be|Spu}HS7e9Ih$LZ@(pZ*insUlSv@lx;ZbFxRtZbL)Stza;~Ta7gsk1L0dc!zrj z2Pzo+$ZLzd$XIP|7PHsorqh)pUXX4Cnd{5F{m;Qc>!i8r$YqLNN4(yYZW%j_jhT~& zKu??A8cyn4*f9&Sv-ecTOzf^Et)BWN3`RZ7;t>wLNbtoyp893}9C}6n46@LTAcZFk zziaiD&R5#5uQnS&L1)brzBedCq0K02ZPOmY5|Wy#fX#De)xTpwH+ga8Rlmxke~u!^ zH$4#4px8#B77n~%EJ>D3fC_ME%^1X~kr0l&I>obE5oD8hDp7$@84~23&Gv?;ehtT= z|L(u$y)W|ONQ^$Je}gmCG6;r{OA4n*Ybx}|AbD7wEK=4p$5~SUnZ@t$=3!i417iU? z@^5)kMjj3NGS88l*Bc^TW1JBxbNi~_VnKy7%uF&_(o6P9{U!_90uu%hB7*%EcS02v zQU}V=z!Wpw5A^GyK88D^jL4g@%w)Nk-Y*W1WAH~U!8JGoa|id#489Ba9#79?N^ln* z7XwI6+=&n3cPZ1m^F8;JMM*?Z{0O`M0uI37iZOFL`!-mAu-S8Te8l%*y6n*f?{ldY zF!N6Cv&C(oB)N7TE|W+DNMBW=vOZbGeEr8U%q!y22EG8E={mWCg={fTQpFngG!Mzz zj&MHFvXEyn45oEli_RU5l(mLWdh0nTbTy5cO9E$Pb+)7p1RQOF4w4p%O4Lwm@Q!>) z*zu5ET6R6j`iyI~4P!A4t0J70cWV6(_P5M|;R-br3!AfOAM0O_TxsA?=$#G|T_m_f zOqt;+qiN-?1)~z0lsUP!SF!GZhSf#I9&wnaKOrY(0yFW90aci7j%=F_`>#inLKB0q z7$(#~k2zFeLq`Q8g1LkcLNFLnb9#D>;)_$1X3?!jgIRsdZXMCL^~!0mXs4HK z9$MkPB%5$tQUBhY$wKdpNh%VXMNC%=+Xx>i5w}cwa6&BYqyx)qphLy*w(+XX0si?FE|`a_g_CDbn0`|^C~ zwk0}Y@u1LZ;SdD@%m>UJ)a0%iVr2aSNHkh)#snKHzY#<2xM08R+ zu&L@qC|=N)O&9_70PYWUSwGCSis2B%;DE&4VXw4DoMZ+@+S*1<6rMrGUmoPszk+7| zn9xJpdnymeDUj;Xp`QkP(6@B&P#lH^{p&2z%Hn>i0tJc)PLhK=UH>vpz6f5n62nX4 zZbK9T#T$%ZSlpN-8>%pv;Ae9~q}SM*LNP{`Pzz@v3Q}Ecc!|&ld>A{KUS_TTSPGHt zZWcXA^cWOmTa7z_6?M;$x+p}BKrhI45P!1mksg6XxhCs?_2@HrTwoS`hMA$UN!^|y zLG_kxDD0xxd}GM=s!0n3O92DEjIRS5h{j4Ol9_TOg*hK-Z z)~jtIk65<`kqp8Zn-6{7ghy?$7TleYXrl&WmEsH!&g@u?w^>H?Ag6af>ZLNo<>VrD zI2yB}b4Mm|dh%wA)42hy4-_R5>nJfM4iJWY1ZEbOPG~Mc5D`_&60>$2vMy(>{{6rW zm*|NQ+r8R#*fIdvz2MTo^oZJknz_(sMbsL%)|;JK_YkWbV<7ZuL`YXSmT>!mjWGGL z7LBecrdiY6AyhnqMh1Kn$OMFX%3T~H7~M(-KD$A%J*iq^$KW2-inft(Q6`@i2Z>!2 z+n(wLZ1kZyMyu}XZz4^d7(Wfui}{rp3z#@H z0g&V`u|Ao3vCpzBnuMZbtqf~sW^}>4r(!9hlvqYPG4H{%8O$l^8zX%Z)VSz@ac}`V z?6QVo#GB3!rWYIF5`va}Hkz`y)FSF=y5J73t@l3<5LbW7A`f~Kl!XqP*$p`<*^z(3 zI^33n+ptXOH=MEAEH+^YwNeu_&yytf_Q%O!yt3VNM0LaXoWsX3QXXDu0h37P9Z5z` zH4@NS_Qqw&pZ~&k4s2A;2OFgx6m+JIDCcDpg0aH3%pncDuv7`ZB*d%o-)pHi?s^rU zS7dt=ol4H+T>UyG;gzn!J{yQ)vm;y*Mj6rkv_Mxno9$&Pn?d_R1-4y+D3co#wllX2 z78mOV0OuB?K><6~zMsH0z^p-{RJAP$AQ2kCl0YyBpR^13#b9|i0pa1@ESv8OiyktG zVdubU=9>UX+j&AFU(`YT@LnLz*(C#p3tW}i|2c5u#s39(#V51U_4C<-w4R=M2OIE`>4+sXal^a;J8TJIV1_t~I zuAQKzVa=iE(!IljXldtdcFDM0mMb`pA6O{FdIBXuO|*f`M(e_BVexo{8gDF=lfEq+ zRBv-vMxbuI-9iaXZ0VZ58>dGd>=8Fuya#bNgdvXNbFv$PF*}FC5Cp?w{};U0;<`xz%T$oKS&K4FHMD4z?ctPrB7cT6);SAG02%Oe}QZ3X7*Mf4b_69-^ z%oU`IKstk3tvZbNF*wWJ8wl_J3`U}EvN+A+k6HX57Q{DIyaNKc+^lz@PBNkHgetQbWiicyp680%9eGoQ@_9s6hU&98!s0toFz*2j zEy~|gdwGst@;WZzukh$gEPjy153xAL;>TFrV(~Xve3ixDVj*sVKf@z}pZdov{(!~r zviJ%M%aCZaK#ZV9SP%j=j*m9J9EnQj!?^keKHm4DC~oBnxh($W@JXY@cLr+a5B9J8 zSaGO0jQi|ArjaTifqE!koG6Z_(xtmf2yiR!DdtKOrDCaE8ZH*0-$|G6FP$WlQTk-* zj?zrAT;79PGx!|LWXhwZqP&-(fezZgNgO?kkH-m!zhcA9xp}wX4!K1auhnqzS`AlT ztKop%amVSm;^bE*={|_pKj1|h&T+a6%4;E}@T=sE$jcdp~?V_Tu}1Gvn;T_d&e6V!v|$?cU*>a1J_m;OLNZ(mCYZi6gw0!@0}3 zTUxx^t$^y>Bgc3@p>r?pK8$nsIY;E&y*R$#IV#8ZImet?TtDIvGtLRVum3ymCGm-jTsZ4m0^t=m<}Ms-Kv-DGEJ;Q*mR-`w@-VL( zsnqb3^RTO7x(wqPPL&?;3IbBKfQsRR0fD{~k|5QP&31be?(Qvme8UnCUBqA(pk*eul+JL# zM&EAz-WQYO0;oZb6~FwDZ;j6#vdKUd#Nk0Tmq=0|YY3+Wopc*MK(XnE?@O3|M9<6y z)Jgzi%!VFmS0Tb6zF^XtOd^0E*moHtglnaK{fa08wOJ=zm8jcROBn06w8rJ(o`FJ+ z+#bv>bkht&E$KrUHU>x5a8`~TeE~V*yOmFUN?5|m_Vzu-g*AS|oEE5$k;pxD^u_L4 zrvmo$=q!C+H%$xS*?W#kZ>$3++rgeetP~y__Fzt*+0mff$~!u+Y#h^-KJZiG_n1C} z8th~3u1y6j8V+RG^!(Y=QjHwz+??jEuKL}Li)5H3nKG{k1G2bqp+SnuKa$9O_?*MX zJC6dKJQzi&)4?k=H;Ad5Gfd#NPH8~W83A49 zv??9^h$4rEV4-Kww6JqMzCzU(>NvYsjge9cJNFtYd~VDvLE1 z8!XPSh-k2o-*3mc@5y4w<2Xo7Wk4|XKM6;*Z}&u!Mah?CW7){7kaLmgVw@wz9OygK zKafEzAw{0NY!%3 z(AaLGc81RoYiaeI#%-|;&7Hdgi|=5lGZ0W0r-B1bDi7E$D#xbXRYGhR25F`;ymoK!p4+G`?IfxhRI+Iw~rDkB{l zcE^71j$AZv!H99rkasi&E9VM0%E{3X{h*L}H{;~x_ptmfaaTA6 z>gDl0Wc2gJ1)abE9=R|<=oh~PIofp?c!{(Y+5$%KsZQ2vVpg*%4S?f_dJC5nx2}GJ zoJ^1CLw=O!kXZ@|cG(^>$kOa5t|`cQr>7wpsl}dxmwHp2i~#lyoX`N99yE-|D*Xzl zS#&CZO5zI9s=!|a`C0LyJ+`;sPXE9zu|{gnei5IK;^Pr*QE}4Gd;to>t!c`bl*=KN zQ#%jaiR3zAsLpAv4D|E23b9ZfywwnvksPFVt;uH|HDN$QEqp`A&=5E5;JgH5ED_E` zXBKjT5fwQL-i|r8>+&6YcLj48!s)<7=73kx$;FJ?5GELV#%=^*uH;p$>JTz8FH)_=*qdB)fh(7UDueW@)b>=GQt*BMt3g$@DW3y-3b(htU z_vlFGDoj{do3jYn2%h1)Os1K^0csceCJ9jJyjkIEJkT>3aCKhjxa&zWN@@UxOfoIA zf`%>BX{3+s3QteMaS&P6kzJ#M7fiRdV(`^_Lf|Cq4`>M4_sFbc&5_3KkNQjP)XEGE zQ_zoJ42`?4Gf$uHFv8kG!2rDs%6buWhyQ>8AXESr+ks`*H4=+Ysws<4{s%Y+T0xD6 zBo}46_X%xTzW}CW%IHvvuABt6iE&~|<3;$%oWtsV5R7WFmqmN&2-YgdL!^fyN3d^_%@T;jD}{}KP$W{F5u`c> zEp2Zigx|R^NZJD5`=HjIcNVfZu}JuGJYoWCn=o4o>!UZIfRaJK*oOcCy9gm7g+8NJ~)_d2^lBd7aaI#gg&y0ul~4k!CJvbdPM_#$4~% zsE{b!hmaV%bue7jNMm*>$lXXZIyW`%H4F}(3OlONgP=FYc{G+>fNuV_8Po{|2eg_zp`kwKU!08%6@lM%px0}&2I zSQ6o|$y^J299r7BfwT!=8!I+Io8<1h2?MgmMerii778d)n+dW~39C`I77(Crf*>G> z+DLNDAd963N=|UNnm-Zp#Q8W)&DH58&G5(dSi*t~ID=64B=Z^auSVCX;lX0sI4m$E zg=#>&^9Nd4yKr$mTLXxhicqL)vQkN^G(t*K6Wk{>3TrOA;3(3-^JR7?LWTB=uAu=TggdABrt> ztU_X;Sy2{xC+FGw#@T4o+Kd&{aq`tQglUt5G~At-AE-$H%dt6#STv|_p-siD)bV0_ z8G0AKzTLQ)+W1Dyr)>tIbkMwqm^n5Syvk2rlz9m+lV$V^jxFCoyH9sivowwim<<>4Fb-%V6_37g zZ7t=_y$!sMH{rmySbK@W2&oPeX`Do1OrpE#fr2U64}Hk$5*=y)>?!t;G=d&;h+u-p zs_o}4)ooAlC=ql7+;~5FmbxuT8YL?z_ml-C>^8lQLM;F;_%9$Ls1olZXTDzTpJmtA z-i(aE@_H_EX}C`|J#IFMBFGsrno?`gA(nd)9YQcVT8_(-k#884Jpy1R01mH@a8*o< z5xsUo1OBNaFyk~7^80qXNJVgD`;k*P1tC$NJ+gi3;h5NB^x4P!IX&_y!@yD0v!j&9 zm@0F+VNsSNMTD&*I`Zfjw_9XKz>lOnL~jne2RLC?cGIXyvJpN&NZCDwd_nj3yoKDc zm^`4bS+hRsMBsW1KW-e>9EQB+V_Lr>hQWW=pswzN(7aJbfFF7KOix|WW`04nI=dp1 zAjG_>7zz@d7yyruD{`XjKY%hc7QGuDcW@#i;;W+)GW7hWun3!bh4Wzcwxm)R4Z#jR zCLOmrELL|O4$$FXKerOZau_0!Nt%3v+|lVS+6|TC8xIiFaF5+k?{?4byNX`rvj3TG zYm6Cp?H^hS>Hicy9;t zy->4bn<644R=J9gS3$9gW-E z+=6()j*mne5`mHlGII|`Q6PFbX|ec5=?vY8XdQTZl>_FZ3#r~wJJ?9M8IM5;@A*dh ze&F1DFA)%6Vdy|n?RSu}jq$ZJ!2cb2?b14a zZDXcU2eGyE1fL-u&Mx$Zb=t4fM{e|n&KzO9=F?z6$#w>rrUMl*4C(6A_^FU&!jcYQ zOOsL?Z5ONzd$QIUNa!hfKiHiH>32K7VG|6I$1(mjcCRY`ztYJ%m zmCn-~h@!1S-N}L$0Chi$V=R7>&pN>3L;NXRI0>erN=|#L5G$%_77wyG#e(}lR!^Pb zQ8X=bBqpz)N26O!-FyX*Wk|+q?5fZ!%R@CTwZPsqBwd5-isge~mui1CdeU0815_~W>**Q+s3n-AU zkU_qBzOXJ3Eq@&;L{PFV5#sD#PtI7PZ?$`l#r|RI$wZTGJ)v5&9f0{ zwMtXGLlgOKLhH3wm_`zBJz|3_5A?EOZVjQ9ta_Lw9XxaP@9jc0JcDRn(P9&S%P`$6Q;`gJdj>PYe;9Nl5 zM};l!eA)q1Le`2%RmwQsNDJ|j2s+X0^Uy2#<2ON9R)h_NFY94C9b#_2JMBK4*J}J{ zQ2$+c6JVh=zul_UzJq-sqE7Ahd|k&PQ$C+{<@qHXgglCVHe73QPQAxt;jISQ*b9zfTG0`)8}oMrK@2$5KZNvFiywwTXlO66jb=90BbPN+~k54Ek(;tKAeHc#HKD;qD4 zrl2}SMuGZF-#V)(|`?wzXV8?*@xFcjf=Iy9< z?pso4e#D${9tUJXZVC5A!zyDj@R}Q*lb|Q2R6=${gt8vMOCyL$)w6itQ_e5Kd;M95 z=g6mJ79;^0EO*ZlOoR@fL*wcw3!*YDWuN2G^E`J4iXE0a!CAXXxj+)sA=PR>$RUgA z4#@?=gaYp}bbZGHUdHjRfPbDHie^@h1UV8azr<&Wc_f$16mtTp2~g)sKZ}od3B|6U zK4pA3B?Y9=Zt>j&?VgrAVd-ko+2f4k%CIxxOyavF9+Z34EP7TS0UVu;XpOeqRJ0lo zkn7_$H-E2cAa<#6-vNuH7mM|6Q?wAW2H@EyIq9nx*A<{P7?lv1* zOA`x$>H1LaXpK45LmJ=*^}NsyZfJ3Sv!mMw{}FrZJJ<#oXQ&;}O2Md>-MMtHq)4OX z!f4=B2qf*r6okZRW1amVJL#v2KGBNEq6n^loa+&XZ>@jy1mbiMHcJBx*cMs2}_Ol(On6S|>iy&21sqTK=;cq0Ka-M-nZS6;dL{6#ZK zD|m4uqdT-YNK96C$_j-X~tO6J#h$ zkj3Q~{9C@@rwID^Xv|`%%2hEPTCB1lsnFr}U>P-PrAd&uGrTXNKvL=)NHgRcAdF*3 z){z0*cF@UwUgG5)ykrhiP9FJ!7UkNodcnN0fWFU&W2JPto$mnkz+()|okPU4EKHuf z-?X#;#!NpCv*Z{&$I^(7Es(`~V@bkJd%WwKCC!bKi zja6Jsut20A4|9R(-~$PMl1j^4$Q6O)gks@+BNIYkTK!kl0kl0%MEiL;Mku}+8FKtc zJ~j=31io(!pCQfy0ekwF34#RjT&j0}I5Y!*?08IW4{tGfoT%FIz*z{PIe`|`KVxy7 z#U=LRU-IbJP@s~+SCCoRP#1ZH78ALGcVwH`DS2UITe^sGM77vmWS&A#ewID0;AaYP z1q@MUnS%|qh{QKME<>cAq$Skq2V&!}Q;SDO+$G~_EK3b7K#iHV@HThz`oufWH$6H= z3k(~?Yd7~CLRj*OTQJDcF;>l^=^zj1%o}(&n6BnJyR+l!0_y%c2ZRrh40OlVVL0rx zesqLPtm-gyC1~JI?=2Losci^mh+&7Aww=4NzV+aZMNL1+Q!8f_~O}m7t~5&NG?M%`{yK;5P@P_Z@g2GN1OwI5UocEy-%f zTCF0)Ym%7$7;jzu7#CUQWHjOPD>6g)>aJ(e{UD3UsumjZ;&P-R1AdN@DMdgF9eg;c zQ83SMTA% zkpm8{2A+uP6RMWH=)Vn66quI(g;;FxJk$?krVJ`TW5jk z?bY|f*Qo~>L#E+i#n?Ie%p zSUkYuK^70OIK_e_T5|8H$9VKdES_O;mc<1YFR`FHUVV}UQMN>}>3Cfc`G0}uxb_m8 zup8V2#WPw7_B8b{qA+FjH2;kwe)@$1%QB9q)B7{WGLICBxm>mgg(&`&i>2b|__wE` Re`EO7!>bP~<5MVK{=cda)Q|uG literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/exceptions.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e57f4567b78a98b5544075eb9daac1bb83cc9fa4 GIT binary patch literal 5023 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 V$!e~ev&_oP>ZQ`x;4+ba{|}AZ8bJU6 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/filters.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/filters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b9ac96d9d401283e422a34937419ab8d4c176a4 GIT binary patch literal 34389 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/idtracking.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/idtracking.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7547493cd3abb14d58222902306a23bd10b95cbb GIT binary patch literal 9959 zcmb_i&5u)Ac7I>CpIt6v3=~k%;Gtn=YBF7!?sO)d5g}AVF-?cAZUGG$Pi0;k-)G9k zWmnzz3JS}W#emcuDU(GuQAV=>DT_qPB8&M0vdSh>q->v*&15x;C{h+tltq-^@7(8S z*H;5kT-?uh?|bK*d%iCp&d!!B{C;^n{_(%PZCU@y!T9H)a}_1pK&32Y_pEihVcYCG zJ!jo*xahkLPkD`;$~E#T-zcb>@>TJ<-SE{hRZ=tP6@O@{vYLHvsoAjf%x%nITv10b zJ`&m(mocuYqZl8R@vJJ`u@;X18eg>*>||zTpu&5ds1pw~hQ&@CYLxXT$!#=sb3G~O zFdFn8he@v4>olWAajUPwcBdbzm6pSo;Fm)oKG#s9MO3jhvX%Wad&i0Gk@L*nakuA2 z)^+QTDm&iDec_C}m%w!M)O~B@02*fnpU&fZVLx7Qlfs>+>kkIKD5>251fdzFFebUj z1a={p-D^Ks{X7bFw7R@PBbdolZZBo4wvUz0I|_`SjiP>c^daxB1>`*EAg!>t^dw zr~hzq<7rX`G1U0;Go*kVx?Qq;l!~oun9E4zV!$G#I)%=JR3qnwJ+ercj3~N*6$_5` z(In+&zu9{_3*MIPI2`{7 z)>V{f8&zmEY-KeZbyhjb1)sUfQ@Q6B`0*{3R|U-EgcmJvCOOdpcM2bZH--NiMZIB-dno}py&Z<-DG}?-qS7*>3Q8swtoFKc>A~gK5C7)eGiLRp>Im&wE z>pD1$?VJLa^-CkW3%NOI?KmT6WCh?q)ON>0?MUs$-ZPGJ%EDLN6>Z~Pzh2cMDA5 z+j*yC=hMGo)$nt)I9{Cb21SVI{sBrfj|#kDQFumf*B;qzh|-^lf&c>c%7T;3+#U?# zR4_ETZo$+1w6I2!fAplOA4a;uncdu>$qe5@iTF(dIXpfFYnsclQy7CLr$7l;pl=sc zZaZ@p0mKL(UN)yw)ZgJLbe)ll8CN8HSm*_pRB#DoG_*U3w`fX03N&OD!k%~}e3I)Z z=z={^Co_RjJpqpBH?T96v`Q*#!((F{rq*TDB@>al846^PuJtIdj~i4@gE5E(*op|C z2SsJS1XBvjfa0#eYuKbHVozWppCo#ck3sHmFVOmJJbMo%q7WO|E7`-NV^Fi#{Qm+f z)TQ=FeE9+>mcpseV|EW^^(D-GfU+CNj8(_4$Y3NPGh$xAU}U`jH@t)_rt*0%h6Nbe zb70_~f^iKG+`Owhp{mD&dTLeb%{ot=Gfm93LzsXThHK5Z{-hbzxB8FzgC~7HkJrL_ zoA#jo?Mr$A$PnhFvJ^q1$DKicS!RiZAV`Wq(CRg#2wmt9)oDS8B>Alk)r2|bQ6^q%u<_KeA2q}HEGff#aMTpf zWt51v!LrM+L1p|**d%UKDZ$g|R-UXTS0$BuOSgktpDtYw zmTui#x|7th@#ibomv7u$S-w7fTlbcyX|FF5(>->kj=2^}=6FEXGA^X@%wR2I6}=PT!v8|216#g*d1S+D zd>{VfB8(tC$cykGDRxxc-`t!Nr^!?HONZ7UR>!++ZO+}dHcR)d?eEL(#T|;I^THkF zD7xTjtLw?gOGlQB#P!Z6<9KBY2t+(pzo1 ziHLp~`^ptPXLXArBfr8ois>qUP4o#6VR$rJ z8*KGdy+4TSYt4;~u)k1FWrns!)ciYGXjB6aJaKzr-yGUE`G7`1e~;B~qgp76f^1YC z=w`pQHuhW1EAwX3oTNCFWXwi6UE3OL_2Wj_h}eO~E}2c28r8Li-O+bYS+)loT}E;2 zvv7tg_^UZJ%s7~s)FaVoCMS)d55W`c{SGO;Y9ATAt zaZGF|uX!AqJ%Xl&I&(q#c?KR`XU8F%jP1Xh#}i8gkoM8}G=eUO;WsIB#lz<7v1 z#jaGlcqzuzE-?3*XEL=q!-;I4;q(~>vGr_>)zuWMkGH>zPzr1;Y7saGZ7+7g zmi3Vhl`OVsvo6@>fL(clU0$EYn>9Ja@XBwoC)!Dn%^SlxL6+hSKMbLePV8WhU?(*} zL{w8?SRwjTY)G-s3-+hvOo9FU_)Pb2f-OMsx3W;B;iD@6!&eG|^?};zv0n~?&8=q7 zJke(fGksUlN8(x;PN#Ac!>8$L>GxUHS^X}nAF%p8RulCkJw{3rZ;&?Pa{ErH?0cnx zpT}Rp_x+mh`8j{yFUdOUvg}7%UPXzzsIq{`Rt|z0S0P|R>xG_YHF79G3Bd5C&g}W*^?Z%26~14@@=>S zo%PTJUa9?{ootktb4p)E!PN{c6OVbty%JG02XkYf{|;+J1v4E{Lot6epB3A4=pGDD z>^~*!%or+%S7f4m8H2B5D0$`z1?f*R*cX3r^WsFzy`+#Dw<&6n5DPhDF2yYn6fa`- zK$$NY4DWa1wZF%jG{P?1Rrox^x%~)nVTKX0p_%!VJDIVInR&6hb{BaUa)M}5XJt5l zt=XrK$Vk1Os`NU~6tS|K99tR0H>o4nkyQzmoS0??MPETRc65kL;z`a(P?{J^$tcb~ z4Esn9w~U_s2P{q%m$ygH?pg+) z!6(g@9wey(z0v8xZ0ve2GM)Hl=goHGyy?lbT7KN@T^j)P?f8>{>a;td);}Z+AG4wu z>)WjEvbxV|g1hv@B+}~s1&U<$e8+eF{8Ow4V3pwTs$+|DX^V>j@ z;)}(M8Fx7vC7{IQK#&=8TYreTaY)Pl6csa{;-4@-_9@Qn&+lih#f?ncj%7f!El+6V zL>0&YBmo-qTq?WJv(%D(YFK1~@#F(}f;>g~(!Bj zfoZ0gL`*u-?~LjXnSIiOt%qx9J5jy8)o(H7w5SQ2aXIVgtss@`w&HCegmFS8WDuW} z3#KJa-@=6WHG9aEq#9!d-~MN;F?k%P0*!%KiP6Mc2hh#1JNIPgMfPJ6!qw0L+Qy(r z7@Rp_2HZLpNN#W()K7HVL>NR7q~f`9=XTgmuxosr=MD#pOEb6_Z%|dwaPLo0eT8@p zhk*?DR~9qe7(0Jre`$Sbf9bScx;4*z6U%iGX7dUOt3C8`(#vgJXZXF7=e`$tqz7`N z{6k>}!O>gELM@VmXT}&JVwCWeO)u5MCj%t)U=!&0)pi`d3c0Klpv~j=v65>h!Qvuz z8_H1>Ks2JG89y}&(bj|Xl7@;jsSb4KVF$N2S-34(`b@JVGo3zEt5K}K!j7rLb`AFi z!|xqR*_-Xf%kU$cz32)gHhYP%6l^#_6KicCrRi$GhIiV5rb&_T2+Oid1H+F^E-TZ) z9Ru7b%cj(@a0EACI&uL1Vl%$rTjg~k@v9jA3yQ=g79#z;Q!ViNsp1R|lK!#!&Uod` zcvu9DBKImD)<43ceENS@V8Ji+1Q9!(i zjjsYRDW}9(-x%olKd@sG)|@{ST3C6k&cG$FQ`AHS(Aez;ml?7yBZlwpxX1yzvHQ%? z-^Uv71w>2Pr%g@_ceiGS8kX6$)a#HG)k0pd!+k7uWm3ZREU!2b%V`+VrwQ5Od{2s;oFB&V6rcx!Y(Ev?F|*EaLkojI)=QbS8Pnx zJHv0?<6ZMEo6x~s1TG?41Fc~k>jSMqy~vv(ku*`6Z*sUM68s+`$fL5Hsy#gXaLww2 z(V}y>7cIF^b%vXQ2Cl2?2n05wI__3z=N~Zsj27$lj|NY0{iy{pnXE_Q<`yqvO7-*y zqbH|=%NyLvAngOx+pr@X!Kg)i|;d}%Ny-MiBAuMK~*ux8lg0erJeM5kfd|TYuSHjc);N>ZpE*=WglwX{2 z3HgdeQ~-r;TO1(>eT9h`lNW_pPh~fpBoBvqD~t}#!b^x6P`Z=JoB#w&+F0W8`t4d zBT5xrQt$NPVGm47#%Pe&CKQ?Zttr4R9V!yjSscWoH;_HOg3XgSl((>I&ZmEb! zvWDUz-JC<(*_FP>R@O5=j(?R##ry}PMIj$75Pg?yGH4CfH=41@@Jn)^_dVw3=Uw({ vtf(jT0xO>tLt6R9R1A^UD6M@NOpO(fj_t8m-5v=uD<`jm(4=M literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/lexer.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/lexer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c1488864dfdbbfe055b9d988c820a6b23baa063 GIT binary patch literal 18516 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/meta.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/meta.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b492b18f709a7663e49f9ac7fa8de9f0d9a026a GIT binary patch literal 3672 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/optimizer.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/optimizer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e71613138988ecf696f1ab2d3aad84b7eb46692 GIT binary patch literal 2039 zcmZuyPj4GV6yI5IY{!k$QVQjO&`2D>618YAMNx&CKWznS-AV}vHWsVN?l_rrcV{~@ zPU6Vr(q8!v?U6etK8mlL_zIl(y;-lRDkgf9H}l@Seed`Fc&Fd*1z3OFaEE`kgWxYZ zG%EsgA7sD5mIZN;u`JA45yl}SzLmF%D2~8K+1l$MUV9W|?X2@U$T~85)r#9$cRv`c zi^DJodK~Lim8as)P*+YB>QWki`RjYD=Wh>AWUbCu+FV(lPK}YJ%V*q~nJSOD(>&Fs zb)s~9qVtRkK9T2KUQ|X}t03~`M49nIXKI3nu)Mv0z*WhsT%?j)jXUAEa@?NiDQp}` zE`?Rnka>9~@~LnV@?q`Uj!ebW%9W)|OUp~`$P*`ESLC@D+EiEMq$(%c6vDwBPM*L8 z?^UXcO6B;>iLmskiSk1DqNnaFelB?`N-~`3mCYp_-k61oH*}8hhnzpu29b-R$|cXW zuK2VxI?u@k^0EBF@pEmSBfdI-S}ZfK3}Y0$w|64WB#;DN6G?dUWh6@gC^=T=Qy-9j zMUV+@B@oECodJdmWJnT5h{lIUZ+&C@sM*O^W*StA(9t z7i6zvbHSXwVlTsa_=e4cw+!XVE`Oo$D3$U8t}8^3EKq>RIdZ3YB@G!yDiH$`kv28z zlj2=G5~PcCQ?)g=j@6kghl6mj{!~(x-0;CyuK>^-viTy zyZ`L(ZjFDi(%A8X(T_j#+jqy?RkbIa7(dpj$j1k=sK%A5ZYgSsJinE{IB{ZjdouPI z-Wk^&I9?eZRK1DIJhi(D*b2SRBbH z!YBZ>K^;&Rv<~Wlu7EZ`eb6T8D(D*M1JHHQhoBpvk3b*CHxHw%g`9K@d9_L-rIW~~ zk=&dkc?l*IrEfG~rh_}c99fx9{K2DFZ|jgPx=Er+<&uQsWPN$C%j>JG3>)z%rJ!li ze@cP><_?&7@CM&~%U-hCr;eS5r>!}A6V1c7Y|c*C=D}$@W52=qD1fx{yl3vQfd1wv zvY&!1gs-j38+-4KFSIHZNEtq&pg-uX!)|o!EyoI>;T~TRF!=qddTILGfW7Z=xG~1HYUA&J^M5FX`sMt+xLD*v< z+hh^zv1{yd^FN$OjUfMo5G_R^lVs6L5=>fjIQWeuc`+4vEioG~WyoN>?&C!#>d~GutH)s2@Bvjr^Im4Lg#@D^|O>U#sq7 z4htij<0I*mlf^qn;hc$kOJ(#`ys>mj#yUGccB} zx?#7~>py1xb~NZLI!Ti0G)dxi-K}-HH|xXDo7curLHZu`@BZ&Ii|)NT5#Q3N^WTct K2HR+LJO2WlFF1+- literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/parser.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67d1407c20df4db7ad3d3478a81c21ba54c7275d GIT binary patch literal 25183 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 C`@5b1 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/runtime.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/runtime.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5bb3e1580ad7bb36efb25def25b8563e803476d2 GIT binary patch literal 24591 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/sandbox.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/sandbox.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2658276b55bbe140b1268a1a1e448fc69936edc8 GIT binary patch literal 13994 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 PA}w0xd2bf|_O$oEGXNh) literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/utils.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..049f03ef686351672f4e007feca701dab2502313 GIT binary patch literal 20792 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 literal 0 HcmV?d00001 diff --git a/Lib/site-packages/jinja2/__pycache__/visitor.cpython-37.pyc b/Lib/site-packages/jinja2/__pycache__/visitor.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b149b3a3e4b58412337b14a2b3e3db5f15701562 GIT binary patch literal 3355 zcma)9O>Z1U8t&@pnQ2e#5WW&XLMn1dGC~*Ou8`}xm}kz|8!(cdXF6GsoH6+>*2jF8+dOh z5ASu^+;-aj>_07zXFp2z#jVZ5$V6GH?bNqto|c{48AgVWQaOngk4EEIjZ~5uE_k(( z4^qvuq2fs@mDwyeZH4K0s-wMOw#9FRZGP*moA2=5sa^LkI+yP#G1{~TY{gNi5~H^G z2ix~HTff3Cr_Bnl19>66%pVtn+i2znI^}d3%y%X0)}$+IkDRV2Jz2*uOqNajHlz=8 z*NO`y>3(UZcok9}i1@%*UBs@*vRUN| zK2q5*m6c0BRhmmR5R*8wsy}_!nLu!%74P@2+hxJ^exJW?4+~>q3{S*J@pQ0=8}#2! z5!3#Tp8g|BVEnXi16rEI2bDqmD4oR83fhJEQuxXq>j&h^t{RHN2#FDj1TQ=sie#@e zFopYcB%@@{ilNNu@2M=P?CCGgf~=1QP~s`Ca&;UTq#)TVtd>^Nja5JMekV;-zilmq z{6y&}EYIjK1VYh?fmTssG9}<>DvOZPjGh`ARoh)O^AbAAa<=d6vn$Sto4L7@yV5{eNOxBzaOjRH_%;pP}E_LJ4s&)2kI)BBuj7pC-kt-6IA~HDCC~H(@Q+eFN zX*@CuNl)8G^1F>PYMpkiSPKH14?$4)K|o1?Q4`S+S*G#bGb$bw9;r|?%540fqY0dT z|LpEo?+c@}>3!I_|0TcqPVdfmd{1Pe_i>8i>Fub|xHpc*Z;*45PjAEzhnbk(9Q17c z-|Cg{)2qC-Ii405R?^@Vayoh6sjsuymCmw)H&<3IVpYdNiq|J-78!Hrv6HhW?8M7G z$qv@^)!fV3faUIg-Msd1w(aDIqLoo|FS6Oot0tcDV5i;G6tbcf1SPc~@79Ch z;Y7sqEDQpfhCyHhVAZfEtek4kCm(ByJn3aU?6*AE_x+}w4KcfTsIYIN8IJC+`2)Ue z7SE9WJ6a?LNHbDe{LKCqcOU}kk>$*25QU;-4uGxoXocp)7Jz{>^7|z#9D$u|h2PoU zv0Q{Yw(n=~tpsmd>*s?DYD+;n<5+|Md5z%+pld~>v0MO3iT20@6c-HQs#2LKsi@T=WRhAjl^5vB!ZUFI`n6s;hxBX62TDgj4^ft0-drNgNi%Os=fKyWKfIP) zp06{*yz#i6H=i(+?KO-W^YH^GZ{&4}JKcBgdnjppB1vvp$@LYkN@URx<1zg< zrHY9Oil(V3VeQY5pr~8f#Tv3Ju(zCUD^W+~&;S7`uev@>QQEAOu&rJKjx98E4V}ZD zV=d;PwJ`Flk;^XPubf$Tfu66PD;4Mxg z`{oX+Xj%HG=H*3>yk>A|;3mZ_$|e-uCQ%?IMcT|Gs;w?RmWNT2Dgln5Bn2l4Tu=!t zGrP=5+Saa>cy|Q~Yr1%>63!BU3s)bW^JUSpWgC$EPqDG29FJVuV6#`wJ8ikR({5Nm z*3Z$I&r|mTbrc)@8g)ywU*hhI`0ys0X`u7hfV-D9&5<>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__(self, directory=None, pattern='__jinja2_%s.cache'): + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self): + def _unsafe_dir(): + raise RuntimeError('Cannot determine safe temp directory. You ' + 'need to explicitly provide one.') + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == 'nt': + return tmpdir + if not hasattr(os, 'getuid'): + _unsafe_dir() + + dirname = '_jinja2-cache-%d' % os.getuid() + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if actual_dir_stat.st_uid != os.getuid() \ + or not stat.S_ISDIR(actual_dir_stat.st_mode) \ + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU: + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if actual_dir_stat.st_uid != os.getuid() \ + or not stat.S_ISDIR(actual_dir_stat.st_mode) \ + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU: + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket): + return path.join(self.directory, self.pattern % bucket.key) + + def load_bytecode(self, bucket): + f = open_if_exists(self._get_cache_filename(bucket), 'rb') + if f is not None: + try: + bucket.load_bytecode(f) + finally: + f.close() + + def dump_bytecode(self, bucket): + f = open(self._get_cache_filename(bucket), 'wb') + try: + bucket.write_bytecode(f) + finally: + f.close() + + def clear(self): + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + files = fnmatch.filter(listdir(self.directory), self.pattern % '*') + for filename in files: + try: + remove(path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `werkzeug `_.contrib.cache + - `python-memcached `_ + - `cmemcache `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only unicode. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__(self, client, prefix='jinja2/bytecode/', timeout=None, + ignore_memcache_errors=True): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket): + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + code = None + if code is not None: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket): + args = (self.prefix + bucket.key, bucket.bytecode_to_string()) + if self.timeout is not None: + args += (self.timeout,) + try: + self.client.set(*args) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/Lib/site-packages/jinja2/compiler.py b/Lib/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..d534a82 --- /dev/null +++ b/Lib/site-packages/jinja2/compiler.py @@ -0,0 +1,1721 @@ +# -*- coding: utf-8 -*- +""" + jinja2.compiler + ~~~~~~~~~~~~~~~ + + Compiles nodes into python code. + + :copyright: (c) 2017 by the Jinja Team. + :license: BSD, see LICENSE for more details. +""" +from itertools import chain +from copy import deepcopy +from keyword import iskeyword as is_python_keyword +from functools import update_wrapper +from jinja2 import nodes +from jinja2.nodes import EvalContext +from jinja2.visitor import NodeVisitor +from jinja2.optimizer import Optimizer +from jinja2.exceptions import TemplateAssertionError +from jinja2.utils import Markup, concat, escape +from jinja2._compat import range_type, text_type, string_types, \ + iteritems, NativeStringIO, imap, izip +from jinja2.idtracking import Symbols, VAR_LOAD_PARAMETER, \ + VAR_LOAD_RESOLVE, VAR_LOAD_ALIAS, VAR_LOAD_UNDEFINED + + +operators = { + 'eq': '==', + 'ne': '!=', + 'gt': '>', + 'gteq': '>=', + 'lt': '<', + 'lteq': '<=', + 'in': 'in', + 'notin': 'not in' +} + +# what method to iterate over items do we want to use for dict iteration +# in generated code? on 2.x let's go with iteritems, on 3.x with items +if hasattr(dict, 'iteritems'): + dict_item_iter = 'iteritems' +else: + dict_item_iter = 'items' + +code_features = ['division'] + +# does this python version support generator stops? (PEP 0479) +try: + exec('from __future__ import generator_stop') + code_features.append('generator_stop') +except SyntaxError: + pass + +# does this python version support yield from? +try: + exec('def f(): yield from x()') +except SyntaxError: + supports_yield_from = False +else: + supports_yield_from = True + + +def optimizeconst(f): + def new_func(self, node, frame, **kwargs): + # Only optimize if the frame is not volatile + if self.optimized and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + if new_node != node: + return self.visit(new_node, frame) + return f(self, node, frame, **kwargs) + return update_wrapper(new_func, f) + + +def generate(node, environment, name, filename, stream=None, + defer_init=False, optimized=True): + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError('Can\'t compile non template nodes') + generator = environment.code_generator_class(environment, name, filename, + stream, defer_init, + optimized) + generator.visit(node) + if stream is None: + return generator.stream.getvalue() + + +def has_safe_repr(value): + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + if type(value) in (bool, int, float, complex, range_type, Markup) + string_types: + return True + if type(value) in (tuple, list, set, frozenset): + for item in value: + if not has_safe_repr(item): + return False + return True + elif type(value) is dict: + for key, value in iteritems(value): + if not has_safe_repr(key): + return False + if not has_safe_repr(value): + return False + return True + return False + + +def find_undeclared(nodes, names): + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef(object): + + def __init__(self, node): + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame(object): + """Holds compile time information for us.""" + + def __init__(self, eval_ctx, parent=None, level=None): + self.eval_ctx = eval_ctx + self.symbols = Symbols(parent and parent.symbols or None, + level=level) + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = parent and parent.require_output_check + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer = None + + # the name of the block we're in, otherwise None. + self.block = parent and parent.block or None + + # the parent of this frame + self.parent = parent + + if parent is not None: + self.buffer = parent.buffer + + def copy(self): + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated=False): + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self): + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements. + """ + rv = self.copy() + rv.rootlevel = False + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self): + self.filters = set() + self.tests = set() + + def visit_Filter(self, node): + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node): + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node): + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names): + self.names = set(names) + self.undeclared = set() + + def visit_Name(self, node): + if node.ctx == 'load' and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node): + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + + def __init__(self, environment, name, filename, stream=None, + defer_init=False, optimized=True): + if stream is None: + stream = NativeStringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimized = optimized + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests = {} + self.filters = {} + + # the debug information + self.debug_info = [] + self._write_debug_info = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack = [] + + # Tracks parameter definition blocks + self._param_def_block = [] + + # Tracks the current context. + self._context_reference_stack = ['context'] + + # -- Various compilation helpers + + def fail(self, msg, lineno): + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self): + """Get a new unique identifier.""" + self._last_identifier += 1 + return 't_%d' % self._last_identifier + + def buffer(self, frame): + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline('%s = []' % frame.buffer) + + def return_buffer_contents(self, frame, force_unescaped=False): + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline('if context.eval_ctx.autoescape:') + self.indent() + self.writeline('return Markup(concat(%s))' % frame.buffer) + self.outdent() + self.writeline('else:') + self.indent() + self.writeline('return concat(%s)' % frame.buffer) + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline('return Markup(concat(%s))' % frame.buffer) + return + self.writeline('return concat(%s)' % frame.buffer) + + def indent(self): + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step=1): + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame, node=None): + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline('yield ', node) + else: + self.writeline('%s.append(' % frame.buffer, node) + + def end_write(self, frame): + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(')') + + def simple_write(self, s, frame, node=None): + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes, frame): + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline('pass') + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x): + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write('\n' * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, + self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(' ' * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline(self, x, node=None, extra=0): + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node=None, extra=0): + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature(self, node, frame, extra_kwargs=None): + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occour. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = False + for kwarg in chain((x.key for x in node.kwargs), extra_kwargs or ()): + if is_python_keyword(kwarg): + kwarg_workaround = True + break + + for arg in node.args: + self.write(', ') + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(', ') + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in iteritems(extra_kwargs): + self.write(', %s=%s' % (key, value)) + if node.dyn_args: + self.write(', *') + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(', **dict({') + else: + self.write(', **{') + for kwarg in node.kwargs: + self.write('%r: ' % kwarg.key) + self.visit(kwarg.value, frame) + self.write(', ') + if extra_kwargs is not None: + for key, value in iteritems(extra_kwargs): + self.write('%r: %s, ' % (key, value)) + if node.dyn_kwargs is not None: + self.write('}, **') + self.visit(node.dyn_kwargs, frame) + self.write(')') + else: + self.write('}') + + elif node.dyn_kwargs is not None: + self.write(', **') + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes): + """Pull all the dependencies.""" + visitor = DependencyFinderVisitor() + for node in nodes: + visitor.visit(node) + for dependency in 'filters', 'tests': + mapping = getattr(self, dependency) + for name in getattr(visitor, dependency): + if name not in mapping: + mapping[name] = self.temporary_identifier() + self.writeline('%s = environment.%s[%r]' % + (mapping[name], dependency, name)) + + def enter_frame(self, frame): + undefs = [] + for target, (action, param) in iteritems(frame.symbols.loads): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline('%s = %s(%r)' % + (target, self.get_resolve_func(), param)) + elif action == VAR_LOAD_ALIAS: + self.writeline('%s = %s' % (target, param)) + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError('unknown load instruction') + if undefs: + self.writeline('%s = missing' % ' = '.join(undefs)) + + def leave_frame(self, frame, with_python_scope=False): + if not with_python_scope: + undefs = [] + for target, _ in iteritems(frame.symbols.loads): + undefs.append(target) + if undefs: + self.writeline('%s = missing' % ' = '.join(undefs)) + + def func(self, name): + if self.environment.is_async: + return 'async def %s' % name + return 'def %s' % name + + def macro_body(self, node, frame): + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + for idx, arg in enumerate(node.args): + if arg.name == 'caller': + explicit_caller = idx + if arg.name in ('kwargs', 'varargs'): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ('caller', 'kwargs', 'varargs')) + + if 'caller' in undeclared: + # In older Jinja2 versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail('When defining macros or call blocks the ' + 'special "caller" argument must be omitted ' + 'or be given a default.', node.lineno) + else: + args.append(frame.symbols.declare_parameter('caller')) + macro_ref.accesses_caller = True + if 'kwargs' in undeclared and not 'kwargs' in skip_special_params: + args.append(frame.symbols.declare_parameter('kwargs')) + macro_ref.accesses_kwargs = True + if 'varargs' in undeclared and not 'varargs' in skip_special_params: + args.append(frame.symbols.declare_parameter('varargs')) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline('%s(%s):' % (self.func('macro'), ', '.join(args)), node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline('if %s is missing:' % ref) + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline('%s = undefined(%r, name=%r)' % ( + ref, + 'parameter %r was not provided' % arg.name, + arg.name)) + else: + self.writeline('%s = ' % ref) + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref, frame): + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ', '.join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, 'name', None) + if len(macro_ref.node.args) == 1: + arg_tuple += ',' + self.write('Macro(environment, macro, %r, (%s), %r, %r, %r, ' + 'context.eval_ctx.autoescape)' % + (name, arg_tuple, macro_ref.accesses_kwargs, + macro_ref.accesses_varargs, macro_ref.accesses_caller)) + + def position(self, node): + """Return a human readable position for the node.""" + rv = 'line %d' % node.lineno + if self.name is not None: + rv += ' in ' + repr(self.name) + return rv + + def dump_local_context(self, frame): + return '{%s}' % ', '.join( + '%r: %s' % (name, target) for name, target + in iteritems(frame.symbols.dump_stores())) + + def write_commons(self): + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline('resolve = context.resolve_or_missing') + self.writeline('undefined = environment.undefined') + self.writeline('if 0: yield None') + + def push_parameter_definitions(self, frame): + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self): + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target): + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target): + self._context_reference_stack.append(target) + + def pop_context_reference(self): + self._context_reference_stack.pop() + + def get_context_ref(self): + return self._context_reference_stack[-1] + + def get_resolve_func(self): + target = self._context_reference_stack[-1] + if target == 'context': + return 'resolve' + return '%s.resolve' % target + + def derive_context(self, frame): + return '%s.derived(%s)' % ( + self.get_context_ref(), + self.dump_local_context(frame), + ) + + def parameter_is_undeclared(self, target): + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self): + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame): + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if not frame.toplevel or not vars: + return + public_names = [x for x in vars if x[:1] != '_'] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + self.writeline('context.vars[%r] = %s' % (name, ref)) + else: + self.writeline('context.vars.update({') + for idx, name in enumerate(vars): + if idx: + self.write(', ') + ref = frame.symbols.ref(name) + self.write('%r: %s' % (name, ref)) + self.write('})') + if public_names: + if len(public_names) == 1: + self.writeline('context.exported_vars.add(%r)' % + public_names[0]) + else: + self.writeline('context.exported_vars.update((%s))' % + ', '.join(imap(repr, public_names))) + + # -- Statement Visitors + + def visit_Template(self, node, frame=None): + assert frame is None, 'no root frame allowed' + eval_ctx = EvalContext(self.environment, self.name) + + from jinja2.runtime import __all__ as exported + self.writeline('from __future__ import %s' % ', '.join(code_features)) + self.writeline('from jinja2.runtime import ' + ', '.join(exported)) + + if self.environment.is_async: + self.writeline('from jinja2.asyncsupport import auto_await, ' + 'auto_aiter, make_async_loop_context') + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = not self.defer_init and ', environment=environment' or '' + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail('block %r defined twice' % block.name, block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if '.' in imp: + module, obj = imp.rsplit('.', 1) + self.writeline('from %s import %s as %s' % + (module, obj, alias)) + else: + self.writeline('import %s as %s' % (imp, alias)) + + # add the load name + self.writeline('name = %r' % self.name) + + # generate the root render function. + self.writeline('%s(context, missing=missing%s):' % + (self.func('root'), envenv), extra=1) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if 'self' in find_undeclared(node.body, ('self',)): + ref = frame.symbols.declare_parameter('self') + self.writeline('%s = TemplateReference(context)' % ref) + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline('parent_template = None') + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline('if parent_template is not None:') + self.indent() + if supports_yield_from and not self.environment.is_async: + self.writeline('yield from parent_template.' + 'root_render_func(context)') + else: + self.writeline('%sfor event in parent_template.' + 'root_render_func(context):' % + (self.environment.is_async and 'async ' or '')) + self.indent() + self.writeline('yield event') + self.outdent() + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in iteritems(self.blocks): + self.writeline('%s(context, missing=missing%s):' % + (self.func('block_' + name), envenv), + block, 1) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + undeclared = find_undeclared(block.body, ('self', 'super')) + if 'self' in undeclared: + ref = block_frame.symbols.declare_parameter('self') + self.writeline('%s = TemplateReference(context)' % ref) + if 'super' in undeclared: + ref = block_frame.symbols.declare_parameter('super') + self.writeline('%s = context.super(%r, ' + 'block_%s)' % (ref, name, name)) + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + self.writeline('blocks = {%s}' % ', '.join('%r: block_%s' % (x, x) + for x in self.blocks), + extra=1) + + # add a function that returns the debug info + self.writeline('debug_info = %r' % '&'.join('%s=%s' % x for x + in self.debug_info)) + + def visit_Block(self, node, frame): + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline('if parent_template is None:') + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if supports_yield_from and not self.environment.is_async and \ + frame.buffer is None: + self.writeline('yield from context.blocks[%r][0](%s)' % ( + node.name, context), node) + else: + loop = self.environment.is_async and 'async for' or 'for' + self.writeline('%s event in context.blocks[%r][0](%s):' % ( + loop, node.name, context), node) + self.indent() + self.simple_write('event', frame) + self.outdent() + + self.outdent(level) + + def visit_Extends(self, node, frame): + """Calls the extender.""" + if not frame.toplevel: + self.fail('cannot use extend from a non top-level scope', + node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline('if parent_template is not None:') + self.indent() + self.writeline('raise TemplateRuntimeError(%r)' % + 'extended multiple times') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline('parent_template = environment.get_template(', node) + self.visit(node.template, frame) + self.write(', %r)' % self.name) + self.writeline('for name, parent_block in parent_template.' + 'blocks.%s():' % dict_item_iter) + self.indent() + self.writeline('context.blocks.setdefault(name, []).' + 'append(parent_block)') + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node, frame): + """Handles includes.""" + if node.ignore_missing: + self.writeline('try:') + self.indent() + + func_name = 'get_or_select_template' + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, string_types): + func_name = 'get_template' + elif isinstance(node.template.value, (tuple, list)): + func_name = 'select_template' + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = 'select_template' + + self.writeline('template = environment.%s(' % func_name, node) + self.visit(node.template, frame) + self.write(', %r)' % self.name) + if node.ignore_missing: + self.outdent() + self.writeline('except TemplateNotFound:') + self.indent() + self.writeline('pass') + self.outdent() + self.writeline('else:') + self.indent() + + skip_event_yield = False + if node.with_context: + loop = self.environment.is_async and 'async for' or 'for' + self.writeline('%s event in template.root_render_func(' + 'template.new_context(context.get_all(), True, ' + '%s)):' % (loop, self.dump_local_context(frame))) + elif self.environment.is_async: + self.writeline('for event in (await ' + 'template._get_default_module_async())' + '._body_stream:') + else: + if supports_yield_from: + self.writeline('yield from template._get_default_module()' + '._body_stream') + skip_event_yield = True + else: + self.writeline('for event in template._get_default_module()' + '._body_stream:') + + if not skip_event_yield: + self.indent() + self.simple_write('event', frame) + self.outdent() + + if node.ignore_missing: + self.outdent() + + def visit_Import(self, node, frame): + """Visit regular imports.""" + self.writeline('%s = ' % frame.symbols.ref(node.target), node) + if frame.toplevel: + self.write('context.vars[%r] = ' % node.target) + if self.environment.is_async: + self.write('await ') + self.write('environment.get_template(') + self.visit(node.template, frame) + self.write(', %r).' % self.name) + if node.with_context: + self.write('make_module%s(context.get_all(), True, %s)' + % (self.environment.is_async and '_async' or '', + self.dump_local_context(frame))) + elif self.environment.is_async: + self.write('_get_default_module_async()') + else: + self.write('_get_default_module()') + if frame.toplevel and not node.target.startswith('_'): + self.writeline('context.exported_vars.discard(%r)' % node.target) + + def visit_FromImport(self, node, frame): + """Visit named imports.""" + self.newline(node) + self.write('included_template = %senvironment.get_template(' + % (self.environment.is_async and 'await ' or '')) + self.visit(node.template, frame) + self.write(', %r).' % self.name) + if node.with_context: + self.write('make_module%s(context.get_all(), True, %s)' + % (self.environment.is_async and '_async' or '', + self.dump_local_context(frame))) + elif self.environment.is_async: + self.write('_get_default_module_async()') + else: + self.write('_get_default_module()') + + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline('%s = getattr(included_template, ' + '%r, missing)' % (frame.symbols.ref(alias), name)) + self.writeline('if %s is missing:' % frame.symbols.ref(alias)) + self.indent() + self.writeline('%s = undefined(%r %% ' + 'included_template.__name__, ' + 'name=%r)' % + (frame.symbols.ref(alias), + 'the template %%r (imported on %s) does ' + 'not export the requested name %s' % ( + self.position(node), + repr(name) + ), name)) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith('_'): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline('context.vars[%r] = %s' % + (name, frame.symbols.ref(name))) + else: + self.writeline('context.vars.update({%s})' % ', '.join( + '%r: %s' % (name, frame.symbols.ref(name)) for name in var_names + )) + if discarded_names: + if len(discarded_names) == 1: + self.writeline('context.exported_vars.discard(%r)' % + discarded_names[0]) + else: + self.writeline('context.exported_vars.difference_' + 'update((%s))' % ', '.join(imap(repr, discarded_names))) + + def visit_For(self, node, frame): + loop_frame = frame.inner() + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body. + extended_loop = node.recursive or 'loop' in \ + find_undeclared(node.iter_child_nodes( + only=('body',)), ('loop',)) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter('loop') + + loop_frame.symbols.analyze_node(node, for_branch='body') + if node.else_: + else_frame.symbols.analyze_node(node, for_branch='else') + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch='test') + self.writeline('%s(fiter):' % self.func(loop_filter_func), node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.environment.is_async and 'async for ' or 'for ') + self.visit(node.target, loop_frame) + self.write(' in ') + self.write(self.environment.is_async and 'auto_aiter(fiter)' or 'fiter') + self.write(':') + self.indent() + self.writeline('if ', node.test) + self.visit(node.test, test_frame) + self.write(':') + self.indent() + self.writeline('yield ') + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline('%s(reciter, loop_render_func, depth=0):' % + self.func('loop'), node) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline('%s = missing' % loop_ref) + + for name in node.find_all(nodes.Name): + if name.ctx == 'store' and name.name == 'loop': + self.fail('Can\'t assign to special loop variable ' + 'in for-loop target', name.lineno) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline('%s = 1' % iteration_indicator) + + self.writeline(self.environment.is_async and 'async for ' or 'for ', node) + self.visit(node.target, loop_frame) + if extended_loop: + if self.environment.is_async: + self.write(', %s in await make_async_loop_context(' % loop_ref) + else: + self.write(', %s in LoopContext(' % loop_ref) + else: + self.write(' in ') + + if node.test: + self.write('%s(' % loop_filter_func) + if node.recursive: + self.write('reciter') + else: + if self.environment.is_async and not extended_loop: + self.write('auto_aiter(') + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(')') + if node.test: + self.write(')') + + if node.recursive: + self.write(', undefined, loop_render_func, depth):') + else: + self.write(extended_loop and ', undefined):' or ':') + + self.indent() + self.enter_frame(loop_frame) + + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline('%s = 0' % iteration_indicator) + self.outdent() + self.leave_frame(loop_frame, with_python_scope=node.recursive + and not node.else_) + + if node.else_: + self.writeline('if %s:' % iteration_indicator) + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + if self.environment.is_async: + self.write('await ') + self.write('loop(') + if self.environment.is_async: + self.write('auto_aiter(') + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(')') + self.write(', loop)') + self.end_write(frame) + + def visit_If(self, node, frame): + if_frame = frame.soft() + self.writeline('if ', node) + self.visit(node.test, if_frame) + self.write(':') + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline('elif ', elif_) + self.visit(elif_.test, if_frame) + self.write(':') + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline('else:') + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node, frame): + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith('_'): + self.write('context.exported_vars.add(%r)' % node.name) + ref = frame.symbols.ref(node.name) + self.writeline('context.vars[%r] = ' % node.name) + self.write('%s = ' % frame.symbols.ref(node.name)) + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node, frame): + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline('caller = ') + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node, frame): + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node, frame): + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for idx, (target, expr) in enumerate(izip(node.targets, node.values)): + self.newline() + self.visit(target, with_frame) + self.write(' = ') + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node, frame): + self.newline(node) + self.visit(node.node, frame) + + def visit_Output(self, node, frame): + # if we have a known extends statement, we don't output anything + # if we are in a require_output_check section + if self.has_known_extends and frame.require_output_check: + return + + allow_constant_finalize = True + if self.environment.finalize: + func = self.environment.finalize + if getattr(func, 'contextfunction', False) or \ + getattr(func, 'evalcontextfunction', False): + allow_constant_finalize = False + elif getattr(func, 'environmentfunction', False): + finalize = lambda x: text_type( + self.environment.finalize(self.environment, x)) + else: + finalize = lambda x: text_type(self.environment.finalize(x)) + else: + finalize = text_type + + # if we are inside a frame that requires output checking, we do so + outdent_later = False + if frame.require_output_check: + self.writeline('if parent_template is None:') + self.indent() + outdent_later = True + + # try to evaluate as many chunks as possible into a static + # string at compile time. + body = [] + for child in node.nodes: + try: + if not allow_constant_finalize: + raise nodes.Impossible() + const = child.as_const(frame.eval_ctx) + except nodes.Impossible: + body.append(child) + continue + # the frame can't be volatile here, becaus otherwise the + # as_const() function would raise an Impossible exception + # at that point. + try: + if frame.eval_ctx.autoescape: + if hasattr(const, '__html__'): + const = const.__html__() + else: + const = escape(const) + const = finalize(const) + except Exception: + # if something goes wrong here we evaluate the node + # at runtime for easier debugging + body.append(child) + continue + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + # if we have less than 3 nodes or a buffer we yield or extend/append + if len(body) < 3 or frame.buffer is not None: + if frame.buffer is not None: + # for one item we append, for more we extend + if len(body) == 1: + self.writeline('%s.append(' % frame.buffer) + else: + self.writeline('%s.extend((' % frame.buffer) + self.indent() + for item in body: + if isinstance(item, list): + val = repr(concat(item)) + if frame.buffer is None: + self.writeline('yield ' + val) + else: + self.writeline(val + ',') + else: + if frame.buffer is None: + self.writeline('yield ', item) + else: + self.newline(item) + close = 1 + if frame.eval_ctx.volatile: + self.write('(escape if context.eval_ctx.autoescape' + ' else to_string)(') + elif frame.eval_ctx.autoescape: + self.write('escape(') + else: + self.write('to_string(') + if self.environment.finalize is not None: + self.write('environment.finalize(') + if getattr(self.environment.finalize, + "contextfunction", False): + self.write('context, ') + close += 1 + self.visit(item, frame) + self.write(')' * close) + if frame.buffer is not None: + self.write(',') + if frame.buffer is not None: + # close the open parentheses + self.outdent() + self.writeline(len(body) == 1 and ')' or '))') + + # otherwise we create a format string as this is faster in that case + else: + format = [] + arguments = [] + for item in body: + if isinstance(item, list): + format.append(concat(item).replace('%', '%%')) + else: + format.append('%s') + arguments.append(item) + self.writeline('yield ') + self.write(repr(concat(format)) + ' % (') + self.indent() + for argument in arguments: + self.newline(argument) + close = 0 + if frame.eval_ctx.volatile: + self.write('(escape if context.eval_ctx.autoescape else' + ' to_string)(') + close += 1 + elif frame.eval_ctx.autoescape: + self.write('escape(') + close += 1 + if self.environment.finalize is not None: + self.write('environment.finalize(') + if getattr(self.environment.finalize, + 'contextfunction', False): + self.write('context, ') + elif getattr(self.environment.finalize, + 'evalcontextfunction', False): + self.write('context.eval_ctx, ') + elif getattr(self.environment.finalize, + 'environmentfunction', False): + self.write('environment, ') + close += 1 + self.visit(argument, frame) + self.write(')' * close + ', ') + self.outdent() + self.writeline(')') + + if outdent_later: + self.outdent() + + def visit_Assign(self, node, frame): + self.push_assign_tracking() + self.newline(node) + self.visit(node.target, frame) + self.write(' = ') + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node, frame): + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(' = (Markup if context.eval_ctx.autoescape ' + 'else identity)(') + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write('concat(%s)' % block_frame.buffer) + self.write(')') + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node, frame): + if node.ctx == 'store' and frame.toplevel: + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == 'load': + load = frame.symbols.find_load(ref) + if not (load is not None and load[0] == VAR_LOAD_PARAMETER and \ + not self.parameter_is_undeclared(ref)): + self.write('(undefined(name=%r) if %s is missing else %s)' % + (node.name, ref, ref)) + return + + self.write(ref) + + def visit_NSRef(self, node, frame): + # NSRefs can only be used to store values; since they use the normal + # `foo.bar` notation they will be parsed as a normal attribute access + # when used anywhere but in a `set` context + ref = frame.symbols.ref(node.name) + self.writeline('if not isinstance(%s, Namespace):' % ref) + self.indent() + self.writeline('raise TemplateRuntimeError(%r)' % + 'cannot assign attribute on non-namespace object') + self.outdent() + self.writeline('%s[%r]' % (ref, node.attr)) + + def visit_Const(self, node, frame): + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node, frame): + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write('(Markup if context.eval_ctx.autoescape else identity)(%r)' + % node.data) + + def visit_Tuple(self, node, frame): + self.write('(') + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(', ') + self.visit(item, frame) + self.write(idx == 0 and ',)' or ')') + + def visit_List(self, node, frame): + self.write('[') + for idx, item in enumerate(node.items): + if idx: + self.write(', ') + self.visit(item, frame) + self.write(']') + + def visit_Dict(self, node, frame): + self.write('{') + for idx, item in enumerate(node.items): + if idx: + self.write(', ') + self.visit(item.key, frame) + self.write(': ') + self.visit(item.value, frame) + self.write('}') + + def binop(operator, interceptable=True): + @optimizeconst + def visitor(self, node, frame): + if self.environment.sandboxed and \ + operator in self.environment.intercepted_binops: + self.write('environment.call_binop(context, %r, ' % operator) + self.visit(node.left, frame) + self.write(', ') + self.visit(node.right, frame) + else: + self.write('(') + self.visit(node.left, frame) + self.write(' %s ' % operator) + self.visit(node.right, frame) + self.write(')') + return visitor + + def uaop(operator, interceptable=True): + @optimizeconst + def visitor(self, node, frame): + if self.environment.sandboxed and \ + operator in self.environment.intercepted_unops: + self.write('environment.call_unop(context, %r, ' % operator) + self.visit(node.node, frame) + else: + self.write('(' + operator) + self.visit(node.node, frame) + self.write(')') + return visitor + + visit_Add = binop('+') + visit_Sub = binop('-') + visit_Mul = binop('*') + visit_Div = binop('/') + visit_FloorDiv = binop('//') + visit_Pow = binop('**') + visit_Mod = binop('%') + visit_And = binop('and', interceptable=False) + visit_Or = binop('or', interceptable=False) + visit_Pos = uaop('+') + visit_Neg = uaop('-') + visit_Not = uaop('not ', interceptable=False) + del binop, uaop + + @optimizeconst + def visit_Concat(self, node, frame): + if frame.eval_ctx.volatile: + func_name = '(context.eval_ctx.volatile and' \ + ' markup_join or unicode_join)' + elif frame.eval_ctx.autoescape: + func_name = 'markup_join' + else: + func_name = 'unicode_join' + self.write('%s((' % func_name) + for arg in node.nodes: + self.visit(arg, frame) + self.write(', ') + self.write('))') + + @optimizeconst + def visit_Compare(self, node, frame): + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + + def visit_Operand(self, node, frame): + self.write(' %s ' % operators[node.op]) + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node, frame): + self.write('environment.getattr(') + self.visit(node.node, frame) + self.write(', %r)' % node.attr) + + @optimizeconst + def visit_Getitem(self, node, frame): + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write('[') + self.visit(node.arg, frame) + self.write(']') + else: + self.write('environment.getitem(') + self.visit(node.node, frame) + self.write(', ') + self.visit(node.arg, frame) + self.write(')') + + def visit_Slice(self, node, frame): + if node.start is not None: + self.visit(node.start, frame) + self.write(':') + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(':') + self.visit(node.step, frame) + + @optimizeconst + def visit_Filter(self, node, frame): + if self.environment.is_async: + self.write('await auto_await(') + self.write(self.filters[node.name] + '(') + func = self.environment.filters.get(node.name) + if func is None: + self.fail('no filter named %r' % node.name, node.lineno) + if getattr(func, 'contextfilter', False): + self.write('context, ') + elif getattr(func, 'evalcontextfilter', False): + self.write('context.eval_ctx, ') + elif getattr(func, 'environmentfilter', False): + self.write('environment, ') + + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write('(context.eval_ctx.autoescape and' + ' Markup(concat(%s)) or concat(%s))' % + (frame.buffer, frame.buffer)) + elif frame.eval_ctx.autoescape: + self.write('Markup(concat(%s))' % frame.buffer) + else: + self.write('concat(%s)' % frame.buffer) + self.signature(node, frame) + self.write(')') + if self.environment.is_async: + self.write(')') + + @optimizeconst + def visit_Test(self, node, frame): + self.write(self.tests[node.name] + '(') + if node.name not in self.environment.tests: + self.fail('no test named %r' % node.name, node.lineno) + self.visit(node.node, frame) + self.signature(node, frame) + self.write(')') + + @optimizeconst + def visit_CondExpr(self, node, frame): + def write_expr2(): + if node.expr2 is not None: + return self.visit(node.expr2, frame) + self.write('undefined(%r)' % ('the inline if-' + 'expression on %s evaluated to false and ' + 'no else section was defined.' % self.position(node))) + + self.write('(') + self.visit(node.expr1, frame) + self.write(' if ') + self.visit(node.test, frame) + self.write(' else ') + write_expr2() + self.write(')') + + @optimizeconst + def visit_Call(self, node, frame, forward_caller=False): + if self.environment.is_async: + self.write('await auto_await(') + if self.environment.sandboxed: + self.write('environment.call(context, ') + else: + self.write('context.call(') + self.visit(node.node, frame) + extra_kwargs = forward_caller and {'caller': 'caller'} or None + self.signature(node, frame, extra_kwargs) + self.write(')') + if self.environment.is_async: + self.write(')') + + def visit_Keyword(self, node, frame): + self.write(node.key + '=') + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node, frame): + self.write('Markup(') + self.visit(node.expr, frame) + self.write(')') + + def visit_MarkSafeIfAutoescape(self, node, frame): + self.write('(context.eval_ctx.autoescape and Markup or identity)(') + self.visit(node.expr, frame) + self.write(')') + + def visit_EnvironmentAttribute(self, node, frame): + self.write('environment.' + node.name) + + def visit_ExtensionAttribute(self, node, frame): + self.write('environment.extensions[%r].%s' % (node.identifier, node.name)) + + def visit_ImportedName(self, node, frame): + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node, frame): + self.write(node.name) + + def visit_ContextReference(self, node, frame): + self.write('context') + + def visit_Continue(self, node, frame): + self.writeline('continue', node) + + def visit_Break(self, node, frame): + self.writeline('break', node) + + def visit_Scope(self, node, frame): + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node, frame): + ctx = self.temporary_identifier() + self.writeline('%s = %s' % (ctx, self.derive_context(frame))) + self.writeline('%s.vars = ' % ctx) + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier(self, node, frame): + for keyword in node.options: + self.writeline('context.eval_ctx.%s = ' % keyword.key) + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier(self, node, frame): + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline('%s = context.eval_ctx.save()' % old_ctx_name) + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline('context.eval_ctx.revert(%s)' % old_ctx_name) diff --git a/Lib/site-packages/jinja2/constants.py b/Lib/site-packages/jinja2/constants.py new file mode 100644 index 0000000..11efd1e --- /dev/null +++ b/Lib/site-packages/jinja2/constants.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +""" + jinja.constants + ~~~~~~~~~~~~~~~ + + Various constants. + + :copyright: (c) 2017 by the Jinja Team. + :license: BSD, see LICENSE for more details. +""" + + +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = u'''\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate''' diff --git a/Lib/site-packages/jinja2/debug.py b/Lib/site-packages/jinja2/debug.py new file mode 100644 index 0000000..b61139f --- /dev/null +++ b/Lib/site-packages/jinja2/debug.py @@ -0,0 +1,372 @@ +# -*- coding: utf-8 -*- +""" + jinja2.debug + ~~~~~~~~~~~~ + + Implements the debug interface for Jinja. This module does some pretty + ugly stuff with the Python traceback system in order to achieve tracebacks + with correct line numbers, locals and contents. + + :copyright: (c) 2017 by the Jinja Team. + :license: BSD, see LICENSE for more details. +""" +import sys +import traceback +from types import TracebackType, CodeType +from jinja2.utils import missing, internal_code +from jinja2.exceptions import TemplateSyntaxError +from jinja2._compat import iteritems, reraise, PY2 + +# on pypy we can take advantage of transparent proxies +try: + from __pypy__ import tproxy +except ImportError: + tproxy = None + + +# how does the raise helper look like? +try: + exec("raise TypeError, 'foo'") +except SyntaxError: + raise_helper = 'raise __jinja_exception__[1]' +except TypeError: + raise_helper = 'raise __jinja_exception__[0], __jinja_exception__[1]' + + +class TracebackFrameProxy(object): + """Proxies a traceback frame.""" + + def __init__(self, tb): + self.tb = tb + self._tb_next = None + + @property + def tb_next(self): + return self._tb_next + + def set_next(self, next): + if tb_set_next is not None: + try: + tb_set_next(self.tb, next and next.tb or None) + except Exception: + # this function can fail due to all the hackery it does + # on various python implementations. We just catch errors + # down and ignore them if necessary. + pass + self._tb_next = next + + @property + def is_jinja_frame(self): + return '__jinja_template__' in self.tb.tb_frame.f_globals + + def __getattr__(self, name): + return getattr(self.tb, name) + + +def make_frame_proxy(frame): + proxy = TracebackFrameProxy(frame) + if tproxy is None: + return proxy + def operation_handler(operation, *args, **kwargs): + if operation in ('__getattribute__', '__getattr__'): + return getattr(proxy, args[0]) + elif operation == '__setattr__': + proxy.__setattr__(*args, **kwargs) + else: + return getattr(proxy, operation)(*args, **kwargs) + return tproxy(TracebackType, operation_handler) + + +class ProcessedTraceback(object): + """Holds a Jinja preprocessed traceback for printing or reraising.""" + + def __init__(self, exc_type, exc_value, frames): + assert frames, 'no frames for this traceback?' + self.exc_type = exc_type + self.exc_value = exc_value + self.frames = frames + + # newly concatenate the frames (which are proxies) + prev_tb = None + for tb in self.frames: + if prev_tb is not None: + prev_tb.set_next(tb) + prev_tb = tb + prev_tb.set_next(None) + + def render_as_text(self, limit=None): + """Return a string with the traceback.""" + lines = traceback.format_exception(self.exc_type, self.exc_value, + self.frames[0], limit=limit) + return ''.join(lines).rstrip() + + def render_as_html(self, full=False): + """Return a unicode string with the traceback as rendered HTML.""" + from jinja2.debugrenderer import render_traceback + return u'%s\n\n' % ( + render_traceback(self, full=full), + self.render_as_text().decode('utf-8', 'replace') + ) + + @property + def is_template_syntax_error(self): + """`True` if this is a template syntax error.""" + return isinstance(self.exc_value, TemplateSyntaxError) + + @property + def exc_info(self): + """Exception info tuple with a proxy around the frame objects.""" + return self.exc_type, self.exc_value, self.frames[0] + + @property + def standard_exc_info(self): + """Standard python exc_info for re-raising""" + tb = self.frames[0] + # the frame will be an actual traceback (or transparent proxy) if + # we are on pypy or a python implementation with support for tproxy + if type(tb) is not TracebackType: + tb = tb.tb + return self.exc_type, self.exc_value, tb + + +def make_traceback(exc_info, source_hint=None): + """Creates a processed traceback object from the exc_info.""" + exc_type, exc_value, tb = exc_info + if isinstance(exc_value, TemplateSyntaxError): + exc_info = translate_syntax_error(exc_value, source_hint) + initial_skip = 0 + else: + initial_skip = 1 + return translate_exception(exc_info, initial_skip) + + +def translate_syntax_error(error, source=None): + """Rewrites a syntax error to please traceback systems.""" + error.source = source + error.translated = True + exc_info = (error.__class__, error, None) + filename = error.filename + if filename is None: + filename = '' + return fake_exc_info(exc_info, filename, error.lineno) + + +def translate_exception(exc_info, initial_skip=0): + """If passed an exc_info it will automatically rewrite the exceptions + all the way down to the correct line numbers and frames. + """ + tb = exc_info[2] + frames = [] + + # skip some internal frames if wanted + for x in range(initial_skip): + if tb is not None: + tb = tb.tb_next + initial_tb = tb + + while tb is not None: + # skip frames decorated with @internalcode. These are internal + # calls we can't avoid and that are useless in template debugging + # output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + # save a reference to the next frame if we override the current + # one with a faked one. + next = tb.tb_next + + # fake template exceptions + template = tb.tb_frame.f_globals.get('__jinja_template__') + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + tb = fake_exc_info(exc_info[:2] + (tb,), template.filename, + lineno)[2] + + frames.append(make_frame_proxy(tb)) + tb = next + + # if we don't have any exceptions in the frames left, we have to + # reraise it unchanged. + # XXX: can we backup here? when could this happen? + if not frames: + reraise(exc_info[0], exc_info[1], exc_info[2]) + + return ProcessedTraceback(exc_info[0], exc_info[1], frames) + + +def get_jinja_locals(real_locals): + ctx = real_locals.get('context') + if ctx: + locals = ctx.get_all().copy() + else: + locals = {} + + local_overrides = {} + + for name, value in iteritems(real_locals): + if not name.startswith('l_') or value is missing: + continue + try: + _, depth, name = name.split('_', 2) + depth = int(depth) + except ValueError: + continue + cur_depth = local_overrides.get(name, (-1,))[0] + if cur_depth < depth: + local_overrides[name] = (depth, value) + + for name, (_, value) in iteritems(local_overrides): + if value is missing: + locals.pop(name, None) + else: + locals[name] = value + + return locals + + +def fake_exc_info(exc_info, filename, lineno): + """Helper for `translate_exception`.""" + exc_type, exc_value, tb = exc_info + + # figure the real context out + if tb is not None: + locals = get_jinja_locals(tb.tb_frame.f_locals) + + # if there is a local called __jinja_exception__, we get + # rid of it to not break the debug functionality. + locals.pop('__jinja_exception__', None) + else: + locals = {} + + # assamble fake globals we need + globals = { + '__name__': filename, + '__file__': filename, + '__jinja_exception__': exc_info[:2], + + # we don't want to keep the reference to the template around + # to not cause circular dependencies, but we mark it as Jinja + # frame for the ProcessedTraceback + '__jinja_template__': None + } + + # and fake the exception + code = compile('\n' * (lineno - 1) + raise_helper, filename, 'exec') + + # if it's possible, change the name of the code. This won't work + # on some python environments such as google appengine + try: + if tb is None: + location = 'template' + else: + function = tb.tb_frame.f_code.co_name + if function == 'root': + location = 'top-level template code' + elif function.startswith('block_'): + location = 'block "%s"' % function[6:] + else: + location = 'template' + + if PY2: + code = CodeType(0, code.co_nlocals, code.co_stacksize, + code.co_flags, code.co_code, code.co_consts, + code.co_names, code.co_varnames, filename, + location, code.co_firstlineno, + code.co_lnotab, (), ()) + else: + code = CodeType(0, code.co_kwonlyargcount, + code.co_nlocals, code.co_stacksize, + code.co_flags, code.co_code, code.co_consts, + code.co_names, code.co_varnames, filename, + location, code.co_firstlineno, + code.co_lnotab, (), ()) + except Exception as e: + pass + + # execute the code and catch the new traceback + try: + exec(code, globals, locals) + except: + exc_info = sys.exc_info() + new_tb = exc_info[2].tb_next + + # return without this frame + return exc_info[:2] + (new_tb,) + + +def _init_ugly_crap(): + """This function implements a few ugly things so that we can patch the + traceback objects. The function returned allows resetting `tb_next` on + any python traceback object. Do not attempt to use this on non cpython + interpreters + """ + import ctypes + from types import TracebackType + + if PY2: + # figure out size of _Py_ssize_t for Python 2: + if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'): + _Py_ssize_t = ctypes.c_int64 + else: + _Py_ssize_t = ctypes.c_int + else: + # platform ssize_t on Python 3 + _Py_ssize_t = ctypes.c_ssize_t + + # regular python + class _PyObject(ctypes.Structure): + pass + _PyObject._fields_ = [ + ('ob_refcnt', _Py_ssize_t), + ('ob_type', ctypes.POINTER(_PyObject)) + ] + + # python with trace + if hasattr(sys, 'getobjects'): + class _PyObject(ctypes.Structure): + pass + _PyObject._fields_ = [ + ('_ob_next', ctypes.POINTER(_PyObject)), + ('_ob_prev', ctypes.POINTER(_PyObject)), + ('ob_refcnt', _Py_ssize_t), + ('ob_type', ctypes.POINTER(_PyObject)) + ] + + class _Traceback(_PyObject): + pass + _Traceback._fields_ = [ + ('tb_next', ctypes.POINTER(_Traceback)), + ('tb_frame', ctypes.POINTER(_PyObject)), + ('tb_lasti', ctypes.c_int), + ('tb_lineno', ctypes.c_int) + ] + + def tb_set_next(tb, next): + """Set the tb_next attribute of a traceback object.""" + if not (isinstance(tb, TracebackType) and + (next is None or isinstance(next, TracebackType))): + raise TypeError('tb_set_next arguments must be traceback objects') + obj = _Traceback.from_address(id(tb)) + if tb.tb_next is not None: + old = _Traceback.from_address(id(tb.tb_next)) + old.ob_refcnt -= 1 + if next is None: + obj.tb_next = ctypes.POINTER(_Traceback)() + else: + next = _Traceback.from_address(id(next)) + next.ob_refcnt += 1 + obj.tb_next = ctypes.pointer(next) + + return tb_set_next + + +# try to get a tb_set_next implementation if we don't have transparent +# proxies. +tb_set_next = None +if tproxy is None: + try: + tb_set_next = _init_ugly_crap() + except: + pass + del _init_ugly_crap diff --git a/Lib/site-packages/jinja2/defaults.py b/Lib/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..7c93dec --- /dev/null +++ b/Lib/site-packages/jinja2/defaults.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +""" + jinja2.defaults + ~~~~~~~~~~~~~~~ + + Jinja default filters and tags. + + :copyright: (c) 2017 by the Jinja Team. + :license: BSD, see LICENSE for more details. +""" +from jinja2._compat import range_type +from jinja2.utils import generate_lorem_ipsum, Cycler, Joiner, Namespace + + +# defaults for the parser / lexer +BLOCK_START_STRING = '{%' +BLOCK_END_STRING = '%}' +VARIABLE_START_STRING = '{{' +VARIABLE_END_STRING = '}}' +COMMENT_START_STRING = '{#' +COMMENT_END_STRING = '#}' +LINE_STATEMENT_PREFIX = None +LINE_COMMENT_PREFIX = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE = '\n' +KEEP_TRAILING_NEWLINE = False + + +# default filters, tests and namespace +from jinja2.filters import FILTERS as DEFAULT_FILTERS +from jinja2.tests import TESTS as DEFAULT_TESTS +DEFAULT_NAMESPACE = { + 'range': range_type, + 'dict': dict, + 'lipsum': generate_lorem_ipsum, + 'cycler': Cycler, + 'joiner': Joiner, + 'namespace': Namespace +} + + +# default policies +DEFAULT_POLICIES = { + 'compiler.ascii_str': True, + 'urlize.rel': 'noopener', + 'urlize.target': None, + 'truncate.leeway': 5, + 'json.dumps_function': None, + 'json.dumps_kwargs': {'sort_keys': True}, + 'ext.i18n.trimmed': False, +} + + +# export all constants +__all__ = tuple(x for x in locals().keys() if x.isupper()) diff --git a/Lib/site-packages/jinja2/environment.py b/Lib/site-packages/jinja2/environment.py new file mode 100644 index 0000000..549d9af --- /dev/null +++ b/Lib/site-packages/jinja2/environment.py @@ -0,0 +1,1276 @@ +# -*- coding: utf-8 -*- +""" + jinja2.environment + ~~~~~~~~~~~~~~~~~~ + + Provides a class that holds runtime and parsing time options. + + :copyright: (c) 2017 by the Jinja Team. + :license: BSD, see LICENSE for more details. +""" +import os +import sys +import weakref +from functools import reduce, partial +from jinja2 import nodes +from jinja2.defaults import BLOCK_START_STRING, \ + BLOCK_END_STRING, VARIABLE_START_STRING, VARIABLE_END_STRING, \ + COMMENT_START_STRING, COMMENT_END_STRING, LINE_STATEMENT_PREFIX, \ + LINE_COMMENT_PREFIX, TRIM_BLOCKS, NEWLINE_SEQUENCE, \ + DEFAULT_FILTERS, DEFAULT_TESTS, DEFAULT_NAMESPACE, \ + DEFAULT_POLICIES, KEEP_TRAILING_NEWLINE, LSTRIP_BLOCKS +from jinja2.lexer import get_lexer, TokenStream +from jinja2.parser import Parser +from jinja2.nodes import EvalContext +from jinja2.compiler import generate, CodeGenerator +from jinja2.runtime import Undefined, new_context, Context +from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \ + TemplatesNotFound, TemplateRuntimeError +from jinja2.utils import import_string, LRUCache, Markup, missing, \ + concat, consume, internalcode, have_async_gen +from jinja2._compat import imap, ifilter, string_types, iteritems, \ + text_type, reraise, implements_iterator, implements_to_string, \ + encode_filename, PY2, PYPY + + +# for direct template usage we have up to ten living environments +_spontaneous_environments = LRUCache(10) + +# the function to create jinja traceback objects. This is dynamically +# imported on the first exception in the exception handler. +_make_traceback = None + + +def get_spontaneous_environment(*args): + """Return a new spontaneous environment. A spontaneous environment is an + unnamed and unaccessible (in theory) environment that is used for + templates generated from a string and not from the file system. + """ + try: + env = _spontaneous_environments.get(args) + except TypeError: + return Environment(*args) + if env is not None: + return env + _spontaneous_environments[args] = env = Environment(*args) + env.shared = True + return env + + +def create_cache(size): + """Return the cache class for the given size.""" + if size == 0: + return None + if size < 0: + return {} + return LRUCache(size) + + +def copy_cache(cache): + """Create an empty copy of the given cache.""" + if cache is None: + return None + elif type(cache) is dict: + return {} + return LRUCache(cache.capacity) + + +def load_extensions(environment, extensions): + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated environments. + """ + result = {} + for extension in extensions: + if isinstance(extension, string_types): + extension = import_string(extension) + result[extension.identifier] = extension(environment) + return result + + +def fail_for_missing_callable(string, name): + msg = string % name + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = '%s (%s; did you forget to quote the callable name?)' % (msg, e) + raise TemplateRuntimeError(msg) + + +def _environment_sanity_check(environment): + """Perform a sanity check on the environment.""" + assert issubclass(environment.undefined, Undefined), 'undefined must ' \ + 'be a subclass of undefined because filters depend on it.' + assert environment.block_start_string != \ + environment.variable_start_string != \ + environment.comment_start_string, 'block, variable and comment ' \ + 'start strings must be different' + assert environment.newline_sequence in ('\r', '\r\n', '\n'), \ + 'newline_sequence set to unknown line ending string.' + return environment + + +class Environment(object): + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~jinja2.utils.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which allows + you to take advantage of newer Python features. This requires + Python 3.6 or later. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: these are currently EXPERIMENTAL undocumented features. + exception_handler = None + exception_formatter = None + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class = CodeGenerator + + #: the context class thatis used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class = Context + + def __init__(self, + block_start_string=BLOCK_START_STRING, + block_end_string=BLOCK_END_STRING, + variable_start_string=VARIABLE_START_STRING, + variable_end_string=VARIABLE_END_STRING, + comment_start_string=COMMENT_START_STRING, + comment_end_string=COMMENT_END_STRING, + line_statement_prefix=LINE_STATEMENT_PREFIX, + line_comment_prefix=LINE_COMMENT_PREFIX, + trim_blocks=TRIM_BLOCKS, + lstrip_blocks=LSTRIP_BLOCKS, + newline_sequence=NEWLINE_SEQUENCE, + keep_trailing_newline=KEEP_TRAILING_NEWLINE, + extensions=(), + optimized=True, + undefined=Undefined, + finalize=None, + autoescape=False, + loader=None, + cache_size=400, + auto_reload=True, + bytecode_cache=None, + enable_async=False): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.enable_async = enable_async + self.is_async = self.enable_async and have_async_gen + + _environment_sanity_check(self) + + def add_extension(self, extension): + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes): + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in iteritems(attributes): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay(self, block_start_string=missing, block_end_string=missing, + variable_start_string=missing, variable_end_string=missing, + comment_start_string=missing, comment_end_string=missing, + line_statement_prefix=missing, line_comment_prefix=missing, + trim_blocks=missing, lstrip_blocks=missing, + extensions=missing, optimized=missing, + undefined=missing, finalize=missing, autoescape=missing, + loader=missing, cache_size=missing, auto_reload=missing, + bytecode_cache=missing): + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + """ + args = dict(locals()) + del args['self'], args['cache_size'], args['extensions'] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in iteritems(args): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in iteritems(self.extensions): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + return _environment_sanity_check(rv) + + lexer = property(get_lexer, doc="The lexer for this environment.") + + def iter_extensions(self): + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), + key=lambda x: x.priority)) + + def getitem(self, obj, argument): + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, string_types): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj, attribute): + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a bytestring. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def call_filter(self, name, value, args=None, kwargs=None, + context=None, eval_ctx=None): + """Invokes a filter on a value the same way the compiler does it. + + Note that on Python 3 this might return a coroutine in case the + filter is running from an environment in async mode and the filter + supports async execution. It's your responsibility to await this + if needed. + + .. versionadded:: 2.7 + """ + func = self.filters.get(name) + if func is None: + fail_for_missing_callable('no filter named %r', name) + args = [value] + list(args or ()) + if getattr(func, 'contextfilter', False): + if context is None: + raise TemplateRuntimeError('Attempted to invoke context ' + 'filter without context') + args.insert(0, context) + elif getattr(func, 'evalcontextfilter', False): + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + args.insert(0, eval_ctx) + elif getattr(func, 'environmentfilter', False): + args.insert(0, self) + return func(*args, **(kwargs or {})) + + def call_test(self, name, value, args=None, kwargs=None): + """Invokes a test on a value the same way the compiler does it. + + .. versionadded:: 2.7 + """ + func = self.tests.get(name) + if func is None: + fail_for_missing_callable('no test named %r', name) + return func(value, *(args or ()), **(kwargs or {})) + + @internalcode + def parse(self, source, name=None, filename=None): + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja2 extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + exc_info = sys.exc_info() + self.handle_exception(exc_info, source_hint=source) + + def _parse(self, source, name, filename): + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, encode_filename(filename)).parse() + + def lex(self, source, name=None, filename=None): + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = text_type(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + exc_info = sys.exc_info() + self.handle_exception(exc_info, source_hint=source) + + def preprocess(self, source, name=None, filename=None): + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce(lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), text_type(source)) + + def _tokenize(self, source, name, filename=None, state=None): + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) + return stream + + def _generate(self, source, name, filename, defer_init=False): + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate(source, self, name, filename, defer_init=defer_init, + optimized=self.optimized) + + def _compile(self, source, filename): + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, 'exec') + + @internalcode + def compile(self, source, name=None, filename=None, raw=False, + defer_init=False): + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, string_types): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, + defer_init=defer_init) + if raw: + return source + if filename is None: + filename = '