From 619d195e96087e7a3fef86c7cd4f86df26d8af10 Mon Sep 17 00:00:00 2001 From: talksik Date: Sat, 12 Dec 2020 13:22:56 -0500 Subject: [PATCH] Initial commit --- .gitattributes | 2 + .vscode/settings.json | 3 + README.md | 2 + __pycache__/hello.cpython-37.pyc | Bin 0 -> 333 bytes hello.py | 7 + venv/bin/activate | 76 + venv/bin/activate.csh | 37 + venv/bin/activate.fish | 75 + venv/bin/easy_install | 10 + venv/bin/easy_install-3.7 | 10 + venv/bin/epylint | 10 + venv/bin/flask | 10 + venv/bin/isort | 10 + venv/bin/pip | 10 + venv/bin/pip3 | 10 + venv/bin/pip3.7 | 10 + venv/bin/pylint | 10 + venv/bin/pyreverse | 10 + venv/bin/python | 1 + venv/bin/python3 | 1 + venv/bin/symilar | 10 + .../Click-7.0.dist-info/INSTALLER | 1 + .../Click-7.0.dist-info/LICENSE.txt | 39 + .../Click-7.0.dist-info/METADATA | 121 + .../site-packages/Click-7.0.dist-info/RECORD | 40 + .../site-packages/Click-7.0.dist-info/WHEEL | 6 + .../Click-7.0.dist-info/top_level.txt | 1 + .../Flask-1.0.3.dist-info/INSTALLER | 1 + .../Flask-1.0.3.dist-info/LICENSE | 31 + .../Flask-1.0.3.dist-info/METADATA | 124 + .../Flask-1.0.3.dist-info/RECORD | 48 + .../site-packages/Flask-1.0.3.dist-info/WHEEL | 6 + .../Flask-1.0.3.dist-info/entry_points.txt | 3 + .../Flask-1.0.3.dist-info/top_level.txt | 1 + .../Jinja2-2.10.1.dist-info/INSTALLER | 1 + .../Jinja2-2.10.1.dist-info/LICENSE | 31 + .../Jinja2-2.10.1.dist-info/METADATA | 67 + .../Jinja2-2.10.1.dist-info/RECORD | 61 + .../Jinja2-2.10.1.dist-info/WHEEL | 6 + .../Jinja2-2.10.1.dist-info/entry_points.txt | 4 + .../Jinja2-2.10.1.dist-info/top_level.txt | 1 + .../MarkupSafe-1.1.1.dist-info/INSTALLER | 1 + .../MarkupSafe-1.1.1.dist-info/LICENSE.rst | 28 + .../MarkupSafe-1.1.1.dist-info/METADATA | 103 + .../MarkupSafe-1.1.1.dist-info/RECORD | 16 + .../MarkupSafe-1.1.1.dist-info/WHEEL | 5 + .../MarkupSafe-1.1.1.dist-info/top_level.txt | 1 + .../Werkzeug-0.15.4.dist-info/INSTALLER | 1 + .../Werkzeug-0.15.4.dist-info/LICENSE.rst | 28 + .../Werkzeug-0.15.4.dist-info/METADATA | 133 + .../Werkzeug-0.15.4.dist-info/RECORD | 119 + .../Werkzeug-0.15.4.dist-info/WHEEL | 6 + .../Werkzeug-0.15.4.dist-info/top_level.txt | 1 + .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 333 bytes .../__pycache__/mccabe.cpython-37.pyc | Bin 0 -> 11156 bytes .../__pycache__/six.cpython-37.pyc | Bin 0 -> 26410 bytes .../astroid-2.2.5.dist-info/COPYING | 339 + .../astroid-2.2.5.dist-info/COPYING.LESSER | 510 + .../astroid-2.2.5.dist-info/INSTALLER | 1 + .../astroid-2.2.5.dist-info/METADATA | 102 + .../astroid-2.2.5.dist-info/RECORD | 125 + .../astroid-2.2.5.dist-info/WHEEL | 5 + .../astroid-2.2.5.dist-info/top_level.txt | 1 + .../site-packages/astroid/__init__.py | 166 + .../site-packages/astroid/__pkginfo__.py | 57 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4454 bytes .../__pycache__/__pkginfo__.cpython-37.pyc | Bin 0 -> 1442 bytes .../astroid/__pycache__/_ast.cpython-37.pyc | Bin 0 -> 1359 bytes .../__pycache__/arguments.cpython-37.pyc | Bin 0 -> 7037 bytes .../__pycache__/as_string.cpython-37.pyc | Bin 0 -> 26198 bytes .../astroid/__pycache__/bases.cpython-37.pyc | Bin 0 -> 15719 bytes .../__pycache__/builder.cpython-37.pyc | Bin 0 -> 12312 bytes .../__pycache__/context.cpython-37.pyc | Bin 0 -> 4297 bytes .../__pycache__/decorators.cpython-37.pyc | Bin 0 -> 3538 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 9389 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 0 -> 7265 bytes .../__pycache__/inference.cpython-37.pyc | Bin 0 -> 20659 bytes .../__pycache__/manager.cpython-37.pyc | Bin 0 -> 9295 bytes .../astroid/__pycache__/mixins.cpython-37.pyc | Bin 0 -> 5800 bytes .../__pycache__/modutils.cpython-37.pyc | Bin 0 -> 17193 bytes .../__pycache__/node_classes.cpython-37.pyc | Bin 0 -> 119379 bytes .../astroid/__pycache__/nodes.cpython-37.pyc | Bin 0 -> 2050 bytes .../__pycache__/objects.cpython-37.pyc | Bin 0 -> 8521 bytes .../__pycache__/protocols.cpython-37.pyc | Bin 0 -> 16509 bytes .../__pycache__/raw_building.cpython-37.pyc | Bin 0 -> 10940 bytes .../__pycache__/rebuilder.cpython-37.pyc | Bin 0 -> 38356 bytes .../__pycache__/scoped_nodes.cpython-37.pyc | Bin 0 -> 69892 bytes .../__pycache__/test_utils.cpython-37.pyc | Bin 0 -> 2509 bytes .../__pycache__/transforms.cpython-37.pyc | Bin 0 -> 3456 bytes .../astroid/__pycache__/util.cpython-37.pyc | Bin 0 -> 5724 bytes .../python3.7/site-packages/astroid/_ast.py | 40 + .../site-packages/astroid/arguments.py | 285 + .../site-packages/astroid/as_string.py | 630 ++ .../python3.7/site-packages/astroid/bases.py | 547 ++ .../__pycache__/brain_argparse.cpython-37.pyc | Bin 0 -> 1083 bytes .../__pycache__/brain_attrs.cpython-37.pyc | Bin 0 -> 1496 bytes .../brain_builtin_inference.cpython-37.pyc | Bin 0 -> 19730 bytes .../brain_collections.cpython-37.pyc | Bin 0 -> 2638 bytes .../__pycache__/brain_curses.cpython-37.pyc | Bin 0 -> 3388 bytes .../__pycache__/brain_dateutil.cpython-37.pyc | Bin 0 -> 702 bytes .../__pycache__/brain_fstrings.cpython-37.pyc | Bin 0 -> 1585 bytes .../brain_functools.cpython-37.pyc | Bin 0 -> 4584 bytes .../brain/__pycache__/brain_gi.cpython-37.pyc | Bin 0 -> 4027 bytes .../__pycache__/brain_hashlib.cpython-37.pyc | Bin 0 -> 1944 bytes .../__pycache__/brain_http.cpython-37.pyc | Bin 0 -> 3495 bytes .../brain/__pycache__/brain_io.cpython-37.pyc | Bin 0 -> 1325 bytes .../brain_mechanize.cpython-37.pyc | Bin 0 -> 738 bytes .../brain_multiprocessing.cpython-37.pyc | Bin 0 -> 2601 bytes .../brain_namedtuple_enum.cpython-37.pyc | Bin 0 -> 11354 bytes .../__pycache__/brain_nose.cpython-37.pyc | Bin 0 -> 2067 bytes .../__pycache__/brain_numpy.cpython-37.pyc | Bin 0 -> 20290 bytes .../brain_pkg_resources.cpython-37.pyc | Bin 0 -> 2209 bytes .../__pycache__/brain_pytest.cpython-37.pyc | Bin 0 -> 2179 bytes .../brain/__pycache__/brain_qt.cpython-37.pyc | Bin 0 -> 2087 bytes .../__pycache__/brain_random.cpython-37.pyc | Bin 0 -> 2192 bytes .../brain/__pycache__/brain_re.cpython-37.pyc | Bin 0 -> 1086 bytes .../__pycache__/brain_six.cpython-37.pyc | Bin 0 -> 5541 bytes .../__pycache__/brain_ssl.cpython-37.pyc | Bin 0 -> 3620 bytes .../brain_subprocess.cpython-37.pyc | Bin 0 -> 3786 bytes .../brain_threading.cpython-37.pyc | Bin 0 -> 706 bytes .../__pycache__/brain_typing.cpython-37.pyc | Bin 0 -> 2357 bytes .../__pycache__/brain_uuid.cpython-37.pyc | Bin 0 -> 649 bytes .../astroid/brain/brain_argparse.py | 33 + .../astroid/brain/brain_attrs.py | 59 + .../astroid/brain/brain_builtin_inference.py | 822 ++ .../astroid/brain/brain_collections.py | 82 + .../astroid/brain/brain_curses.py | 179 + .../astroid/brain/brain_dateutil.py | 28 + .../astroid/brain/brain_fstrings.py | 51 + .../astroid/brain/brain_functools.py | 157 + .../site-packages/astroid/brain/brain_gi.py | 220 + .../astroid/brain/brain_hashlib.py | 67 + .../site-packages/astroid/brain/brain_http.py | 81 + .../site-packages/astroid/brain/brain_io.py | 45 + .../astroid/brain/brain_mechanize.py | 29 + .../astroid/brain/brain_multiprocessing.py | 112 + .../astroid/brain/brain_namedtuple_enum.py | 440 + .../site-packages/astroid/brain/brain_nose.py | 77 + .../astroid/brain/brain_numpy.py | 557 ++ .../astroid/brain/brain_pkg_resources.py | 75 + .../astroid/brain/brain_pytest.py | 88 + .../site-packages/astroid/brain/brain_qt.py | 82 + .../astroid/brain/brain_random.py | 75 + .../site-packages/astroid/brain/brain_re.py | 36 + .../site-packages/astroid/brain/brain_six.py | 200 + .../site-packages/astroid/brain/brain_ssl.py | 74 + .../astroid/brain/brain_subprocess.py | 119 + .../astroid/brain/brain_threading.py | 29 + .../astroid/brain/brain_typing.py | 96 + .../site-packages/astroid/brain/brain_uuid.py | 20 + .../site-packages/astroid/builder.py | 435 + .../site-packages/astroid/context.py | 179 + .../site-packages/astroid/decorators.py | 141 + .../site-packages/astroid/exceptions.py | 230 + .../site-packages/astroid/helpers.py | 272 + .../site-packages/astroid/inference.py | 899 ++ .../astroid/interpreter/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 204 bytes .../__pycache__/dunder_lookup.cpython-37.pyc | Bin 0 -> 2157 bytes .../__pycache__/objectmodel.cpython-37.pyc | Bin 0 -> 25014 bytes .../astroid/interpreter/_import/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 212 bytes .../_import/__pycache__/spec.cpython-37.pyc | Bin 0 -> 9386 bytes .../_import/__pycache__/util.cpython-37.pyc | Bin 0 -> 428 bytes .../astroid/interpreter/_import/spec.py | 337 + .../astroid/interpreter/_import/util.py | 10 + .../astroid/interpreter/dunder_lookup.py | 66 + .../astroid/interpreter/objectmodel.py | 728 ++ .../site-packages/astroid/manager.py | 327 + .../python3.7/site-packages/astroid/mixins.py | 160 + .../site-packages/astroid/modutils.py | 704 ++ .../site-packages/astroid/node_classes.py | 4697 ++++++++++ .../python3.7/site-packages/astroid/nodes.py | 173 + .../site-packages/astroid/objects.py | 282 + .../site-packages/astroid/protocols.py | 755 ++ .../site-packages/astroid/raw_building.py | 449 + .../site-packages/astroid/rebuilder.py | 1066 +++ .../site-packages/astroid/scoped_nodes.py | 2798 ++++++ .../site-packages/astroid/test_utils.py | 71 + .../site-packages/astroid/transforms.py | 90 + .../python3.7/site-packages/astroid/util.py | 164 + .../python3.7/site-packages/click/__init__.py | 97 + .../click/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2676 bytes .../__pycache__/_bashcomplete.cpython-37.pyc | Bin 0 -> 9132 bytes .../click/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 16803 bytes .../__pycache__/_termui_impl.cpython-37.pyc | Bin 0 -> 13967 bytes .../__pycache__/_textwrap.cpython-37.pyc | Bin 0 -> 1350 bytes .../__pycache__/_unicodefun.cpython-37.pyc | Bin 0 -> 3340 bytes .../__pycache__/_winconsole.cpython-37.pyc | Bin 0 -> 8747 bytes .../click/__pycache__/core.cpython-37.pyc | Bin 0 -> 59847 bytes .../__pycache__/decorators.cpython-37.pyc | Bin 0 -> 11604 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 8630 bytes .../__pycache__/formatting.cpython-37.pyc | Bin 0 -> 8566 bytes .../click/__pycache__/globals.cpython-37.pyc | Bin 0 -> 1897 bytes .../click/__pycache__/parser.cpython-37.pyc | Bin 0 -> 11474 bytes .../click/__pycache__/termui.cpython-37.pyc | Bin 0 -> 20791 bytes .../click/__pycache__/testing.cpython-37.pyc | Bin 0 -> 11639 bytes .../click/__pycache__/types.cpython-37.pyc | Bin 0 -> 21817 bytes .../click/__pycache__/utils.cpython-37.pyc | Bin 0 -> 15262 bytes .../site-packages/click/_bashcomplete.py | 293 + .../python3.7/site-packages/click/_compat.py | 703 ++ .../site-packages/click/_termui_impl.py | 621 ++ .../site-packages/click/_textwrap.py | 38 + .../site-packages/click/_unicodefun.py | 125 + .../site-packages/click/_winconsole.py | 307 + .../lib/python3.7/site-packages/click/core.py | 1856 ++++ .../site-packages/click/decorators.py | 311 + .../site-packages/click/exceptions.py | 235 + .../site-packages/click/formatting.py | 256 + .../python3.7/site-packages/click/globals.py | 48 + .../python3.7/site-packages/click/parser.py | 427 + .../python3.7/site-packages/click/termui.py | 606 ++ .../python3.7/site-packages/click/testing.py | 374 + .../python3.7/site-packages/click/types.py | 668 ++ .../python3.7/site-packages/click/utils.py | 440 + .../python3.7/site-packages/easy_install.py | 5 + .../python3.7/site-packages/flask/__init__.py | 49 + .../python3.7/site-packages/flask/__main__.py | 14 + .../flask/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1850 bytes .../flask/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 477 bytes .../flask/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 3330 bytes .../flask/__pycache__/app.cpython-37.pyc | Bin 0 -> 71414 bytes .../__pycache__/blueprints.cpython-37.pyc | Bin 0 -> 20472 bytes .../flask/__pycache__/cli.cpython-37.pyc | Bin 0 -> 25067 bytes .../flask/__pycache__/config.cpython-37.pyc | Bin 0 -> 10210 bytes .../flask/__pycache__/ctx.cpython-37.pyc | Bin 0 -> 13986 bytes .../__pycache__/debughelpers.cpython-37.pyc | Bin 0 -> 6625 bytes .../flask/__pycache__/globals.cpython-37.pyc | Bin 0 -> 1777 bytes .../flask/__pycache__/helpers.cpython-37.pyc | Bin 0 -> 33264 bytes .../flask/__pycache__/logging.cpython-37.pyc | Bin 0 -> 2406 bytes .../flask/__pycache__/sessions.cpython-37.pyc | Bin 0 -> 12272 bytes .../flask/__pycache__/signals.cpython-37.pyc | Bin 0 -> 2438 bytes .../__pycache__/templating.cpython-37.pyc | Bin 0 -> 4987 bytes .../flask/__pycache__/testing.cpython-37.pyc | Bin 0 -> 7860 bytes .../flask/__pycache__/views.cpython-37.pyc | Bin 0 -> 4800 bytes .../flask/__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 6794 bytes .../python3.7/site-packages/flask/_compat.py | 101 + venv/lib/python3.7/site-packages/flask/app.py | 2334 +++++ .../site-packages/flask/blueprints.py | 447 + venv/lib/python3.7/site-packages/flask/cli.py | 910 ++ .../python3.7/site-packages/flask/config.py | 269 + venv/lib/python3.7/site-packages/flask/ctx.py | 457 + .../site-packages/flask/debughelpers.py | 168 + .../python3.7/site-packages/flask/globals.py | 61 + .../python3.7/site-packages/flask/helpers.py | 1051 +++ .../site-packages/flask/json/__init__.py | 357 + .../json/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 11443 bytes .../flask/json/__pycache__/tag.cpython-37.pyc | Bin 0 -> 11106 bytes .../python3.7/site-packages/flask/json/tag.py | 300 + .../python3.7/site-packages/flask/logging.py | 78 + .../python3.7/site-packages/flask/sessions.py | 385 + .../python3.7/site-packages/flask/signals.py | 57 + .../site-packages/flask/templating.py | 150 + .../python3.7/site-packages/flask/testing.py | 246 + .../python3.7/site-packages/flask/views.py | 158 + .../python3.7/site-packages/flask/wrappers.py | 216 + .../isort-4.3.20.dist-info/INSTALLER | 1 + .../isort-4.3.20.dist-info/LICENSE | 21 + .../isort-4.3.20.dist-info/METADATA | 697 ++ .../isort-4.3.20.dist-info/RECORD | 30 + .../isort-4.3.20.dist-info/WHEEL | 6 + .../isort-4.3.20.dist-info/entry_points.txt | 9 + .../isort-4.3.20.dist-info/top_level.txt | 1 + .../python3.7/site-packages/isort/__init__.py | 28 + .../python3.7/site-packages/isort/__main__.py | 9 + .../isort/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1617 bytes .../isort/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 368 bytes .../isort/__pycache__/finders.cpython-37.pyc | Bin 0 -> 12007 bytes .../isort/__pycache__/hooks.cpython-37.pyc | Bin 0 -> 3228 bytes .../isort/__pycache__/isort.cpython-37.pyc | Bin 0 -> 29921 bytes .../isort/__pycache__/main.cpython-37.pyc | Bin 0 -> 16744 bytes .../isort/__pycache__/natural.cpython-37.pyc | Bin 0 -> 2328 bytes .../__pycache__/pie_slice.cpython-37.pyc | Bin 0 -> 5028 bytes .../__pycache__/pylama_isort.cpython-37.pyc | Bin 0 -> 1029 bytes .../isort/__pycache__/settings.cpython-37.pyc | Bin 0 -> 12294 bytes .../isort/__pycache__/utils.cpython-37.pyc | Bin 0 -> 1620 bytes .../python3.7/site-packages/isort/finders.py | 382 + .../python3.7/site-packages/isort/hooks.py | 91 + .../python3.7/site-packages/isort/isort.py | 1058 +++ .../lib/python3.7/site-packages/isort/main.py | 401 + .../python3.7/site-packages/isort/natural.py | 47 + .../site-packages/isort/pie_slice.py | 154 + .../site-packages/isort/pylama_isort.py | 29 + .../python3.7/site-packages/isort/settings.py | 356 + .../python3.7/site-packages/isort/utils.py | 53 + .../itsdangerous-1.1.0.dist-info/INSTALLER | 1 + .../itsdangerous-1.1.0.dist-info/LICENSE.rst | 47 + .../itsdangerous-1.1.0.dist-info/METADATA | 98 + .../itsdangerous-1.1.0.dist-info/RECORD | 26 + .../itsdangerous-1.1.0.dist-info/WHEEL | 6 + .../top_level.txt | 1 + .../site-packages/itsdangerous/__init__.py | 22 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1030 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1192 bytes .../__pycache__/_json.cpython-37.pyc | Bin 0 -> 875 bytes .../__pycache__/encoding.cpython-37.pyc | Bin 0 -> 1657 bytes .../__pycache__/exc.cpython-37.pyc | Bin 0 -> 3246 bytes .../__pycache__/jws.cpython-37.pyc | Bin 0 -> 6705 bytes .../__pycache__/serializer.cpython-37.pyc | Bin 0 -> 8061 bytes .../__pycache__/signer.cpython-37.pyc | Bin 0 -> 5821 bytes .../__pycache__/timed.cpython-37.pyc | Bin 0 -> 4587 bytes .../__pycache__/url_safe.cpython-37.pyc | Bin 0 -> 2576 bytes .../site-packages/itsdangerous/_compat.py | 46 + .../site-packages/itsdangerous/_json.py | 18 + .../site-packages/itsdangerous/encoding.py | 49 + .../site-packages/itsdangerous/exc.py | 98 + .../site-packages/itsdangerous/jws.py | 218 + .../site-packages/itsdangerous/serializer.py | 233 + .../site-packages/itsdangerous/signer.py | 179 + .../site-packages/itsdangerous/timed.py | 147 + .../site-packages/itsdangerous/url_safe.py | 65 + .../site-packages/jinja2/__init__.py | 83 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2556 bytes .../jinja2/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 3369 bytes .../__pycache__/_identifier.cpython-37.pyc | Bin 0 -> 1867 bytes .../__pycache__/asyncfilters.cpython-37.pyc | Bin 0 -> 4799 bytes .../__pycache__/asyncsupport.cpython-37.pyc | Bin 0 -> 8147 bytes .../jinja2/__pycache__/bccache.cpython-37.pyc | Bin 0 -> 12736 bytes .../__pycache__/compiler.cpython-37.pyc | Bin 0 -> 46865 bytes .../__pycache__/constants.cpython-37.pyc | Bin 0 -> 1730 bytes .../jinja2/__pycache__/debug.cpython-37.pyc | Bin 0 -> 9346 bytes .../__pycache__/defaults.cpython-37.pyc | Bin 0 -> 1480 bytes .../__pycache__/environment.cpython-37.pyc | Bin 0 -> 43275 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 5044 bytes .../jinja2/__pycache__/ext.cpython-37.pyc | Bin 0 -> 20065 bytes .../jinja2/__pycache__/filters.cpython-37.pyc | Bin 0 -> 34410 bytes .../__pycache__/idtracking.cpython-37.pyc | Bin 0 -> 9980 bytes .../jinja2/__pycache__/lexer.cpython-37.pyc | Bin 0 -> 18537 bytes .../jinja2/__pycache__/loaders.cpython-37.pyc | Bin 0 -> 16600 bytes .../jinja2/__pycache__/meta.cpython-37.pyc | Bin 0 -> 3693 bytes .../__pycache__/nativetypes.cpython-37.pyc | Bin 0 -> 5149 bytes .../jinja2/__pycache__/nodes.cpython-37.pyc | Bin 0 -> 36109 bytes .../__pycache__/optimizer.cpython-37.pyc | Bin 0 -> 2060 bytes .../jinja2/__pycache__/parser.cpython-37.pyc | Bin 0 -> 25204 bytes .../jinja2/__pycache__/runtime.cpython-37.pyc | Bin 0 -> 24612 bytes .../jinja2/__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 14214 bytes .../jinja2/__pycache__/tests.cpython-37.pyc | Bin 0 -> 4436 bytes .../jinja2/__pycache__/utils.cpython-37.pyc | Bin 0 -> 20813 bytes .../jinja2/__pycache__/visitor.cpython-37.pyc | Bin 0 -> 3376 bytes .../python3.7/site-packages/jinja2/_compat.py | 99 + .../site-packages/jinja2/_identifier.py | 2 + .../site-packages/jinja2/asyncfilters.py | 146 + .../site-packages/jinja2/asyncsupport.py | 256 + .../python3.7/site-packages/jinja2/bccache.py | 362 + .../site-packages/jinja2/compiler.py | 1721 ++++ .../site-packages/jinja2/constants.py | 32 + .../python3.7/site-packages/jinja2/debug.py | 372 + .../site-packages/jinja2/defaults.py | 56 + .../site-packages/jinja2/environment.py | 1276 +++ .../site-packages/jinja2/exceptions.py | 146 + .../lib/python3.7/site-packages/jinja2/ext.py | 627 ++ .../python3.7/site-packages/jinja2/filters.py | 1190 +++ .../site-packages/jinja2/idtracking.py | 286 + .../python3.7/site-packages/jinja2/lexer.py | 739 ++ .../python3.7/site-packages/jinja2/loaders.py | 481 + .../python3.7/site-packages/jinja2/meta.py | 106 + .../site-packages/jinja2/nativetypes.py | 220 + .../python3.7/site-packages/jinja2/nodes.py | 999 ++ .../site-packages/jinja2/optimizer.py | 49 + .../python3.7/site-packages/jinja2/parser.py | 903 ++ .../python3.7/site-packages/jinja2/runtime.py | 813 ++ .../python3.7/site-packages/jinja2/sandbox.py | 486 + .../python3.7/site-packages/jinja2/tests.py | 175 + .../python3.7/site-packages/jinja2/utils.py | 647 ++ .../python3.7/site-packages/jinja2/visitor.py | 87 + .../AUTHORS.rst | 10 + .../INSTALLER | 1 + .../lazy_object_proxy-1.4.1.dist-info/LICENSE | 21 + .../METADATA | 152 + .../lazy_object_proxy-1.4.1.dist-info/RECORD | 20 + .../lazy_object_proxy-1.4.1.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../lazy_object_proxy/__init__.py | 23 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 584 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 229 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 461 bytes .../__pycache__/simple.cpython-37.pyc | Bin 0 -> 7784 bytes .../__pycache__/slots.cpython-37.pyc | Bin 0 -> 15255 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 804 bytes .../lazy_object_proxy/_version.py | 4 + .../cext.cpython-37m-darwin.so | Bin 0 -> 35464 bytes .../site-packages/lazy_object_proxy/compat.py | 9 + .../site-packages/lazy_object_proxy/simple.py | 246 + .../site-packages/lazy_object_proxy/slots.py | 414 + .../site-packages/lazy_object_proxy/utils.py | 13 + .../site-packages/markupsafe/__init__.py | 327 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 10876 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 783 bytes .../__pycache__/_constants.cpython-37.pyc | Bin 0 -> 4283 bytes .../__pycache__/_native.cpython-37.pyc | Bin 0 -> 2135 bytes .../site-packages/markupsafe/_compat.py | 33 + .../site-packages/markupsafe/_constants.py | 264 + .../site-packages/markupsafe/_native.py | 69 + .../site-packages/markupsafe/_speedups.c | 423 + .../_speedups.cpython-37m-darwin.so | Bin 0 -> 35080 bytes .../mccabe-0.6.1.dist-info/DESCRIPTION.rst | 152 + .../mccabe-0.6.1.dist-info/INSTALLER | 1 + .../mccabe-0.6.1.dist-info/METADATA | 178 + .../mccabe-0.6.1.dist-info/RECORD | 10 + .../mccabe-0.6.1.dist-info/WHEEL | 6 + .../mccabe-0.6.1.dist-info/entry_points.txt | 3 + .../mccabe-0.6.1.dist-info/metadata.json | 1 + .../mccabe-0.6.1.dist-info/top_level.txt | 1 + venv/lib/python3.7/site-packages/mccabe.py | 347 + .../pip-19.0.3.dist-info/INSTALLER | 1 + .../pip-19.0.3.dist-info/LICENSE.txt | 20 + .../pip-19.0.3.dist-info/METADATA | 75 + .../site-packages/pip-19.0.3.dist-info/RECORD | 620 ++ .../site-packages/pip-19.0.3.dist-info/WHEEL | 6 + .../pip-19.0.3.dist-info/entry_points.txt | 5 + .../pip-19.0.3.dist-info/top_level.txt | 1 + .../python3.7/site-packages/pip/__init__.py | 1 + .../python3.7/site-packages/pip/__main__.py | 19 + .../pip/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 206 bytes .../pip/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 458 bytes .../site-packages/pip/_internal/__init__.py | 78 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1850 bytes .../__pycache__/build_env.cpython-37.pyc | Bin 0 -> 7463 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 7058 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 9843 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 21179 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 11750 bytes .../__pycache__/index.cpython-37.pyc | Bin 0 -> 25260 bytes .../__pycache__/locations.cpython-37.pyc | Bin 0 -> 4437 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 8169 bytes .../__pycache__/pyproject.cpython-37.pyc | Bin 0 -> 3186 bytes .../__pycache__/resolve.cpython-37.pyc | Bin 0 -> 9104 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 25937 bytes .../site-packages/pip/_internal/build_env.py | 215 + .../site-packages/pip/_internal/cache.py | 224 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 281 bytes .../__pycache__/autocompletion.cpython-37.pyc | Bin 0 -> 5094 bytes .../__pycache__/base_command.cpython-37.pyc | Bin 0 -> 7822 bytes .../cli/__pycache__/cmdoptions.cpython-37.pyc | Bin 0 -> 16897 bytes .../__pycache__/main_parser.cpython-37.pyc | Bin 0 -> 2367 bytes .../cli/__pycache__/parser.cpython-37.pyc | Bin 0 -> 8945 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 410 bytes .../pip/_internal/cli/autocompletion.py | 152 + .../pip/_internal/cli/base_command.py | 341 + .../pip/_internal/cli/cmdoptions.py | 809 ++ .../pip/_internal/cli/main_parser.py | 104 + .../site-packages/pip/_internal/cli/parser.py | 261 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 79 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2509 bytes .../commands/__pycache__/check.cpython-37.pyc | Bin 0 -> 1334 bytes .../__pycache__/completion.cpython-37.pyc | Bin 0 -> 3083 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 6435 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 4722 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 2879 bytes .../commands/__pycache__/hash.cpython-37.pyc | Bin 0 -> 2073 bytes .../commands/__pycache__/help.cpython-37.pyc | Bin 0 -> 1249 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 12466 bytes .../commands/__pycache__/list.cpython-37.pyc | Bin 0 -> 8715 bytes .../__pycache__/search.cpython-37.pyc | Bin 0 -> 4315 bytes .../commands/__pycache__/show.cpython-37.pyc | Bin 0 -> 5896 bytes .../__pycache__/uninstall.cpython-37.pyc | Bin 0 -> 2705 bytes .../commands/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 5008 bytes .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 176 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 37 + .../pip/_internal/commands/install.py | 566 ++ .../pip/_internal/commands/list.py | 301 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 78 + .../pip/_internal/commands/wheel.py | 186 + .../pip/_internal/configuration.py | 387 + .../site-packages/pip/_internal/download.py | 971 ++ .../site-packages/pip/_internal/exceptions.py | 274 + .../site-packages/pip/_internal/index.py | 990 ++ .../site-packages/pip/_internal/locations.py | 211 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 269 bytes .../__pycache__/candidate.cpython-37.pyc | Bin 0 -> 1318 bytes .../__pycache__/format_control.cpython-37.pyc | Bin 0 -> 2272 bytes .../models/__pycache__/index.cpython-37.pyc | Bin 0 -> 1173 bytes .../models/__pycache__/link.cpython-37.pyc | Bin 0 -> 5007 bytes .../pip/_internal/models/candidate.py | 31 + .../pip/_internal/models/format_control.py | 73 + .../pip/_internal/models/index.py | 31 + .../pip/_internal/models/link.py | 163 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 205 bytes .../__pycache__/check.cpython-37.pyc | Bin 0 -> 3635 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 5620 bytes .../__pycache__/prepare.cpython-37.pyc | Bin 0 -> 10281 bytes .../pip/_internal/operations/check.py | 155 + .../pip/_internal/operations/freeze.py | 247 + .../pip/_internal/operations/prepare.py | 413 + .../site-packages/pip/_internal/pep425tags.py | 381 + .../site-packages/pip/_internal/pyproject.py | 171 + .../pip/_internal/req/__init__.py | 77 + .../req/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1702 bytes .../__pycache__/constructors.cpython-37.pyc | Bin 0 -> 7622 bytes .../req/__pycache__/req_file.cpython-37.pyc | Bin 0 -> 9200 bytes .../__pycache__/req_install.cpython-37.pyc | Bin 0 -> 25037 bytes .../req/__pycache__/req_set.cpython-37.pyc | Bin 0 -> 6037 bytes .../__pycache__/req_tracker.cpython-37.pyc | Bin 0 -> 3151 bytes .../__pycache__/req_uninstall.cpython-37.pyc | Bin 0 -> 16994 bytes .../pip/_internal/req/constructors.py | 339 + .../pip/_internal/req/req_file.py | 382 + .../pip/_internal/req/req_install.py | 1021 ++ .../pip/_internal/req/req_set.py | 197 + .../pip/_internal/req/req_tracker.py | 88 + .../pip/_internal/req/req_uninstall.py | 596 ++ .../site-packages/pip/_internal/resolve.py | 393 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 200 bytes .../utils/__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 8047 bytes .../utils/__pycache__/compat.cpython-37.pyc | Bin 0 -> 6148 bytes .../__pycache__/deprecation.cpython-37.pyc | Bin 0 -> 2574 bytes .../utils/__pycache__/encoding.cpython-37.pyc | Bin 0 -> 1277 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 669 bytes .../utils/__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1688 bytes .../utils/__pycache__/hashes.cpython-37.pyc | Bin 0 -> 3607 bytes .../utils/__pycache__/logging.cpython-37.pyc | Bin 0 -> 7834 bytes .../utils/__pycache__/misc.cpython-37.pyc | Bin 0 -> 25739 bytes .../utils/__pycache__/models.cpython-37.pyc | Bin 0 -> 1949 bytes .../utils/__pycache__/outdated.cpython-37.pyc | Bin 0 -> 4085 bytes .../__pycache__/packaging.cpython-37.pyc | Bin 0 -> 2621 bytes .../setuptools_build.cpython-37.pyc | Bin 0 -> 395 bytes .../utils/__pycache__/temp_dir.cpython-37.pyc | Bin 0 -> 4922 bytes .../utils/__pycache__/typing.cpython-37.pyc | Bin 0 -> 1344 bytes .../utils/__pycache__/ui.cpython-37.pyc | Bin 0 -> 12306 bytes .../pip/_internal/utils/appdirs.py | 270 + .../pip/_internal/utils/compat.py | 264 + .../pip/_internal/utils/deprecation.py | 90 + .../pip/_internal/utils/encoding.py | 39 + .../pip/_internal/utils/filesystem.py | 30 + .../pip/_internal/utils/glibc.py | 93 + .../pip/_internal/utils/hashes.py | 115 + .../pip/_internal/utils/logging.py | 318 + .../site-packages/pip/_internal/utils/misc.py | 1040 +++ .../pip/_internal/utils/models.py | 40 + .../pip/_internal/utils/outdated.py | 164 + .../pip/_internal/utils/packaging.py | 85 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 155 + .../pip/_internal/utils/typing.py | 29 + .../site-packages/pip/_internal/utils/ui.py | 441 + .../pip/_internal/vcs/__init__.py | 534 ++ .../vcs/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 15391 bytes .../vcs/__pycache__/bazaar.cpython-37.pyc | Bin 0 -> 3808 bytes .../vcs/__pycache__/git.cpython-37.pyc | Bin 0 -> 9450 bytes .../vcs/__pycache__/mercurial.cpython-37.pyc | Bin 0 -> 3781 bytes .../vcs/__pycache__/subversion.cpython-37.pyc | Bin 0 -> 5993 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 114 + .../site-packages/pip/_internal/vcs/git.py | 369 + .../pip/_internal/vcs/mercurial.py | 103 + .../pip/_internal/vcs/subversion.py | 200 + .../site-packages/pip/_internal/wheel.py | 1095 +++ .../site-packages/pip/_vendor/__init__.py | 111 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2888 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20617 bytes .../_vendor/__pycache__/distro.cpython-37.pyc | Bin 0 -> 36150 bytes .../__pycache__/ipaddress.cpython-37.pyc | Bin 0 -> 66460 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 220615 bytes .../__pycache__/retrying.cpython-37.pyc | Bin 0 -> 8098 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 26422 bytes .../site-packages/pip/_vendor/appdirs.py | 604 ++ .../pip/_vendor/cachecontrol/__init__.py | 11 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 558 bytes .../__pycache__/_cmd.cpython-37.pyc | Bin 0 -> 1561 bytes .../__pycache__/adapter.cpython-37.pyc | Bin 0 -> 3044 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 1774 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 765 bytes .../__pycache__/controller.cpython-37.pyc | Bin 0 -> 7644 bytes .../__pycache__/filewrapper.cpython-37.pyc | Bin 0 -> 2162 bytes .../__pycache__/heuristics.cpython-37.pyc | Bin 0 -> 4682 bytes .../__pycache__/serialize.cpython-37.pyc | Bin 0 -> 4246 bytes .../__pycache__/wrapper.cpython-37.pyc | Bin 0 -> 666 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 -> 302 bytes .../__pycache__/file_cache.cpython-37.pyc | Bin 0 -> 3236 bytes .../__pycache__/redis_cache.cpython-37.pyc | Bin 0 -> 1558 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 -> 265 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 0 -> 268 bytes .../certifi/__pycache__/core.cpython-37.pyc | Bin 0 -> 526 bytes .../pip/_vendor/certifi/cacert.pem | 4512 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 20 + .../pip/_vendor/chardet/__init__.py | 39 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 852 bytes .../__pycache__/big5freq.cpython-37.pyc | Bin 0 -> 27187 bytes .../__pycache__/big5prober.cpython-37.pyc | Bin 0 -> 1128 bytes .../chardistribution.cpython-37.pyc | Bin 0 -> 6314 bytes .../charsetgroupprober.cpython-37.pyc | Bin 0 -> 2235 bytes .../__pycache__/charsetprober.cpython-37.pyc | Bin 0 -> 3445 bytes .../codingstatemachine.cpython-37.pyc | Bin 0 -> 2892 bytes .../chardet/__pycache__/compat.cpython-37.pyc | Bin 0 -> 363 bytes .../__pycache__/cp949prober.cpython-37.pyc | Bin 0 -> 1135 bytes .../chardet/__pycache__/enums.cpython-37.pyc | Bin 0 -> 2626 bytes .../__pycache__/escprober.cpython-37.pyc | Bin 0 -> 2613 bytes .../chardet/__pycache__/escsm.cpython-37.pyc | Bin 0 -> 7074 bytes .../__pycache__/eucjpprober.cpython-37.pyc | Bin 0 -> 2421 bytes .../__pycache__/euckrfreq.cpython-37.pyc | Bin 0 -> 12071 bytes .../__pycache__/euckrprober.cpython-37.pyc | Bin 0 -> 1136 bytes .../__pycache__/euctwfreq.cpython-37.pyc | Bin 0 -> 27191 bytes .../__pycache__/euctwprober.cpython-37.pyc | Bin 0 -> 1136 bytes .../__pycache__/gb2312freq.cpython-37.pyc | Bin 0 -> 19115 bytes .../__pycache__/gb2312prober.cpython-37.pyc | Bin 0 -> 1144 bytes .../__pycache__/hebrewprober.cpython-37.pyc | Bin 0 -> 2978 bytes .../__pycache__/jisfreq.cpython-37.pyc | Bin 0 -> 22143 bytes .../chardet/__pycache__/jpcntx.cpython-37.pyc | Bin 0 -> 38022 bytes .../langbulgarianmodel.cpython-37.pyc | Bin 0 -> 23636 bytes .../langcyrillicmodel.cpython-37.pyc | Bin 0 -> 29092 bytes .../__pycache__/langgreekmodel.cpython-37.pyc | Bin 0 -> 23594 bytes .../langhebrewmodel.cpython-37.pyc | Bin 0 -> 22223 bytes .../langhungarianmodel.cpython-37.pyc | Bin 0 -> 23625 bytes .../__pycache__/langthaimodel.cpython-37.pyc | Bin 0 -> 22202 bytes .../langturkishmodel.cpython-37.pyc | Bin 0 -> 22225 bytes .../__pycache__/latin1prober.cpython-37.pyc | Bin 0 -> 2935 bytes .../mbcharsetprober.cpython-37.pyc | Bin 0 -> 2240 bytes .../mbcsgroupprober.cpython-37.pyc | Bin 0 -> 1131 bytes .../chardet/__pycache__/mbcssm.cpython-37.pyc | Bin 0 -> 15686 bytes .../sbcharsetprober.cpython-37.pyc | Bin 0 -> 2993 bytes .../sbcsgroupprober.cpython-37.pyc | Bin 0 -> 1621 bytes .../__pycache__/sjisprober.cpython-37.pyc | Bin 0 -> 2447 bytes .../universaldetector.cpython-37.pyc | Bin 0 -> 5837 bytes .../__pycache__/utf8prober.cpython-37.pyc | Bin 0 -> 1978 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 447 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 -> 204 bytes .../cli/__pycache__/chardetect.cpython-37.pyc | Bin 0 -> 2693 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 | 6 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 452 bytes .../colorama/__pycache__/ansi.cpython-37.pyc | Bin 0 -> 3350 bytes .../__pycache__/ansitowin32.cpython-37.pyc | Bin 0 -> 7606 bytes .../__pycache__/initialise.cpython-37.pyc | Bin 0 -> 1671 bytes .../colorama/__pycache__/win32.cpython-37.pyc | Bin 0 -> 3865 bytes .../__pycache__/winterm.cpython-37.pyc | Bin 0 -> 4613 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 257 + .../pip/_vendor/colorama/initialise.py | 80 + .../pip/_vendor/colorama/win32.py | 152 + .../pip/_vendor/colorama/winterm.py | 169 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1050 bytes .../distlib/__pycache__/compat.cpython-37.pyc | Bin 0 -> 32060 bytes .../__pycache__/database.cpython-37.pyc | Bin 0 -> 42581 bytes .../distlib/__pycache__/index.cpython-37.pyc | Bin 0 -> 17346 bytes .../__pycache__/locators.cpython-37.pyc | Bin 0 -> 38732 bytes .../__pycache__/manifest.cpython-37.pyc | Bin 0 -> 10298 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 4484 bytes .../__pycache__/metadata.cpython-37.pyc | Bin 0 -> 27694 bytes .../__pycache__/resources.cpython-37.pyc | Bin 0 -> 10894 bytes .../__pycache__/scripts.cpython-37.pyc | Bin 0 -> 11084 bytes .../distlib/__pycache__/util.cpython-37.pyc | Bin 0 -> 47962 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 20434 bytes .../distlib/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 25370 bytes .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 492 bytes .../_backport/__pycache__/misc.cpython-37.pyc | Bin 0 -> 1089 bytes .../__pycache__/shutil.cpython-37.pyc | Bin 0 -> 21405 bytes .../__pycache__/sysconfig.cpython-37.pyc | Bin 0 -> 15870 bytes .../__pycache__/tarfile.cpython-37.pyc | Bin 0 -> 62735 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 | 1339 +++ .../pip/_vendor/distlib/index.py | 516 ++ .../pip/_vendor/distlib/locators.py | 1295 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1094 +++ .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 417 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 92672 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 102400 bytes .../site-packages/pip/_vendor/distlib/util.py | 1756 ++++ .../pip/_vendor/distlib/version.py | 736 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 89088 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 99328 bytes .../pip/_vendor/distlib/wheel.py | 988 ++ .../site-packages/pip/_vendor/distro.py | 1197 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1321 bytes .../__pycache__/_ihatexml.cpython-37.pyc | Bin 0 -> 13768 bytes .../__pycache__/_inputstream.cpython-37.pyc | Bin 0 -> 22659 bytes .../__pycache__/_tokenizer.cpython-37.pyc | Bin 0 -> 41560 bytes .../__pycache__/_utils.cpython-37.pyc | Bin 0 -> 3313 bytes .../__pycache__/constants.cpython-37.pyc | Bin 0 -> 66225 bytes .../__pycache__/html5parser.cpython-37.pyc | Bin 0 -> 97822 bytes .../__pycache__/serializer.cpython-37.pyc | Bin 0 -> 10838 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 -> 434 bytes .../_trie/__pycache__/_base.cpython-37.pyc | Bin 0 -> 1517 bytes .../_trie/__pycache__/datrie.cpython-37.pyc | Bin 0 -> 2036 bytes .../_trie/__pycache__/py.cpython-37.pyc | Bin 0 -> 2239 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 -> 209 bytes .../alphabeticalattributes.cpython-37.pyc | Bin 0 -> 1325 bytes .../filters/__pycache__/base.cpython-37.pyc | Bin 0 -> 859 bytes .../inject_meta_charset.cpython-37.pyc | Bin 0 -> 1879 bytes .../filters/__pycache__/lint.cpython-37.pyc | Bin 0 -> 2643 bytes .../__pycache__/optionaltags.cpython-37.pyc | Bin 0 -> 2770 bytes .../__pycache__/sanitizer.cpython-37.pyc | Bin 0 -> 16445 bytes .../__pycache__/whitespace.cpython-37.pyc | Bin 0 -> 1363 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 -> 948 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1545 bytes .../__pycache__/sax.cpython-37.pyc | Bin 0 -> 1495 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 -> 3329 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 11252 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 9282 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 11861 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 11801 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 -> 4006 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 7002 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 1731 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 3538 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 6647 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1905 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 -> 266 bytes .../idna/__pycache__/codec.cpython-37.pyc | Bin 0 -> 3073 bytes .../idna/__pycache__/compat.cpython-37.pyc | Bin 0 -> 626 bytes .../idna/__pycache__/core.cpython-37.pyc | Bin 0 -> 9069 bytes .../idna/__pycache__/idnadata.cpython-37.pyc | Bin 0 -> 21440 bytes .../idna/__pycache__/intranges.cpython-37.pyc | Bin 0 -> 1806 bytes .../__pycache__/package_data.cpython-37.pyc | Bin 0 -> 220 bytes .../idna/__pycache__/uts46data.cpython-37.pyc | Bin 0 -> 176100 bytes .../site-packages/pip/_vendor/idna/codec.py | 118 + .../site-packages/pip/_vendor/idna/compat.py | 12 + .../site-packages/pip/_vendor/idna/core.py | 396 + .../pip/_vendor/idna/idnadata.py | 1979 ++++ .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8205 +++++++++++++++++ .../site-packages/pip/_vendor/ipaddress.py | 2419 +++++ .../pip/_vendor/lockfile/__init__.py | 347 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9916 bytes .../__pycache__/linklockfile.cpython-37.pyc | Bin 0 -> 2297 bytes .../__pycache__/mkdirlockfile.cpython-37.pyc | Bin 0 -> 2659 bytes .../__pycache__/pidlockfile.cpython-37.pyc | Bin 0 -> 4859 bytes .../__pycache__/sqlitelockfile.cpython-37.pyc | Bin 0 -> 3758 bytes .../symlinklockfile.cpython-37.pyc | Bin 0 -> 2182 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 -> 2078 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 227 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 2183 bytes .../__pycache__/fallback.cpython-37.pyc | Bin 0 -> 24555 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 41 + .../pip/_vendor/msgpack/fallback.py | 977 ++ .../pip/_vendor/packaging/__about__.py | 27 + .../pip/_vendor/packaging/__init__.py | 26 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 740 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 578 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1018 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2870 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8873 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3991 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19768 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 1456 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 11960 bytes .../pip/_vendor/packaging/_compat.py | 31 + .../pip/_vendor/packaging/_structures.py | 68 + .../pip/_vendor/packaging/markers.py | 296 + .../pip/_vendor/packaging/requirements.py | 138 + .../pip/_vendor/packaging/specifiers.py | 749 ++ .../pip/_vendor/packaging/utils.py | 57 + .../pip/_vendor/packaging/version.py | 420 + .../pip/_vendor/pep517/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 291 bytes .../__pycache__/_in_process.cpython-37.pyc | Bin 0 -> 5634 bytes .../pep517/__pycache__/build.cpython-37.pyc | Bin 0 -> 2769 bytes .../pep517/__pycache__/check.cpython-37.pyc | Bin 0 -> 4817 bytes .../__pycache__/colorlog.cpython-37.pyc | Bin 0 -> 2923 bytes .../pep517/__pycache__/compat.cpython-37.pyc | Bin 0 -> 1027 bytes .../__pycache__/envbuild.cpython-37.pyc | Bin 0 -> 4211 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 5492 bytes .../pip/_vendor/pep517/_in_process.py | 207 + .../site-packages/pip/_vendor/pep517/build.py | 108 + .../site-packages/pip/_vendor/pep517/check.py | 202 + .../pip/_vendor/pep517/colorlog.py | 115 + .../pip/_vendor/pep517/compat.py | 23 + .../pip/_vendor/pep517/envbuild.py | 158 + .../pip/_vendor/pep517/wrappers.py | 163 + .../pip/_vendor/pkg_resources/__init__.py | 3171 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 96828 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 651 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/progress/__init__.py | 127 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3919 bytes .../progress/__pycache__/bar.cpython-37.pyc | Bin 0 -> 2741 bytes .../__pycache__/counter.cpython-37.pyc | Bin 0 -> 1583 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 0 -> 3025 bytes .../__pycache__/spinner.cpython-37.pyc | Bin 0 -> 1500 bytes .../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 + .../site-packages/pip/_vendor/pyparsing.py | 6452 +++++++++++++ .../pip/_vendor/pytoml/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 385 bytes .../pytoml/__pycache__/core.cpython-37.pyc | Bin 0 -> 948 bytes .../pytoml/__pycache__/parser.cpython-37.pyc | Bin 0 -> 10065 bytes .../pytoml/__pycache__/test.cpython-37.pyc | Bin 0 -> 1248 bytes .../pytoml/__pycache__/utils.cpython-37.pyc | Bin 0 -> 2147 bytes .../pytoml/__pycache__/writer.cpython-37.pyc | Bin 0 -> 3582 bytes .../site-packages/pip/_vendor/pytoml/core.py | 13 + .../pip/_vendor/pytoml/parser.py | 341 + .../site-packages/pip/_vendor/pytoml/test.py | 30 + .../site-packages/pip/_vendor/pytoml/utils.py | 67 + .../pip/_vendor/pytoml/writer.py | 106 + .../pip/_vendor/requests/__init__.py | 133 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3496 bytes .../__pycache__/__version__.cpython-37.pyc | Bin 0 -> 559 bytes .../_internal_utils.cpython-37.pyc | Bin 0 -> 1317 bytes .../__pycache__/adapters.cpython-37.pyc | Bin 0 -> 16894 bytes .../requests/__pycache__/api.cpython-37.pyc | Bin 0 -> 6500 bytes .../requests/__pycache__/auth.cpython-37.pyc | Bin 0 -> 8351 bytes .../requests/__pycache__/certs.cpython-37.pyc | Bin 0 -> 642 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 1621 bytes .../__pycache__/cookies.cpython-37.pyc | Bin 0 -> 18796 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 5514 bytes .../requests/__pycache__/help.cpython-37.pyc | Bin 0 -> 2695 bytes .../requests/__pycache__/hooks.cpython-37.pyc | Bin 0 -> 989 bytes .../__pycache__/models.cpython-37.pyc | Bin 0 -> 24117 bytes .../__pycache__/packages.cpython-37.pyc | Bin 0 -> 519 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 0 -> 19437 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 4175 bytes .../__pycache__/structures.cpython-37.pyc | Bin 0 -> 4388 bytes .../requests/__pycache__/utils.cpython-37.pyc | Bin 0 -> 22048 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 533 ++ .../site-packages/pip/_vendor/requests/api.py | 158 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 74 + .../pip/_vendor/requests/cookies.py | 549 ++ .../pip/_vendor/requests/exceptions.py | 126 + .../pip/_vendor/requests/help.py | 119 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 953 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 770 ++ .../pip/_vendor/requests/status_codes.py | 120 + .../pip/_vendor/requests/structures.py | 103 + .../pip/_vendor/requests/utils.py | 977 ++ .../site-packages/pip/_vendor/retrying.py | 267 + .../site-packages/pip/_vendor/six.py | 952 ++ .../pip/_vendor/urllib3/__init__.py | 92 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2124 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 0 -> 10688 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 10157 bytes .../__pycache__/connectionpool.cpython-37.pyc | Bin 0 -> 23662 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 10409 bytes .../urllib3/__pycache__/fields.cpython-37.pyc | Bin 0 -> 5877 bytes .../__pycache__/filepost.cpython-37.pyc | Bin 0 -> 2769 bytes .../__pycache__/poolmanager.cpython-37.pyc | Bin 0 -> 12729 bytes .../__pycache__/request.cpython-37.pyc | Bin 0 -> 5591 bytes .../__pycache__/response.cpython-37.pyc | Bin 0 -> 18756 bytes .../pip/_vendor/urllib3/_collections.py | 329 + .../pip/_vendor/urllib3/connection.py | 391 + .../pip/_vendor/urllib3/connectionpool.py | 896 ++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 208 bytes .../_appengine_environ.cpython-37.pyc | Bin 0 -> 1104 bytes .../__pycache__/appengine.cpython-37.pyc | Bin 0 -> 8323 bytes .../__pycache__/ntlmpool.cpython-37.pyc | Bin 0 -> 3250 bytes .../__pycache__/pyopenssl.cpython-37.pyc | Bin 0 -> 14486 bytes .../securetransport.cpython-37.pyc | Bin 0 -> 17905 bytes .../contrib/__pycache__/socks.cpython-37.pyc | Bin 0 -> 4914 bytes .../urllib3/contrib/_appengine_environ.py | 30 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 225 bytes .../__pycache__/bindings.cpython-37.pyc | Bin 0 -> 10320 bytes .../__pycache__/low_level.cpython-37.pyc | Bin 0 -> 7501 bytes .../contrib/_securetransport/bindings.py | 593 ++ .../contrib/_securetransport/low_level.py | 346 + .../pip/_vendor/urllib3/contrib/appengine.py | 289 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 111 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 466 + .../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 -> 322 bytes .../packages/__pycache__/six.cpython-37.pyc | Bin 0 -> 24410 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 219 bytes .../__pycache__/makefile.cpython-37.pyc | Bin 0 -> 1313 bytes .../urllib3/packages/backports/makefile.py | 53 + .../pip/_vendor/urllib3/packages/six.py | 868 ++ .../packages/ssl_match_hostname/__init__.py | 19 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 563 bytes .../_implementation.cpython-37.pyc | Bin 0 -> 3322 bytes .../ssl_match_hostname/_implementation.py | 156 + .../pip/_vendor/urllib3/poolmanager.py | 450 + .../pip/_vendor/urllib3/request.py | 150 + .../pip/_vendor/urllib3/response.py | 705 ++ .../pip/_vendor/urllib3/util/__init__.py | 54 + .../util/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1000 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 3175 bytes .../util/__pycache__/queue.cpython-37.pyc | Bin 0 -> 1049 bytes .../util/__pycache__/request.cpython-37.pyc | Bin 0 -> 3230 bytes .../util/__pycache__/response.cpython-37.pyc | Bin 0 -> 1978 bytes .../util/__pycache__/retry.cpython-37.pyc | Bin 0 -> 12664 bytes .../util/__pycache__/ssl_.cpython-37.pyc | Bin 0 -> 9556 bytes .../util/__pycache__/timeout.cpython-37.pyc | Bin 0 -> 8779 bytes .../util/__pycache__/url.cpython-37.pyc | Bin 0 -> 5189 bytes .../util/__pycache__/wait.cpython-37.pyc | Bin 0 -> 3141 bytes .../pip/_vendor/urllib3/util/connection.py | 134 + .../pip/_vendor/urllib3/util/queue.py | 21 + .../pip/_vendor/urllib3/util/request.py | 118 + .../pip/_vendor/urllib3/util/response.py | 87 + .../pip/_vendor/urllib3/util/retry.py | 411 + .../pip/_vendor/urllib3/util/ssl_.py | 381 + .../pip/_vendor/urllib3/util/timeout.py | 242 + .../pip/_vendor/urllib3/util/url.py | 230 + .../pip/_vendor/urllib3/util/wait.py | 150 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9684 bytes .../__pycache__/labels.cpython-37.pyc | Bin 0 -> 4098 bytes .../__pycache__/mklabels.cpython-37.pyc | Bin 0 -> 1920 bytes .../__pycache__/tests.cpython-37.pyc | Bin 0 -> 5061 bytes .../__pycache__/x_user_defined.cpython-37.pyc | Bin 0 -> 2673 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 + .../site-packages/pkg_resources/__init__.py | 3236 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 98573 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 646 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 209 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20697 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203052 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24410 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 745 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 583 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1035 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2887 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8895 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3900 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19813 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 514 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10580 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 | 5742 ++++++++++++ .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2428 bytes .../site-packages/pkg_resources/py31compat.py | 23 + .../pylint-2.3.1.dist-info/INSTALLER | 1 + .../pylint-2.3.1.dist-info/METADATA | 138 + .../pylint-2.3.1.dist-info/RECORD | 1631 ++++ .../pylint-2.3.1.dist-info/WHEEL | 5 + .../pylint-2.3.1.dist-info/entry_points.txt | 6 + .../pylint-2.3.1.dist-info/top_level.txt | 1 + .../site-packages/pylint/__init__.py | 43 + .../site-packages/pylint/__main__.py | 8 + .../site-packages/pylint/__pkginfo__.py | 93 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1097 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 0 -> 230 bytes .../__pycache__/__pkginfo__.cpython-37.pyc | Bin 0 -> 2831 bytes .../pylint/__pycache__/config.cpython-37.pyc | Bin 0 -> 25925 bytes .../pylint/__pycache__/epylint.cpython-37.pyc | Bin 0 -> 4994 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 1149 bytes .../pylint/__pycache__/graph.cpython-37.pyc | Bin 0 -> 5236 bytes .../__pycache__/interfaces.cpython-37.pyc | Bin 0 -> 3685 bytes .../pylint/__pycache__/lint.cpython-37.pyc | Bin 0 -> 42854 bytes .../__pycache__/testutils.cpython-37.pyc | Bin 0 -> 9656 bytes .../pylint/__pycache__/utils.cpython-37.pyc | Bin 0 -> 41829 bytes .../site-packages/pylint/checkers/__init__.py | 134 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3594 bytes .../checkers/__pycache__/async.cpython-37.pyc | Bin 0 -> 2771 bytes .../checkers/__pycache__/base.cpython-37.pyc | Bin 0 -> 58787 bytes .../__pycache__/classes.cpython-37.pyc | Bin 0 -> 41856 bytes .../design_analysis.cpython-37.pyc | Bin 0 -> 12522 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 15921 bytes .../__pycache__/format.cpython-37.pyc | Bin 0 -> 31882 bytes .../__pycache__/imports.cpython-37.pyc | Bin 0 -> 24157 bytes .../__pycache__/logging.cpython-37.pyc | Bin 0 -> 10959 bytes .../checkers/__pycache__/misc.cpython-37.pyc | Bin 0 -> 4900 bytes .../__pycache__/newstyle.cpython-37.pyc | Bin 0 -> 2745 bytes .../__pycache__/python3.cpython-37.pyc | Bin 0 -> 35123 bytes .../__pycache__/raw_metrics.cpython-37.pyc | Bin 0 -> 3418 bytes .../__pycache__/refactoring.cpython-37.pyc | Bin 0 -> 41927 bytes .../__pycache__/similar.cpython-37.pyc | Bin 0 -> 12223 bytes .../__pycache__/spelling.cpython-37.pyc | Bin 0 -> 9587 bytes .../__pycache__/stdlib.cpython-37.pyc | Bin 0 -> 11996 bytes .../__pycache__/strings.cpython-37.pyc | Bin 0 -> 17565 bytes .../__pycache__/typecheck.cpython-37.pyc | Bin 0 -> 37657 bytes .../checkers/__pycache__/utils.cpython-37.pyc | Bin 0 -> 29865 bytes .../__pycache__/variables.cpython-37.pyc | Bin 0 -> 42644 bytes .../site-packages/pylint/checkers/async.py | 92 + .../site-packages/pylint/checkers/base.py | 2222 +++++ .../site-packages/pylint/checkers/classes.py | 1750 ++++ .../pylint/checkers/design_analysis.py | 530 ++ .../pylint/checkers/exceptions.py | 561 ++ .../site-packages/pylint/checkers/format.py | 1343 +++ .../site-packages/pylint/checkers/imports.py | 934 ++ .../site-packages/pylint/checkers/logging.py | 375 + .../site-packages/pylint/checkers/misc.py | 182 + .../site-packages/pylint/checkers/newstyle.py | 142 + .../site-packages/pylint/checkers/python3.py | 1398 +++ .../pylint/checkers/raw_metrics.py | 125 + .../pylint/checkers/refactoring.py | 1444 +++ .../site-packages/pylint/checkers/similar.py | 449 + .../site-packages/pylint/checkers/spelling.py | 403 + .../site-packages/pylint/checkers/stdlib.py | 441 + .../site-packages/pylint/checkers/strings.py | 763 ++ .../pylint/checkers/typecheck.py | 1644 ++++ .../site-packages/pylint/checkers/utils.py | 1211 +++ .../pylint/checkers/variables.py | 1858 ++++ .../python3.7/site-packages/pylint/config.py | 931 ++ .../python3.7/site-packages/pylint/epylint.py | 196 + .../site-packages/pylint/exceptions.py | 25 + .../pylint/extensions/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 201 bytes .../_check_docs_utils.cpython-37.pyc | Bin 0 -> 18907 bytes .../__pycache__/bad_builtin.cpython-37.pyc | Bin 0 -> 2067 bytes .../__pycache__/check_docs.cpython-37.pyc | Bin 0 -> 705 bytes .../__pycache__/check_elif.cpython-37.pyc | Bin 0 -> 2614 bytes .../__pycache__/comparetozero.cpython-37.pyc | Bin 0 -> 1991 bytes .../__pycache__/docparams.cpython-37.pyc | Bin 0 -> 14564 bytes .../__pycache__/docstyle.cpython-37.pyc | Bin 0 -> 2523 bytes .../__pycache__/emptystring.cpython-37.pyc | Bin 0 -> 2067 bytes .../__pycache__/mccabe.cpython-37.pyc | Bin 0 -> 5635 bytes .../overlapping_exceptions.cpython-37.pyc | Bin 0 -> 2636 bytes .../redefined_variable_type.cpython-37.pyc | Bin 0 -> 3268 bytes .../pylint/extensions/_check_docs_utils.py | 794 ++ .../pylint/extensions/bad_builtin.py | 73 + .../pylint/extensions/check_docs.py | 23 + .../pylint/extensions/check_elif.py | 74 + .../pylint/extensions/comparetozero.py | 75 + .../pylint/extensions/docparams.py | 498 + .../pylint/extensions/docstyle.py | 89 + .../pylint/extensions/emptystring.py | 75 + .../site-packages/pylint/extensions/mccabe.py | 201 + .../extensions/overlapping_exceptions.py | 90 + .../extensions/redefined_variable_type.py | 116 + .../python3.7/site-packages/pylint/graph.py | 198 + .../site-packages/pylint/interfaces.py | 102 + .../python3.7/site-packages/pylint/lint.py | 1711 ++++ .../pylint/pyreverse/__init__.py | 9 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 261 bytes .../__pycache__/diadefslib.cpython-37.pyc | Bin 0 -> 7641 bytes .../__pycache__/diagrams.cpython-37.pyc | Bin 0 -> 8736 bytes .../__pycache__/inspector.cpython-37.pyc | Bin 0 -> 10304 bytes .../pyreverse/__pycache__/main.cpython-37.pyc | Bin 0 -> 4591 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 5842 bytes .../__pycache__/vcgutils.cpython-37.pyc | Bin 0 -> 4717 bytes .../__pycache__/writer.cpython-37.pyc | Bin 0 -> 7108 bytes .../pylint/pyreverse/diadefslib.py | 238 + .../pylint/pyreverse/diagrams.py | 267 + .../pylint/pyreverse/inspector.py | 368 + .../site-packages/pylint/pyreverse/main.py | 221 + .../site-packages/pylint/pyreverse/utils.py | 221 + .../pylint/pyreverse/vcgutils.py | 229 + .../site-packages/pylint/pyreverse/writer.py | 212 + .../pylint/reporters/__init__.py | 124 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4141 bytes .../reporters/__pycache__/json.cpython-37.pyc | Bin 0 -> 2075 bytes .../reporters/__pycache__/text.cpython-37.pyc | Bin 0 -> 7332 bytes .../site-packages/pylint/reporters/json.py | 60 + .../site-packages/pylint/reporters/text.py | 250 + .../pylint/reporters/ureports/__init__.py | 97 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3085 bytes .../ureports/__pycache__/nodes.cpython-37.pyc | Bin 0 -> 6082 bytes .../__pycache__/text_writer.cpython-37.pyc | Bin 0 -> 3742 bytes .../pylint/reporters/ureports/nodes.py | 188 + .../pylint/reporters/ureports/text_writer.py | 97 + .../test/__pycache__/conftest.cpython-37.pyc | Bin 0 -> 1334 bytes .../test/__pycache__/test_func.cpython-37.pyc | Bin 0 -> 4447 bytes .../test_functional.cpython-37.pyc | Bin 0 -> 13040 bytes .../test_import_graph.cpython-37.pyc | Bin 0 -> 2012 bytes .../test/__pycache__/test_regr.cpython-37.pyc | Bin 0 -> 4236 bytes .../test/__pycache__/test_self.cpython-37.pyc | Bin 0 -> 19971 bytes .../unittest_checker_base.cpython-37.pyc | Bin 0 -> 14537 bytes .../unittest_checker_classes.cpython-37.pyc | Bin 0 -> 3521 bytes ...unittest_checker_exceptions.cpython-37.pyc | Bin 0 -> 1529 bytes .../unittest_checker_format.cpython-37.pyc | Bin 0 -> 12722 bytes .../unittest_checker_imports.cpython-37.pyc | Bin 0 -> 3634 bytes .../unittest_checker_logging.cpython-37.pyc | Bin 0 -> 5064 bytes .../unittest_checker_misc.cpython-37.pyc | Bin 0 -> 4209 bytes .../unittest_checker_python3.cpython-37.pyc | Bin 0 -> 43067 bytes .../unittest_checker_similar.cpython-37.pyc | Bin 0 -> 4491 bytes .../unittest_checker_spelling.cpython-37.pyc | Bin 0 -> 8035 bytes .../unittest_checker_stdlib.cpython-37.pyc | Bin 0 -> 3267 bytes .../unittest_checker_strings.cpython-37.pyc | Bin 0 -> 2182 bytes .../unittest_checker_typecheck.cpython-37.pyc | Bin 0 -> 9862 bytes .../unittest_checker_variables.cpython-37.pyc | Bin 0 -> 8844 bytes .../unittest_checkers_utils.cpython-37.pyc | Bin 0 -> 4441 bytes .../unittest_config.cpython-37.pyc | Bin 0 -> 2074 bytes .../__pycache__/unittest_lint.cpython-37.pyc | Bin 0 -> 25810 bytes .../unittest_pyreverse_diadefs.cpython-37.pyc | Bin 0 -> 5688 bytes ...nittest_pyreverse_inspector.cpython-37.pyc | Bin 0 -> 4259 bytes .../unittest_pyreverse_writer.cpython-37.pyc | Bin 0 -> 3898 bytes .../unittest_reporters_json.cpython-37.pyc | Bin 0 -> 1370 bytes .../unittest_reporting.cpython-37.pyc | Bin 0 -> 2672 bytes .../__pycache__/unittest_utils.cpython-37.pyc | Bin 0 -> 14247 bytes .../__pycache__/test_stdlib.cpython-37.pyc | Bin 0 -> 1688 bytes .../pylint/test/acceptance/test_stdlib.py | 54 + .../site-packages/pylint/test/conftest.py | 53 + .../pylint/test/data/__init__.py | 0 .../data/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 200 bytes .../clientmodule_test.cpython-37.pyc | Bin 0 -> 1474 bytes .../suppliermodule_test.cpython-37.pyc | Bin 0 -> 800 bytes .../site-packages/pylint/test/data/ascript | 2 + .../pylint/test/data/classes_No_Name.dot | 12 + .../pylint/test/data/clientmodule_test.py | 29 + .../pylint/test/data/packages_No_Name.dot | 8 + .../pylint/test/data/suppliermodule_test.py | 10 + .../pylint/test/extensions/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 206 bytes .../test_bad_builtin.cpython-37.pyc | Bin 0 -> 1505 bytes .../test_check_docs.cpython-37.pyc | Bin 0 -> 63314 bytes .../test_check_docs_utils.cpython-37.pyc | Bin 0 -> 2607 bytes .../test_check_mccabe.cpython-37.pyc | Bin 0 -> 2260 bytes .../test_check_raise_docs.cpython-37.pyc | Bin 0 -> 24649 bytes .../test_check_return_docs.cpython-37.pyc | Bin 0 -> 20787 bytes .../test_check_yields_docs.cpython-37.pyc | Bin 0 -> 13790 bytes .../test_comparetozero.cpython-37.pyc | Bin 0 -> 2206 bytes .../__pycache__/test_docstyle.cpython-37.pyc | Bin 0 -> 1442 bytes .../test_elseif_used.cpython-37.pyc | Bin 0 -> 1056 bytes .../test_emptystring.cpython-37.pyc | Bin 0 -> 1240 bytes ...test_overlapping_exceptions.cpython-37.pyc | Bin 0 -> 2928 bytes .../__pycache__/test_redefined.cpython-37.pyc | Bin 0 -> 1830 bytes .../__pycache__/bad_builtin.cpython-37.pyc | Bin 0 -> 281 bytes .../compare_to_zero.cpython-37.pyc | Bin 0 -> 338 bytes .../data/__pycache__/docstring.cpython-37.pyc | Bin 0 -> 1771 bytes .../data/__pycache__/elif.cpython-37.pyc | Bin 0 -> 519 bytes .../empty_string_comparison.cpython-37.pyc | Bin 0 -> 289 bytes .../data/__pycache__/mccabe.cpython-37.pyc | Bin 0 -> 3461 bytes .../overlapping_exceptions.cpython-37.pyc | Bin 0 -> 889 bytes ...overlapping_exceptions_py33.cpython-37.pyc | Bin 0 -> 408 bytes .../data/__pycache__/redefined.cpython-37.pyc | Bin 0 -> 2200 bytes .../test/extensions/data/bad_builtin.py | 4 + .../test/extensions/data/compare_to_zero.py | 28 + .../pylint/test/extensions/data/docstring.py | 40 + .../pylint/test/extensions/data/elif.py | 26 + .../data/empty_string_comparison.py | 16 + .../pylint/test/extensions/data/mccabe.py | 205 + .../extensions/data/overlapping_exceptions.py | 45 + .../data/overlapping_exceptions_py33.py | 18 + .../pylint/test/extensions/data/redefined.py | 85 + .../test/extensions/test_bad_builtin.py | 43 + .../pylint/test/extensions/test_check_docs.py | 2192 +++++ .../test/extensions/test_check_docs_utils.py | 112 + .../test/extensions/test_check_mccabe.py | 63 + .../test/extensions/test_check_raise_docs.py | 781 ++ .../test/extensions/test_check_return_docs.py | 600 ++ .../test/extensions/test_check_yields_docs.py | 397 + .../test/extensions/test_comparetozero.py | 57 + .../pylint/test/extensions/test_docstyle.py | 54 + .../test/extensions/test_elseif_used.py | 33 + .../test/extensions/test_emptystring.py | 39 + .../extensions/test_overlapping_exceptions.py | 69 + .../pylint/test/extensions/test_redefined.py | 50 + .../pylint/test/functional/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 206 bytes .../abstract_abc_methods.cpython-37.pyc | Bin 0 -> 987 bytes ...class_instantiated_in_class.cpython-37.pyc | Bin 0 -> 806 bytes ...ract_class_instantiated_py2.cpython-37.pyc | Bin 0 -> 3125 bytes ...ract_class_instantiated_py3.cpython-37.pyc | Bin 0 -> 5230 bytes ...act_class_instantiated_py34.cpython-37.pyc | Bin 0 -> 775 bytes .../abstract_method_py2.cpython-37.pyc | Bin 0 -> 3693 bytes .../abstract_method_py3.cpython-37.pyc | Bin 0 -> 3689 bytes ...ss_member_before_definition.cpython-37.pyc | Bin 0 -> 1469 bytes .../access_to__name__.cpython-37.pyc | Bin 0 -> 1182 bytes ...access_to_protected_members.cpython-37.pyc | Bin 0 -> 2313 bytes ...nomalous_unicode_escape_py3.cpython-37.pyc | Bin 0 -> 527 bytes .../__pycache__/arguments.cpython-37.pyc | Bin 0 -> 6396 bytes .../arguments_differ.cpython-37.pyc | Bin 0 -> 9101 bytes .../arguments_differ_py3.cpython-37.pyc | Bin 0 -> 2130 bytes .../assert_on_tuple.cpython-37.pyc | Bin 0 -> 464 bytes .../assigning_non_slot.cpython-37.pyc | Bin 0 -> 6105 bytes .../assignment_from_no_return.cpython-37.pyc | Bin 0 -> 1268 bytes ...signment_from_no_return_py3.cpython-37.pyc | Bin 0 -> 1004 bytes ...ribute_defined_outside_init.cpython-37.pyc | Bin 0 -> 2603 bytes .../bad_continuation.cpython-37.pyc | Bin 0 -> 2700 bytes .../bad_continuation_py36.cpython-37.pyc | Bin 0 -> 438 bytes .../bad_continuation_tabs.cpython-37.pyc | Bin 0 -> 1212 bytes .../bad_exception_context.cpython-37.pyc | Bin 0 -> 821 bytes .../bad_indentation.cpython-37.pyc | Bin 0 -> 765 bytes .../bad_inline_option.cpython-37.pyc | Bin 0 -> 323 bytes .../__pycache__/bad_open_mode.cpython-37.pyc | Bin 0 -> 932 bytes .../bad_open_mode_py3.cpython-37.pyc | Bin 0 -> 635 bytes .../bad_reversed_sequence.cpython-37.pyc | Bin 0 -> 3770 bytes .../bad_staticmethod_argument.cpython-37.pyc | Bin 0 -> 737 bytes .../bad_thread_instantiation.cpython-37.pyc | Bin 0 -> 571 bytes .../__pycache__/bad_whitespace.cpython-37.pyc | Bin 0 -> 389 bytes .../__pycache__/bare_except.cpython-37.pyc | Bin 0 -> 249 bytes .../blacklisted_name.cpython-37.pyc | Bin 0 -> 303 bytes .../boolean_datetime.cpython-37.pyc | Bin 0 -> 914 bytes .../__pycache__/broad_except.cpython-37.pyc | Bin 0 -> 424 bytes ..._local_scope_metaclass_1177.cpython-37.pyc | Bin 0 -> 2542 bytes .../cellvar_escaping_loop.cpython-37.pyc | Bin 0 -> 5004 bytes .../class_members_py30.cpython-37.pyc | Bin 0 -> 2999 bytes .../__pycache__/class_scope.cpython-37.pyc | Bin 0 -> 1303 bytes .../comparison_with_callable.cpython-37.pyc | Bin 0 -> 1334 bytes .../confidence_filter.cpython-37.pyc | Bin 0 -> 887 bytes .../confusing_with_statement.cpython-37.pyc | Bin 0 -> 473 bytes ...nsider_iterating_dictionary.cpython-37.pyc | Bin 0 -> 2488 bytes .../__pycache__/consider_join.cpython-37.pyc | Bin 0 -> 1484 bytes ...consider_merging_isinstance.cpython-37.pyc | Bin 0 -> 1135 bytes .../consider_swap_variables.cpython-37.pyc | Bin 0 -> 378 bytes ...er_using_dict_comprehension.cpython-37.pyc | Bin 0 -> 446 bytes .../consider_using_enumerate.cpython-37.pyc | Bin 0 -> 2108 bytes .../consider_using_get.cpython-37.pyc | Bin 0 -> 992 bytes .../consider_using_in.cpython-37.pyc | Bin 0 -> 1215 bytes ...der_using_set_comprehension.cpython-37.pyc | Bin 0 -> 434 bytes .../control_pragmas.cpython-37.pyc | Bin 0 -> 590 bytes .../crash_missing_module_type.cpython-37.pyc | Bin 0 -> 824 bytes .../__pycache__/ctor_arguments.cpython-37.pyc | Bin 0 -> 4133 bytes .../dangerous_default_value.cpython-37.pyc | Bin 0 -> 2825 bytes ...angerous_default_value_py30.cpython-37.pyc | Bin 0 -> 2830 bytes ...fined_and_used_on_same_line.cpython-37.pyc | Bin 0 -> 1347 bytes .../deprecated_lambda.cpython-37.pyc | Bin 0 -> 1109 bytes ...ecated_method_getmoduleinfo.cpython-37.pyc | Bin 0 -> 330 bytes .../deprecated_methods_py2.cpython-37.pyc | Bin 0 -> 471 bytes .../deprecated_methods_py3.cpython-37.pyc | Bin 0 -> 1881 bytes .../deprecated_methods_py36.cpython-37.pyc | Bin 0 -> 455 bytes .../deprecated_module_py2.cpython-37.pyc | Bin 0 -> 368 bytes .../deprecated_module_py3.cpython-37.pyc | Bin 0 -> 280 bytes .../deprecated_module_py36.cpython-37.pyc | Bin 0 -> 297 bytes .../deprecated_module_py4.cpython-37.pyc | Bin 0 -> 308 bytes ...precated_module_uninstalled.cpython-37.pyc | Bin 0 -> 344 bytes ...sable_msg_github_issue_1389.cpython-37.pyc | Bin 0 -> 759 bytes .../disable_ungrouped_imports.cpython-37.pyc | Bin 0 -> 505 bytes .../disable_wrong_import_order.cpython-37.pyc | Bin 0 -> 615 bytes ...sable_wrong_import_position.cpython-37.pyc | Bin 0 -> 386 bytes .../__pycache__/docstrings.cpython-37.pyc | Bin 0 -> 2493 bytes .../duplicate_bases.cpython-37.pyc | Bin 0 -> 795 bytes .../duplicate_dict_literal_key.cpython-37.pyc | Bin 0 -> 447 bytes .../duplicate_except.cpython-37.pyc | Bin 0 -> 526 bytes ..._string_formatting_argument.cpython-37.pyc | Bin 0 -> 394 bytes .../__pycache__/eval_used.cpython-37.pyc | Bin 0 -> 451 bytes .../exception_is_binary_op.cpython-37.pyc | Bin 0 -> 570 bytes .../exception_message.cpython-37.pyc | Bin 0 -> 1420 bytes .../__pycache__/exec_used_py3.cpython-37.pyc | Bin 0 -> 405 bytes .../fallback_import_disabled.cpython-37.pyc | Bin 0 -> 467 bytes .../fallback_import_enabled.cpython-37.pyc | Bin 0 -> 338 bytes .../__pycache__/fixme.cpython-37.pyc | Bin 0 -> 361 bytes .../fixme_bad_formatting_1139.cpython-37.pyc | Bin 0 -> 395 bytes ...string_literal_with_if_py36.cpython-37.pyc | Bin 0 -> 330 bytes .../function_redefined.cpython-37.pyc | Bin 0 -> 4032 bytes .../__pycache__/future_import.cpython-37.pyc | Bin 0 -> 284 bytes .../future_unicode_literals.cpython-37.pyc | Bin 0 -> 375 bytes .../generated_members.cpython-37.pyc | Bin 0 -> 801 bytes .../genexp_in_class_scope.cpython-37.pyc | Bin 0 -> 611 bytes .../genexpr_variable_scope.cpython-37.pyc | Bin 0 -> 392 bytes .../__pycache__/globals.cpython-37.pyc | Bin 0 -> 1019 bytes ...icit_str_concat_in_sequence.cpython-37.pyc | Bin 0 -> 570 bytes ...r_concat_in_sequence_latin1.cpython-37.pyc | Bin 0 -> 275 bytes ...oncat_in_sequence_multiline.cpython-37.pyc | Bin 0 -> 261 bytes ...str_concat_in_sequence_utf8.cpython-37.pyc | Bin 0 -> 273 bytes .../__pycache__/import_error.cpython-37.pyc | Bin 0 -> 675 bytes .../inconsistent_mro.cpython-37.pyc | Bin 0 -> 544 bytes .../inconsistent_returns.cpython-37.pyc | Bin 0 -> 6987 bytes .../indexing_exception.cpython-37.pyc | Bin 0 -> 618 bytes .../inherit_non_class.cpython-37.pyc | Bin 0 -> 3544 bytes .../init_is_generator.cpython-37.pyc | Bin 0 -> 493 bytes .../init_not_called.cpython-37.pyc | Bin 0 -> 3285 bytes ...t_subclass_classmethod_py36.cpython-37.pyc | Bin 0 -> 889 bytes .../invalid_all_object.cpython-37.pyc | Bin 0 -> 327 bytes .../invalid_encoding_py27.cpython-37.pyc | Bin 0 -> 320 bytes .../invalid_envvar_value.cpython-37.pyc | Bin 0 -> 1737 bytes .../invalid_exceptions_caught.cpython-37.pyc | Bin 0 -> 2935 bytes .../invalid_exceptions_raised.cpython-37.pyc | Bin 0 -> 3742 bytes .../invalid_length_returned.cpython-37.pyc | Bin 0 -> 3085 bytes .../invalid_metaclass.cpython-37.pyc | Bin 0 -> 1209 bytes .../invalid_metaclass_py3.cpython-37.pyc | Bin 0 -> 830 bytes .../__pycache__/invalid_name.cpython-37.pyc | Bin 0 -> 1075 bytes .../invalid_sequence_index.cpython-37.pyc | Bin 0 -> 10063 bytes .../invalid_slice_index.cpython-37.pyc | Bin 0 -> 3243 bytes .../invalid_unary_operand_type.cpython-37.pyc | Bin 0 -> 1983 bytes .../iterable_context.cpython-37.pyc | Bin 0 -> 5175 bytes .../iterable_context_py3.cpython-37.pyc | Bin 0 -> 1663 bytes .../iterable_context_py36.cpython-37.pyc | Bin 0 -> 2573 bytes .../keyword_arg_before_vararg.cpython-37.pyc | Bin 0 -> 1410 bytes .../__pycache__/len_checks.cpython-37.pyc | Bin 0 -> 1425 bytes .../__pycache__/line_endings.cpython-37.pyc | Bin 0 -> 275 bytes .../__pycache__/line_too_long.cpython-37.pyc | Bin 0 -> 1186 bytes ...line_too_long_end_of_module.cpython-37.pyc | Bin 0 -> 459 bytes .../literal_comparison.cpython-37.pyc | Bin 0 -> 508 bytes ...ogging_format_interpolation.cpython-37.pyc | Bin 0 -> 995 bytes ...g_format_interpolation_py36.cpython-37.pyc | Bin 0 -> 380 bytes ..._fstring_interpolation_py36.cpython-37.pyc | Bin 0 -> 660 bytes .../logging_not_lazy.cpython-37.pyc | Bin 0 -> 628 bytes .../logical_tautology.cpython-37.pyc | Bin 0 -> 844 bytes .../long_lines_with_utf8.cpython-37.pyc | Bin 0 -> 401 bytes .../long_utf8_lines.cpython-37.pyc | Bin 0 -> 506 bytes .../__pycache__/lost_exception.cpython-37.pyc | Bin 0 -> 861 bytes .../mapping_context.cpython-37.pyc | Bin 0 -> 4242 bytes .../mapping_context_py2.cpython-37.pyc | Bin 0 -> 969 bytes .../mapping_context_py3.cpython-37.pyc | Bin 0 -> 951 bytes .../__pycache__/member_checks.cpython-37.pyc | Bin 0 -> 7078 bytes .../member_checks_hints.cpython-37.pyc | Bin 0 -> 1051 bytes .../member_checks_ignore_none.cpython-37.pyc | Bin 0 -> 349 bytes ...ecks_inference_improvements.cpython-37.pyc | Bin 0 -> 446 bytes .../member_checks_no_hints.cpython-37.pyc | Bin 0 -> 1054 bytes .../member_checks_opaque.cpython-37.pyc | Bin 0 -> 413 bytes .../member_checks_py37.cpython-37.pyc | Bin 0 -> 643 bytes .../membership_protocol.cpython-37.pyc | Bin 0 -> 4033 bytes .../membership_protocol_py2.cpython-37.pyc | Bin 0 -> 1768 bytes .../membership_protocol_py3.cpython-37.pyc | Bin 0 -> 1727 bytes .../messages_managed_by_id.cpython-37.pyc | Bin 0 -> 522 bytes .../__pycache__/method_hidden.cpython-37.pyc | Bin 0 -> 2577 bytes .../misplaced_bare_raise.cpython-37.pyc | Bin 0 -> 1849 bytes ...splaced_comparison_constant.cpython-37.pyc | Bin 0 -> 1257 bytes .../misplaced_format_function.cpython-37.pyc | Bin 0 -> 2128 bytes .../missing_docstring.cpython-37.pyc | Bin 0 -> 1926 bytes .../missing_final_newline.cpython-37.pyc | Bin 0 -> 347 bytes .../missing_kwoa_py3.cpython-37.pyc | Bin 0 -> 1164 bytes .../missing_self_argument.cpython-37.pyc | Bin 0 -> 1081 bytes .../mixed_indentation.cpython-37.pyc | Bin 0 -> 539 bytes .../monkeypatch_method.cpython-37.pyc | Bin 0 -> 808 bytes .../multiple_imports.cpython-37.pyc | Bin 0 -> 244 bytes .../namePresetCamelCase.cpython-37.pyc | Bin 0 -> 1225 bytes .../name_preset_snake_case.cpython-37.pyc | Bin 0 -> 1238 bytes .../__pycache__/name_styles.cpython-37.pyc | Bin 0 -> 5432 bytes ...namedtuple_member_inference.cpython-37.pyc | Bin 0 -> 829 bytes .../names_in__all__.cpython-37.pyc | Bin 0 -> 1559 bytes .../nested_blocks_issue1088.cpython-37.pyc | Bin 0 -> 636 bytes .../no_classmethod_decorator.cpython-37.pyc | Bin 0 -> 1500 bytes .../__pycache__/no_else_raise.cpython-37.pyc | Bin 0 -> 2068 bytes .../__pycache__/no_else_return.cpython-37.pyc | Bin 0 -> 1888 bytes .../no_name_in_module.cpython-37.pyc | Bin 0 -> 1400 bytes .../no_self_argument_py37.cpython-37.pyc | Bin 0 -> 728 bytes .../__pycache__/no_self_use.cpython-37.pyc | Bin 0 -> 3415 bytes .../no_self_use_py3.cpython-37.pyc | Bin 0 -> 888 bytes .../no_staticmethod_decorator.cpython-37.pyc | Bin 0 -> 1502 bytes .../non_iterator_returned.cpython-37.pyc | Bin 0 -> 4540 bytes .../none_dunder_protocols_py36.cpython-37.pyc | Bin 0 -> 1353 bytes .../nonexistent_operator.cpython-37.pyc | Bin 0 -> 381 bytes .../not_async_context_manager.cpython-37.pyc | Bin 0 -> 3341 bytes .../__pycache__/not_callable.cpython-37.pyc | Bin 0 -> 4176 bytes .../not_context_manager.cpython-37.pyc | Bin 0 -> 3429 bytes ...tponed_evaluation_activated.cpython-37.pyc | Bin 0 -> 864 bytes ...ed_evaluation_not_activated.cpython-37.pyc | Bin 0 -> 824 bytes ...ess_access_different_scopes.cpython-37.pyc | Bin 0 -> 746 bytes .../raising_format_tuple.cpython-37.pyc | Bin 0 -> 2452 bytes .../raising_non_exception_py3.cpython-37.pyc | Bin 0 -> 670 bytes .../__pycache__/raising_self.cpython-37.pyc | Bin 0 -> 656 bytes .../recursion_error_2667.cpython-37.pyc | Bin 0 -> 743 bytes .../recursion_error_940.cpython-37.pyc | Bin 0 -> 802 bytes .../recursion_error_crash.cpython-37.pyc | Bin 0 -> 439 bytes .../recursion_error_crash_2683.cpython-37.pyc | Bin 0 -> 745 bytes ...ion_error_crash_astroid_623.cpython-37.pyc | Bin 0 -> 544 bytes ...defined_argument_from_local.cpython-37.pyc | Bin 0 -> 1797 bytes .../redefined_builtin.cpython-37.pyc | Bin 0 -> 486 bytes .../redundant_unittest_assert.cpython-37.pyc | Bin 0 -> 1424 bytes ...sion_1326_crash_uninferable.cpython-37.pyc | Bin 0 -> 465 bytes ...sion_no_value_for_parameter.cpython-37.pyc | Bin 0 -> 732 bytes .../__pycache__/reimported.cpython-37.pyc | Bin 0 -> 485 bytes .../repeated_keyword.cpython-37.pyc | Bin 0 -> 539 bytes .../__pycache__/return_in_init.cpython-37.pyc | Bin 0 -> 1414 bytes .../reused_outer_loop_variable.cpython-37.pyc | Bin 0 -> 806 bytes ...sed_outer_loop_variable_py3.cpython-37.pyc | Bin 0 -> 392 bytes .../self_cls_assignment.cpython-37.pyc | Bin 0 -> 1867 bytes .../signature_differs.cpython-37.pyc | Bin 0 -> 1120 bytes .../simplifiable_if_expression.cpython-37.pyc | Bin 0 -> 1006 bytes .../simplifiable_if_statement.cpython-37.pyc | Bin 0 -> 2579 bytes ...simplify_chained_comparison.cpython-37.pyc | Bin 0 -> 1955 bytes .../singledispatch_functions.cpython-37.pyc | Bin 0 -> 2144 bytes ...ingledispatch_functions_py3.cpython-37.pyc | Bin 0 -> 2148 bytes .../singleton_comparison.cpython-37.pyc | Bin 0 -> 402 bytes .../__pycache__/slots_checks.cpython-37.pyc | Bin 0 -> 4117 bytes .../socketerror_import.cpython-37.pyc | Bin 0 -> 447 bytes .../statement_without_effect.cpython-37.pyc | Bin 0 -> 1757 bytes ...atement_without_effect_py36.cpython-37.pyc | Bin 0 -> 740 bytes ..._iteration_inside_generator.cpython-37.pyc | Bin 0 -> 3426 bytes .../string_formatting.cpython-37.pyc | Bin 0 -> 6901 bytes .../string_formatting_disable.cpython-37.pyc | Bin 0 -> 251 bytes ...formatting_failed_inference.cpython-37.pyc | Bin 0 -> 408 bytes ...tting_failed_inference_py35.cpython-37.pyc | Bin 0 -> 487 bytes .../string_formatting_py27.cpython-37.pyc | Bin 0 -> 720 bytes .../string_formatting_py3.cpython-37.pyc | Bin 0 -> 916 bytes ...subprocess_popen_preexec_fn.cpython-37.pyc | Bin 0 -> 386 bytes .../__pycache__/super_checks.cpython-37.pyc | Bin 0 -> 6225 bytes .../superfluous_parens.cpython-37.pyc | Bin 0 -> 514 bytes .../suspicious_str_strip_call.cpython-37.pyc | Bin 0 -> 422 bytes ...spicious_str_strip_call_py3.cpython-37.pyc | Bin 0 -> 392 bytes .../sys_stream_regression_1004.cpython-37.pyc | Bin 0 -> 405 bytes .../__pycache__/ternary.cpython-37.pyc | Bin 0 -> 1236 bytes .../__pycache__/test_compile.cpython-37.pyc | Bin 0 -> 539 bytes .../__pycache__/tokenize_error.cpython-37.pyc | Bin 0 -> 387 bytes .../tokenize_error_jython.cpython-37.pyc | Bin 0 -> 394 bytes .../too_few_public_methods.cpython-37.pyc | Bin 0 -> 2207 bytes .../too_few_public_methods_37.cpython-37.pyc | Bin 0 -> 1026 bytes .../too_many_ancestors.cpython-37.pyc | Bin 0 -> 1534 bytes .../too_many_arguments.cpython-37.pyc | Bin 0 -> 1250 bytes ...o_many_arguments_issue_1045.cpython-37.pyc | Bin 0 -> 385 bytes ...oo_many_boolean_expressions.cpython-37.pyc | Bin 0 -> 557 bytes .../too_many_branches.cpython-37.pyc | Bin 0 -> 743 bytes ...oo_many_instance_attributes.cpython-37.pyc | Bin 0 -> 839 bytes .../__pycache__/too_many_lines.cpython-37.pyc | Bin 0 -> 286 bytes .../too_many_lines_disabled.cpython-37.pyc | Bin 0 -> 365 bytes .../too_many_locals.cpython-37.pyc | Bin 0 -> 1844 bytes .../too_many_nested_blocks.cpython-37.pyc | Bin 0 -> 1610 bytes .../too_many_public_methods.cpython-37.pyc | Bin 0 -> 3350 bytes .../too_many_return_statements.cpython-37.pyc | Bin 0 -> 881 bytes .../too_many_statements.cpython-37.pyc | Bin 0 -> 1924 bytes .../trailing_comma_tuple.cpython-37.pyc | Bin 0 -> 851 bytes .../trailing_newlines.cpython-37.pyc | Bin 0 -> 273 bytes .../trailing_whitespaces.cpython-37.pyc | Bin 0 -> 536 bytes .../try_except_raise_crash.cpython-37.pyc | Bin 0 -> 877 bytes .../unbalanced_tuple_unpacking.cpython-37.pyc | Bin 0 -> 3597 bytes ...lanced_tuple_unpacking_py30.cpython-37.pyc | Bin 0 -> 590 bytes .../undefined_loop_variable.cpython-37.pyc | Bin 0 -> 2195 bytes .../undefined_variable.cpython-37.pyc | Bin 0 -> 9553 bytes .../undefined_variable_py30.cpython-37.pyc | Bin 0 -> 4128 bytes ...ed_special_method_signature.cpython-37.pyc | Bin 0 -> 6178 bytes .../ungrouped_imports.cpython-37.pyc | Bin 0 -> 601 bytes .../unhashable_dict_key.cpython-37.pyc | Bin 0 -> 493 bytes .../unidiomatic_typecheck.cpython-37.pyc | Bin 0 -> 2490 bytes .../uninferable_all_object.cpython-37.pyc | Bin 0 -> 401 bytes .../unnecessary_lambda.cpython-37.pyc | Bin 0 -> 3230 bytes .../unnecessary_pass.cpython-37.pyc | Bin 0 -> 1727 bytes .../__pycache__/unneeded_not.cpython-37.pyc | Bin 0 -> 1252 bytes .../__pycache__/unpacking.cpython-37.pyc | Bin 0 -> 578 bytes .../unpacking_generalizations.cpython-37.pyc | Bin 0 -> 1119 bytes .../unpacking_non_sequence.cpython-37.pyc | Bin 0 -> 4936 bytes .../__pycache__/unreachable.cpython-37.pyc | Bin 0 -> 783 bytes .../unrecognized_inline_option.cpython-37.pyc | Bin 0 -> 256 bytes .../unsubscriptable_value.cpython-37.pyc | Bin 0 -> 4089 bytes .../unsubscriptable_value_py37.cpython-37.pyc | Bin 0 -> 742 bytes ...ported_assignment_operation.cpython-37.pyc | Bin 0 -> 2699 bytes ...nsupported_binary_operation.cpython-37.pyc | Bin 0 -> 2694 bytes ...nsupported_delete_operation.cpython-37.pyc | Bin 0 -> 2585 bytes .../unused_argument.cpython-37.pyc | Bin 0 -> 2146 bytes .../unused_argument_py3.cpython-37.pyc | Bin 0 -> 319 bytes .../unused_global_variable1.cpython-37.pyc | Bin 0 -> 235 bytes .../unused_global_variable2.cpython-37.pyc | Bin 0 -> 235 bytes .../unused_global_variable3.cpython-37.pyc | Bin 0 -> 343 bytes .../unused_global_variable4.cpython-37.pyc | Bin 0 -> 250 bytes .../__pycache__/unused_import.cpython-37.pyc | Bin 0 -> 1152 bytes .../unused_import_assigned_to.cpython-37.pyc | Bin 0 -> 876 bytes .../unused_typing_imports.cpython-37.pyc | Bin 0 -> 1530 bytes .../unused_variable.cpython-37.pyc | Bin 0 -> 2192 bytes .../unused_variable_py36.cpython-37.pyc | Bin 0 -> 496 bytes .../used_before_assignment_488.cpython-37.pyc | Bin 0 -> 451 bytes ...before_assignment_issue1081.cpython-37.pyc | Bin 0 -> 1268 bytes ..._before_assignment_issue853.cpython-37.pyc | Bin 0 -> 571 bytes ..._before_assignment_nonlocal.cpython-37.pyc | Bin 0 -> 2238 bytes .../useless-import-alias.cpython-37.pyc | Bin 0 -> 719 bytes .../useless_else_on_loop.cpython-37.pyc | Bin 0 -> 2267 bytes .../useless_object_inheritance.cpython-37.pyc | Bin 0 -> 1358 bytes .../__pycache__/useless_return.cpython-37.pyc | Bin 0 -> 811 bytes .../useless_super_delegation.cpython-37.pyc | Bin 0 -> 13606 bytes ...seless_super_delegation_py3.cpython-37.pyc | Bin 0 -> 2715 bytes ...eless_super_delegation_py35.cpython-37.pyc | Bin 0 -> 985 bytes .../using_constant_test.cpython-37.pyc | Bin 0 -> 3716 bytes .../wildcard_import.cpython-37.pyc | Bin 0 -> 266 bytes .../wildcard_import_allowed.cpython-37.pyc | Bin 0 -> 279 bytes .../with_used_before_assign.cpython-37.pyc | Bin 0 -> 556 bytes .../with_using_generator.cpython-37.pyc | Bin 0 -> 786 bytes .../wrong_exception_operation.cpython-37.pyc | Bin 0 -> 389 bytes .../wrong_import_order.cpython-37.pyc | Bin 0 -> 1096 bytes .../wrong_import_order2.cpython-37.pyc | Bin 0 -> 440 bytes .../wrong_import_position.cpython-37.pyc | Bin 0 -> 1059 bytes .../wrong_import_position10.cpython-37.pyc | Bin 0 -> 513 bytes .../wrong_import_position11.cpython-37.pyc | Bin 0 -> 293 bytes .../wrong_import_position12.cpython-37.pyc | Bin 0 -> 279 bytes .../wrong_import_position13.cpython-37.pyc | Bin 0 -> 308 bytes .../wrong_import_position14.cpython-37.pyc | Bin 0 -> 301 bytes .../wrong_import_position15.cpython-37.pyc | Bin 0 -> 403 bytes .../wrong_import_position2.cpython-37.pyc | Bin 0 -> 384 bytes .../wrong_import_position3.cpython-37.pyc | Bin 0 -> 278 bytes .../wrong_import_position4.cpython-37.pyc | Bin 0 -> 382 bytes .../wrong_import_position5.cpython-37.pyc | Bin 0 -> 278 bytes .../wrong_import_position6.cpython-37.pyc | Bin 0 -> 300 bytes .../wrong_import_position7.cpython-37.pyc | Bin 0 -> 345 bytes .../wrong_import_position8.cpython-37.pyc | Bin 0 -> 287 bytes .../wrong_import_position9.cpython-37.pyc | Bin 0 -> 337 bytes ...osition_exclude_dunder_main.cpython-37.pyc | Bin 0 -> 413 bytes .../yield_from_iterable_py33.cpython-37.pyc | Bin 0 -> 400 bytes .../test/functional/abstract_abc_methods.py | 17 + .../abstract_class_instantiated_in_class.py | 20 + .../abstract_class_instantiated_py2.py | 82 + .../abstract_class_instantiated_py2.rc | 2 + .../abstract_class_instantiated_py2.txt | 4 + .../abstract_class_instantiated_py3.py | 128 + .../abstract_class_instantiated_py3.rc | 2 + .../abstract_class_instantiated_py3.txt | 5 + .../abstract_class_instantiated_py34.py | 19 + .../abstract_class_instantiated_py34.rc | 2 + .../abstract_class_instantiated_py34.txt | 1 + .../test/functional/abstract_method_py2.py | 90 + .../test/functional/abstract_method_py2.rc | 2 + .../test/functional/abstract_method_py2.txt | 16 + .../test/functional/abstract_method_py3.py | 88 + .../test/functional/abstract_method_py3.rc | 2 + .../test/functional/abstract_method_py3.txt | 16 + .../access_member_before_definition.py | 40 + .../access_member_before_definition.txt | 2 + .../test/functional/access_to__name__.py | 21 + .../test/functional/access_to__name__.txt | 2 + .../functional/access_to_protected_members.py | 59 + .../access_to_protected_members.txt | 6 + .../anomalous_unicode_escape_py2.py | 20 + .../anomalous_unicode_escape_py2.rc | 2 + .../anomalous_unicode_escape_py2.txt | 3 + .../anomalous_unicode_escape_py3.py | 19 + .../anomalous_unicode_escape_py3.rc | 2 + .../anomalous_unicode_escape_py3.txt | 3 + .../pylint/test/functional/arguments.py | 217 + .../pylint/test/functional/arguments.txt | 39 + .../test/functional/arguments_differ.py | 210 + .../test/functional/arguments_differ.txt | 8 + .../test/functional/arguments_differ_py3.py | 36 + .../test/functional/arguments_differ_py3.rc | 2 + .../test/functional/arguments_differ_py3.txt | 5 + .../pylint/test/functional/assert_on_tuple.py | 11 + .../test/functional/assert_on_tuple.txt | 2 + .../test/functional/assigning_non_slot.py | 150 + .../test/functional/assigning_non_slot.txt | 5 + .../functional/assignment_from_no_return.py | 31 + .../functional/assignment_from_no_return.txt | 2 + .../assignment_from_no_return_py3.py | 28 + .../assignment_from_no_return_py3.rc | 2 + .../assignment_from_no_return_py3.txt | 0 .../pylint/test/functional/async_functions.py | 63 + .../pylint/test/functional/async_functions.rc | 2 + .../test/functional/async_functions.txt | 11 + .../attribute_defined_outside_init.py | 62 + .../attribute_defined_outside_init.txt | 2 + .../test/functional/bad_continuation.py | 232 + .../test/functional/bad_continuation.txt | 63 + .../test/functional/bad_continuation_py36.py | 8 + .../test/functional/bad_continuation_py36.rc | 2 + .../test/functional/bad_continuation_tabs.py | 52 + .../test/functional/bad_continuation_tabs.rc | 3 + .../test/functional/bad_continuation_tabs.txt | 6 + .../test/functional/bad_except_order.py | 45 + .../test/functional/bad_except_order.txt | 5 + .../test/functional/bad_exception_context.py | 24 + .../test/functional/bad_exception_context.rc | 2 + .../test/functional/bad_exception_context.txt | 3 + .../pylint/test/functional/bad_indentation.py | 19 + .../test/functional/bad_indentation.txt | 2 + .../test/functional/bad_inline_option.py | 5 + .../test/functional/bad_inline_option.rc | 2 + .../test/functional/bad_inline_option.txt | 1 + .../pylint/test/functional/bad_open_mode.py | 37 + .../pylint/test/functional/bad_open_mode.rc | 2 + .../pylint/test/functional/bad_open_mode.txt | 14 + .../test/functional/bad_open_mode_py3.py | 23 + .../test/functional/bad_open_mode_py3.rc | 3 + .../test/functional/bad_open_mode_py3.txt | 6 + .../test/functional/bad_reversed_sequence.py | 84 + .../test/functional/bad_reversed_sequence.txt | 8 + .../functional/bad_staticmethod_argument.py | 16 + .../functional/bad_staticmethod_argument.txt | 2 + .../functional/bad_thread_instantiation.py | 8 + .../functional/bad_thread_instantiation.txt | 2 + .../pylint/test/functional/bad_whitespace.py | 7 + .../pylint/test/functional/bad_whitespace.txt | 15 + .../pylint/test/functional/bare_except.py | 6 + .../pylint/test/functional/bare_except.txt | 1 + .../test/functional/blacklisted_name.py | 4 + .../test/functional/blacklisted_name.txt | 1 + .../test/functional/boolean_datetime.py | 30 + .../test/functional/boolean_datetime.rc | 2 + .../test/functional/boolean_datetime.txt | 8 + .../pylint/test/functional/broad_except.py | 14 + .../pylint/test/functional/broad_except.txt | 2 + .../bugfix_local_scope_metaclass_1177.py | 56 + .../bugfix_local_scope_metaclass_1177.rc | 2 + .../test/functional/cellvar_escaping_loop.py | 120 + .../test/functional/cellvar_escaping_loop.txt | 6 + .../test/functional/class_members_py27.py | 70 + .../test/functional/class_members_py27.rc | 3 + .../test/functional/class_members_py27.txt | 7 + .../test/functional/class_members_py30.py | 68 + .../test/functional/class_members_py30.rc | 2 + .../test/functional/class_members_py30.txt | 7 + .../pylint/test/functional/class_scope.py | 22 + .../pylint/test/functional/class_scope.txt | 4 + .../functional/comparison_with_callable.py | 60 + .../functional/comparison_with_callable.txt | 5 + .../test/functional/confidence_filter.py | 16 + .../test/functional/confidence_filter.rc | 3 + .../test/functional/confidence_filter.txt | 1 + .../functional/confusing_with_statement.py | 27 + .../functional/confusing_with_statement.txt | 1 + .../consider_iterating_dictionary.py | 38 + .../consider_iterating_dictionary.txt | 15 + .../pylint/test/functional/consider_join.py | 126 + .../pylint/test/functional/consider_join.txt | 11 + .../functional/consider_merging_isinstance.py | 37 + .../consider_merging_isinstance.txt | 7 + .../functional/consider_swap_variables.py | 25 + .../functional/consider_swap_variables.txt | 2 + .../consider_using_dict_comprehension.py | 9 + .../consider_using_dict_comprehension.txt | 1 + .../functional/consider_using_enumerate.py | 67 + .../functional/consider_using_enumerate.txt | 4 + .../test/functional/consider_using_get.py | 90 + .../test/functional/consider_using_get.txt | 4 + .../test/functional/consider_using_in.py | 46 + .../test/functional/consider_using_in.txt | 13 + .../consider_using_set_comprehension.py | 9 + .../consider_using_set_comprehension.txt | 1 + .../test/functional/continue_in_finally.py | 24 + .../test/functional/continue_in_finally.txt | 1 + .../pylint/test/functional/control_pragmas.py | 19 + .../test/functional/control_pragmas.txt | 0 .../functional/crash_missing_module_type.py | 18 + .../functional/crash_missing_module_type.txt | 0 .../pylint/test/functional/ctor_arguments.py | 104 + .../pylint/test/functional/ctor_arguments.txt | 24 + .../functional/dangerous_default_value.py | 79 + .../functional/dangerous_default_value.rc | 2 + .../functional/dangerous_default_value.txt | 14 + .../dangerous_default_value_py30.py | 79 + .../dangerous_default_value_py30.rc | 2 + .../dangerous_default_value_py30.txt | 14 + .../defined_and_used_on_same_line.py | 29 + .../test/functional/deprecated_lambda.py | 23 + .../test/functional/deprecated_lambda.rc | 2 + .../test/functional/deprecated_lambda.txt | 2 + .../deprecated_method_getmoduleinfo.py | 4 + .../deprecated_method_getmoduleinfo.rc | 3 + .../deprecated_method_getmoduleinfo.txt | 1 + .../test/functional/deprecated_methods_py2.py | 9 + .../test/functional/deprecated_methods_py2.rc | 2 + .../functional/deprecated_methods_py2.txt | 4 + .../test/functional/deprecated_methods_py3.py | 50 + .../test/functional/deprecated_methods_py3.rc | 2 + .../functional/deprecated_methods_py3.txt | 16 + .../functional/deprecated_methods_py36.py | 7 + .../functional/deprecated_methods_py36.rc | 2 + .../functional/deprecated_methods_py36.txt | 2 + .../test/functional/deprecated_module_py2.py | 8 + .../test/functional/deprecated_module_py2.rc | 2 + .../test/functional/deprecated_module_py2.txt | 4 + .../test/functional/deprecated_module_py3.py | 4 + .../test/functional/deprecated_module_py3.rc | 3 + .../test/functional/deprecated_module_py3.txt | 1 + .../test/functional/deprecated_module_py36.py | 4 + .../test/functional/deprecated_module_py36.rc | 2 + .../functional/deprecated_module_py36.txt | 1 + .../test/functional/deprecated_module_py4.py | 4 + .../test/functional/deprecated_module_py4.rc | 4 + .../test/functional/deprecated_module_py4.txt | 2 + .../deprecated_module_uninstalled.py | 5 + .../deprecated_module_uninstalled.rc | 2 + .../deprecated_module_uninstalled.txt | 2 + .../disable_msg_github_issue_1389.py | 15 + .../disable_msg_github_issue_1389.rc | 2 + .../functional/disable_ungrouped_imports.py | 10 + .../functional/disable_ungrouped_imports.txt | 2 + .../functional/disable_wrong_import_order.py | 11 + .../functional/disable_wrong_import_order.txt | 1 + .../disable_wrong_import_position.py | 7 + .../pylint/test/functional/docstrings.py | 90 + .../pylint/test/functional/docstrings.txt | 8 + .../functional/duplicate_argument_name.py | 14 + .../functional/duplicate_argument_name.txt | 8 + .../functional/duplicate_argument_name_py3.py | 5 + .../functional/duplicate_argument_name_py3.rc | 2 + .../duplicate_argument_name_py3.txt | 2 + .../pylint/test/functional/duplicate_bases.py | 15 + .../test/functional/duplicate_bases.txt | 1 + .../functional/duplicate_dict_literal_key.py | 17 + .../functional/duplicate_dict_literal_key.txt | 3 + .../test/functional/duplicate_except.py | 12 + .../test/functional/duplicate_except.txt | 1 + .../duplicate_string_formatting_argument.py | 15 + .../duplicate_string_formatting_argument.txt | 2 + .../pylint/test/functional/eval_used.py | 10 + .../pylint/test/functional/eval_used.txt | 4 + .../test/functional/exception_is_binary_op.py | 12 + .../functional/exception_is_binary_op.txt | 4 + .../test/functional/exception_message.py | 41 + .../test/functional/exception_message.rc | 5 + .../test/functional/exception_message.txt | 6 + .../pylint/test/functional/exec_used_py2.py | 10 + .../pylint/test/functional/exec_used_py2.rc | 2 + .../pylint/test/functional/exec_used_py2.txt | 4 + .../pylint/test/functional/exec_used_py3.py | 9 + .../pylint/test/functional/exec_used_py3.rc | 2 + .../pylint/test/functional/exec_used_py3.txt | 4 + .../functional/fallback_import_disabled.py | 10 + .../functional/fallback_import_disabled.txt | 0 .../functional/fallback_import_enabled.py | 5 + .../functional/fallback_import_enabled.rc | 2 + .../functional/fallback_import_enabled.txt | 2 + .../pylint/test/functional/fixme.py | 24 + .../pylint/test/functional/fixme.txt | 6 + .../functional/fixme_bad_formatting_1139.py | 6 + .../functional/fixme_bad_formatting_1139.rc | 2 + .../functional/fixme_bad_formatting_1139.txt | 1 + .../formatted_string_literal_with_if_py36.py | 8 + .../formatted_string_literal_with_if_py36.rc | 2 + .../pylint/test/functional/formatting.txt | 0 .../test/functional/function_redefined.py | 109 + .../test/functional/function_redefined.txt | 7 + .../pylint/test/functional/future_import.py | 3 + .../functional/future_unicode_literals.py | 6 + .../functional/future_unicode_literals.rc | 1 + .../functional/future_unicode_literals.txt | 1 + .../test/functional/generated_members.py | 18 + .../test/functional/generated_members.rc | 5 + .../test/functional/genexp_in_class_scope.py | 6 + .../test/functional/genexp_in_class_scope.txt | 0 .../test/functional/genexpr_variable_scope.py | 5 + .../functional/genexpr_variable_scope.txt | 1 + .../pylint/test/functional/globals.py | 32 + .../pylint/test/functional/globals.txt | 7 + .../implicit_str_concat_in_sequence.py | 26 + .../implicit_str_concat_in_sequence.txt | 4 + .../implicit_str_concat_in_sequence_latin1.py | 4 + ...implicit_str_concat_in_sequence_latin1.txt | 0 ...plicit_str_concat_in_sequence_multiline.py | 4 + ...plicit_str_concat_in_sequence_multiline.rc | 2 + ...licit_str_concat_in_sequence_multiline.txt | 1 + .../implicit_str_concat_in_sequence_utf8.py | 3 + .../implicit_str_concat_in_sequence_utf8.txt | 0 .../pylint/test/functional/import_error.py | 29 + .../pylint/test/functional/import_error.rc | 2 + .../pylint/test/functional/import_error.txt | 4 + .../test/functional/inconsistent_mro.py | 9 + .../test/functional/inconsistent_mro.txt | 1 + .../test/functional/inconsistent_returns.py | 264 + .../test/functional/inconsistent_returns.rc | 2 + .../test/functional/inconsistent_returns.txt | 13 + .../test/functional/indexing_exception.py | 15 + .../test/functional/indexing_exception.rc | 5 + .../test/functional/indexing_exception.txt | 3 + .../test/functional/inherit_non_class.py | 81 + .../test/functional/inherit_non_class.txt | 9 + .../test/functional/init_is_generator.py | 5 + .../test/functional/init_is_generator.txt | 1 + .../pylint/test/functional/init_not_called.py | 64 + .../test/functional/init_not_called.txt | 3 + .../init_subclass_classmethod_py36.py | 16 + .../init_subclass_classmethod_py36.rc | 2 + .../test/functional/invalid_all_object.py | 6 + .../test/functional/invalid_all_object.txt | 3 + .../test/functional/invalid_encoding_py27.py | 3 + .../test/functional/invalid_encoding_py27.rc | 3 + .../test/functional/invalid_encoding_py27.txt | 1 + .../test/functional/invalid_envvar_value.py | 84 + .../test/functional/invalid_envvar_value.txt | 31 + .../functional/invalid_exceptions_caught.py | 135 + .../functional/invalid_exceptions_caught.txt | 12 + .../functional/invalid_exceptions_raised.py | 105 + .../functional/invalid_exceptions_raised.txt | 12 + .../functional/invalid_length_returned.py | 64 + .../functional/invalid_length_returned.txt | 3 + .../test/functional/invalid_metaclass.py | 34 + .../test/functional/invalid_metaclass.txt | 0 .../test/functional/invalid_metaclass_py3.py | 19 + .../test/functional/invalid_metaclass_py3.rc | 2 + .../test/functional/invalid_metaclass_py3.txt | 0 .../pylint/test/functional/invalid_name.py | 39 + .../pylint/test/functional/invalid_name.txt | 3 + .../test/functional/invalid_sequence_index.py | 242 + .../functional/invalid_sequence_index.txt | 20 + .../test/functional/invalid_slice_index.py | 71 + .../test/functional/invalid_slice_index.txt | 5 + .../invalid_star_assignment_target.py | 4 + .../invalid_star_assignment_target.rc | 2 + .../invalid_star_assignment_target.txt | 1 + .../functional/invalid_unary_operand_type.py | 51 + .../functional/invalid_unary_operand_type.txt | 14 + .../test/functional/iterable_context.py | 192 + .../test/functional/iterable_context.txt | 10 + .../test/functional/iterable_context_py2.py | 18 + .../test/functional/iterable_context_py2.rc | 2 + .../test/functional/iterable_context_py2.txt | 1 + .../test/functional/iterable_context_py3.py | 55 + .../test/functional/iterable_context_py3.rc | 3 + .../test/functional/iterable_context_py3.txt | 1 + .../test/functional/iterable_context_py36.py | 41 + .../test/functional/iterable_context_py36.rc | 2 + .../test/functional/iterable_context_py36.txt | 2 + .../functional/keyword_arg_before_vararg.py | 35 + .../functional/keyword_arg_before_vararg.txt | 4 + .../pylint/test/functional/len_checks.py | 77 + .../pylint/test/functional/len_checks.txt | 16 + .../pylint/test/functional/line_endings.py | 3 + .../pylint/test/functional/line_endings.rc | 2 + .../pylint/test/functional/line_endings.txt | 2 + .../pylint/test/functional/line_too_long.py | 45 + .../pylint/test/functional/line_too_long.txt | 6 + .../functional/line_too_long_end_of_module.py | 7 + .../test/functional/literal_comparison.py | 50 + .../test/functional/literal_comparison.txt | 13 + .../logging_format_interpolation.py | 39 + .../logging_format_interpolation.txt | 5 + .../logging_format_interpolation_py36.py | 5 + .../logging_format_interpolation_py36.rc | 2 + .../logging_format_interpolation_py36.txt | 1 + .../logging_fstring_interpolation_py36.py | 21 + .../logging_fstring_interpolation_py36.rc | 2 + .../logging_fstring_interpolation_py36.txt | 5 + .../test/functional/logging_not_lazy.py | 23 + .../test/functional/logging_not_lazy.txt | 6 + .../test/functional/logical_tautology.py | 40 + .../test/functional/logical_tautology.txt | 12 + .../test/functional/long_lines_with_utf8.py | 7 + .../test/functional/long_lines_with_utf8.txt | 1 + .../pylint/test/functional/long_utf8_lines.py | 8 + .../test/functional/long_utf8_lines.txt | 0 .../pylint/test/functional/lost_exception.py | 41 + .../pylint/test/functional/lost_exception.txt | 2 + .../pylint/test/functional/mapping_context.py | 109 + .../test/functional/mapping_context.txt | 2 + .../test/functional/mapping_context_py2.py | 19 + .../test/functional/mapping_context_py2.rc | 2 + .../test/functional/mapping_context_py2.txt | 1 + .../test/functional/mapping_context_py3.py | 19 + .../test/functional/mapping_context_py3.rc | 3 + .../test/functional/mapping_context_py3.txt | 1 + .../pylint/test/functional/member_checks.py | 209 + .../pylint/test/functional/member_checks.txt | 19 + .../test/functional/member_checks_hints.py | 27 + .../test/functional/member_checks_hints.rc | 3 + .../test/functional/member_checks_hints.txt | 5 + .../functional/member_checks_ignore_none.py | 7 + .../functional/member_checks_ignore_none.rc | 2 + .../functional/member_checks_ignore_none.txt | 1 + .../member_checks_inference_improvements.py | 11 + .../test/functional/member_checks_no_hints.py | 27 + .../test/functional/member_checks_no_hints.rc | 2 + .../functional/member_checks_no_hints.txt | 5 + .../test/functional/member_checks_opaque.py | 12 + .../test/functional/member_checks_opaque.rc | 2 + .../test/functional/member_checks_opaque.txt | 1 + .../test/functional/member_checks_py37.py | 19 + .../test/functional/member_checks_py37.rc | 2 + .../test/functional/member_checks_py37.txt | 1 + .../test/functional/membership_protocol.py | 123 + .../test/functional/membership_protocol.txt | 7 + .../functional/membership_protocol_py2.py | 36 + .../functional/membership_protocol_py2.rc | 3 + .../functional/membership_protocol_py2.txt | 3 + .../functional/membership_protocol_py3.py | 36 + .../functional/membership_protocol_py3.rc | 3 + .../functional/membership_protocol_py3.txt | 3 + .../test/functional/messages_managed_by_id.py | 11 + .../functional/messages_managed_by_id.txt | 6 + .../pylint/test/functional/method_hidden.py | 60 + .../pylint/test/functional/method_hidden.txt | 1 + .../test/functional/misplaced_bare_raise.py | 85 + .../test/functional/misplaced_bare_raise.txt | 7 + .../misplaced_comparison_constant.py | 36 + .../misplaced_comparison_constant.txt | 6 + .../functional/misplaced_format_function.py | 58 + .../functional/misplaced_format_function.txt | 4 + .../test/functional/misplaced_future.py | 6 + .../test/functional/misplaced_future.txt | 1 + .../test/functional/missing_docstring.py | 54 + .../test/functional/missing_docstring.txt | 3 + .../test/functional/missing_final_newline.py | 4 + .../test/functional/missing_final_newline.txt | 1 + .../test/functional/missing_kwoa_py3.py | 36 + .../test/functional/missing_kwoa_py3.rc | 2 + .../test/functional/missing_kwoa_py3.txt | 3 + .../test/functional/missing_self_argument.py | 21 + .../test/functional/missing_self_argument.txt | 6 + .../test/functional/mixed_indentation.py | 10 + .../test/functional/mixed_indentation.txt | 2 + .../test/functional/monkeypatch_method.py | 16 + .../test/functional/monkeypatch_method.txt | 0 .../test/functional/multiple_imports.py | 2 + .../test/functional/multiple_imports.txt | 1 + .../test/functional/namePresetCamelCase.py | 23 + .../test/functional/namePresetCamelCase.rc | 13 + .../test/functional/namePresetCamelCase.txt | 3 + .../test/functional/name_preset_snake_case.py | 23 + .../test/functional/name_preset_snake_case.rc | 13 + .../functional/name_preset_snake_case.txt | 3 + .../pylint/test/functional/name_styles.py | 140 + .../pylint/test/functional/name_styles.rc | 5 + .../pylint/test/functional/name_styles.txt | 16 + .../functional/namedtuple_member_inference.py | 22 + .../namedtuple_member_inference.txt | 2 + .../pylint/test/functional/names_in__all__.py | 49 + .../test/functional/names_in__all__.txt | 6 + .../functional/nested_blocks_issue1088.py | 23 + .../functional/nested_blocks_issue1088.txt | 2 + .../functional/no_classmethod_decorator.py | 35 + .../functional/no_classmethod_decorator.txt | 3 + .../pylint/test/functional/no_else_raise.py | 110 + .../pylint/test/functional/no_else_raise.txt | 7 + .../pylint/test/functional/no_else_return.py | 110 + .../pylint/test/functional/no_else_return.txt | 7 + .../test/functional/no_name_in_module.py | 66 + .../test/functional/no_name_in_module.txt | 14 + .../test/functional/no_self_argument_py37.py | 15 + .../test/functional/no_self_argument_py37.rc | 2 + .../test/functional/no_self_argument_py37.txt | 1 + .../pylint/test/functional/no_self_use.py | 78 + .../pylint/test/functional/no_self_use.txt | 1 + .../pylint/test/functional/no_self_use_py3.py | 12 + .../pylint/test/functional/no_self_use_py3.rc | 2 + .../test/functional/no_self_use_py3.txt | 1 + .../functional/no_staticmethod_decorator.py | 35 + .../functional/no_staticmethod_decorator.txt | 3 + .../test/functional/non_iterator_returned.py | 95 + .../test/functional/non_iterator_returned.txt | 4 + .../functional/none_dunder_protocols_py36.py | 34 + .../functional/none_dunder_protocols_py36.rc | 2 + .../functional/none_dunder_protocols_py36.txt | 6 + .../test/functional/nonexistent_operator.py | 15 + .../test/functional/nonexistent_operator.txt | 6 + .../test/functional/nonlocal_and_global.py | 12 + .../test/functional/nonlocal_and_global.rc | 2 + .../test/functional/nonlocal_and_global.txt | 1 + .../functional/nonlocal_without_binding.py | 42 + .../functional/nonlocal_without_binding.rc | 2 + .../functional/nonlocal_without_binding.txt | 3 + .../functional/not_async_context_manager.py | 71 + .../functional/not_async_context_manager.rc | 2 + .../functional/not_async_context_manager.txt | 5 + .../not_async_context_manager_py37.py | 12 + .../not_async_context_manager_py37.rc | 2 + .../not_async_context_manager_py37.txt | 0 .../pylint/test/functional/not_callable.py | 125 + .../pylint/test/functional/not_callable.txt | 8 + .../test/functional/not_context_manager.py | 135 + .../test/functional/not_context_manager.txt | 5 + .../pylint/test/functional/not_in_loop.py | 54 + .../pylint/test/functional/not_in_loop.txt | 8 + .../test/functional/old_division_manually.py | 2 + .../test/functional/old_division_manually.rc | 6 + .../postponed_evaluation_activated.py | 15 + .../postponed_evaluation_activated.rc | 2 + .../postponed_evaluation_activated.txt | 0 .../postponed_evaluation_not_activated.py | 14 + .../postponed_evaluation_not_activated.rc | 2 + .../postponed_evaluation_not_activated.txt | 2 + .../test/functional/print_always_warns.py | 8 + .../test/functional/print_always_warns.rc | 5 + .../test/functional/print_always_warns.txt | 1 + ...rotected_access_access_different_scopes.py | 13 + ...rotected_access_access_different_scopes.rc | 2 + ...otected_access_access_different_scopes.txt | 2 + .../test/functional/raising_format_tuple.py | 51 + .../test/functional/raising_format_tuple.txt | 7 + .../functional/raising_non_exception_py3.py | 13 + .../functional/raising_non_exception_py3.rc | 2 + .../functional/raising_non_exception_py3.txt | 1 + .../pylint/test/functional/raising_self.py | 10 + .../pylint/test/functional/raising_self.txt | 0 .../test/functional/recursion_error_2667.py | 9 + .../test/functional/recursion_error_2667.txt | 0 .../test/functional/recursion_error_940.py | 13 + .../test/functional/recursion_error_crash.py | 9 + .../test/functional/recursion_error_crash.txt | 0 .../functional/recursion_error_crash_2683.py | 13 + .../functional/recursion_error_crash_2683.txt | 0 .../recursion_error_crash_astroid_623.py | 10 + .../recursion_error_crash_astroid_623.txt | 0 .../test/functional/redefine_in_handler.py | 68 + .../test/functional/redefine_in_handler.rc | 2 + .../test/functional/redefine_in_handler.txt | 7 + .../redefined_argument_from_local.py | 67 + .../redefined_argument_from_local.txt | 7 + .../test/functional/redefined_builtin.py | 11 + .../test/functional/redefined_builtin.txt | 2 + .../functional/redundant_unittest_assert.py | 38 + .../functional/redundant_unittest_assert.txt | 6 + .../regression_1326_crash_uninferable.py | 12 + .../regression_no_value_for_parameter.py | 15 + .../regression_no_value_for_parameter.txt | 0 .../pylint/test/functional/reimported.py | 16 + .../pylint/test/functional/reimported.txt | 4 + .../test/functional/repeated_keyword.py | 13 + .../test/functional/repeated_keyword.txt | 1 + .../pylint/test/functional/return_in_init.py | 25 + .../pylint/test/functional/return_in_init.txt | 1 + .../functional/return_outside_function.py | 2 + .../functional/return_outside_function.txt | 1 + .../functional/reused_outer_loop_variable.py | 37 + .../functional/reused_outer_loop_variable.txt | 4 + .../reused_outer_loop_variable_py3.py | 5 + .../reused_outer_loop_variable_py3.rc | 2 + .../reused_outer_loop_variable_py3.txt | 1 + .../test/functional/self_cls_assignment.py | 47 + .../test/functional/self_cls_assignment.txt | 4 + .../test/functional/signature_differs.py | 22 + .../test/functional/signature_differs.txt | 1 + .../functional/simplifiable_if_expression.py | 27 + .../functional/simplifiable_if_expression.txt | 4 + .../functional/simplifiable_if_statement.py | 146 + .../functional/simplifiable_if_statement.txt | 4 + .../functional/simplify_chained_comparison.py | 89 + .../simplify_chained_comparison.txt | 18 + .../functional/singledispatch_functions.py | 76 + .../functional/singledispatch_functions.rc | 3 + .../functional/singledispatch_functions.txt | 5 + .../singledispatch_functions_py3.py | 76 + .../singledispatch_functions_py3.rc | 3 + .../singledispatch_functions_py3.txt | 5 + .../test/functional/singleton_comparison.py | 15 + .../test/functional/singleton_comparison.txt | 8 + .../pylint/test/functional/slots_checks.py | 85 + .../pylint/test/functional/slots_checks.txt | 8 + .../test/functional/socketerror_import.py | 6 + .../star_needs_assignment_target.py | 4 + .../star_needs_assignment_target.rc | 2 + .../star_needs_assignment_target.txt | 1 + .../star_needs_assignment_target_py35.py | 15 + .../star_needs_assignment_target_py35.rc | 2 + .../star_needs_assignment_target_py35.txt | 1 + .../functional/statement_without_effect.py | 75 + .../functional/statement_without_effect.txt | 60 + .../statement_without_effect_py36.py | 18 + .../statement_without_effect_py36.rc | 2 + .../statement_without_effect_py36.txt | 1 + .../stop_iteration_inside_generator.py | 129 + .../stop_iteration_inside_generator.rc | 2 + .../stop_iteration_inside_generator.txt | 7 + .../test/functional/string_formatting.py | 188 + .../test/functional/string_formatting.txt | 41 + .../functional/string_formatting_disable.py | 1 + .../functional/string_formatting_disable.rc | 3 + .../functional/string_formatting_disable.txt | 1 + .../string_formatting_failed_inference.py | 4 + ...string_formatting_failed_inference_py35.py | 6 + ...string_formatting_failed_inference_py35.rc | 2 + .../test/functional/string_formatting_py27.py | 22 + .../test/functional/string_formatting_py27.rc | 3 + .../functional/string_formatting_py27.txt | 15 + .../test/functional/string_formatting_py3.py | 21 + .../test/functional/string_formatting_py3.rc | 2 + .../test/functional/string_formatting_py3.txt | 2 + .../functional/subprocess_popen_preexec_fn.py | 11 + .../subprocess_popen_preexec_fn.txt | 1 + .../pylint/test/functional/super_checks.py | 125 + .../pylint/test/functional/super_checks.txt | 18 + .../test/functional/superfluous_parens.py | 19 + .../test/functional/superfluous_parens.txt | 5 + .../functional/suspicious_str_strip_call.py | 10 + .../functional/suspicious_str_strip_call.rc | 2 + .../functional/suspicious_str_strip_call.txt | 3 + .../suspicious_str_strip_call_py3.py | 9 + .../suspicious_str_strip_call_py3.rc | 2 + .../suspicious_str_strip_call_py3.txt | 3 + .../pylint/test/functional/syntax_error.py | 1 + .../pylint/test/functional/syntax_error.rc | 1 + .../pylint/test/functional/syntax_error.txt | 1 + .../test/functional/syntax_error_jython.py | 1 + .../test/functional/syntax_error_jython.rc | 2 + .../test/functional/syntax_error_jython.txt | 1 + .../functional/sys_stream_regression_1004.py | 7 + .../functional/sys_stream_regression_1004.rc | 3 + .../functional/sys_stream_regression_1004.txt | 2 + .../pylint/test/functional/ternary.py | 33 + .../pylint/test/functional/ternary.txt | 7 + .../pylint/test/functional/test_compile.py | 6 + .../pylint/test/functional/tokenize_error.py | 6 + .../pylint/test/functional/tokenize_error.rc | 1 + .../pylint/test/functional/tokenize_error.txt | 1 + .../test/functional/tokenize_error_jython.py | 7 + .../test/functional/tokenize_error_jython.rc | 2 + .../test/functional/tokenize_error_jython.txt | 1 + .../test/functional/too_few_public_methods.py | 50 + .../functional/too_few_public_methods.txt | 1 + .../functional/too_few_public_methods_37.py | 24 + .../functional/too_few_public_methods_37.rc | 2 + .../functional/too_few_public_methods_37.txt | 0 .../test/functional/too_many_ancestors.py | 24 + .../test/functional/too_many_ancestors.txt | 2 + .../test/functional/too_many_arguments.py | 32 + .../test/functional/too_many_arguments.txt | 1 + .../too_many_arguments_issue_1045.py | 13 + .../too_many_arguments_issue_1045.rc | 2 + .../too_many_arguments_issue_1045.txt | 0 .../too_many_boolean_expressions.py | 20 + .../too_many_boolean_expressions.txt | 4 + .../test/functional/too_many_branches.py | 69 + .../test/functional/too_many_branches.txt | 1 + .../too_many_instance_attributes.py | 26 + .../too_many_instance_attributes.txt | 1 + .../pylint/test/functional/too_many_lines.py | 1015 ++ .../pylint/test/functional/too_many_lines.txt | 1 + .../functional/too_many_lines_disabled.py | 1018 ++ .../pylint/test/functional/too_many_locals.py | 60 + .../test/functional/too_many_locals.txt | 3 + .../test/functional/too_many_nested_blocks.py | 97 + .../functional/too_many_nested_blocks.txt | 2 + .../functional/too_many_public_methods.py | 79 + .../functional/too_many_public_methods.txt | 1 + .../functional/too_many_return_statements.py | 40 + .../functional/too_many_return_statements.txt | 1 + .../functional/too_many_star_expressions.py | 7 + .../functional/too_many_star_expressions.rc | 2 + .../functional/too_many_star_expressions.txt | 2 + .../test/functional/too_many_statements.py | 125 + .../test/functional/too_many_statements.txt | 2 + .../test/functional/trailing_comma_tuple.py | 38 + .../test/functional/trailing_comma_tuple.rc | 2 + .../test/functional/trailing_comma_tuple.txt | 7 + .../test/functional/trailing_newlines.py | 3 + .../test/functional/trailing_newlines.txt | 1 + .../test/functional/trailing_whitespaces.py | 11 + .../test/functional/trailing_whitespaces.txt | 3 + .../test/functional/try_except_raise.py | 120 + .../test/functional/try_except_raise.txt | 7 + .../test/functional/try_except_raise_crash.py | 25 + .../functional/try_except_raise_crash.txt | 1 + .../functional/unbalanced_tuple_unpacking.py | 108 + .../functional/unbalanced_tuple_unpacking.txt | 6 + .../unbalanced_tuple_unpacking_py30.py | 11 + .../unbalanced_tuple_unpacking_py30.rc | 2 + .../functional/undefined_loop_variable.py | 75 + .../functional/undefined_loop_variable.txt | 3 + .../test/functional/undefined_variable.py | 247 + .../test/functional/undefined_variable.txt | 26 + .../functional/undefined_variable_py30.py | 82 + .../functional/undefined_variable_py30.rc | 2 + .../functional/undefined_variable_py30.txt | 8 + .../unexpected_special_method_signature.py | 120 + .../unexpected_special_method_signature.txt | 16 + .../test/functional/ungrouped_imports.py | 20 + .../test/functional/ungrouped_imports.txt | 5 + .../test/functional/unhashable_dict_key.py | 11 + .../test/functional/unhashable_dict_key.txt | 3 + .../test/functional/unidiomatic_typecheck.py | 76 + .../test/functional/unidiomatic_typecheck.txt | 18 + .../test/functional/uninferable_all_object.py | 9 + .../test/functional/unnecessary_lambda.py | 51 + .../test/functional/unnecessary_lambda.txt | 7 + .../test/functional/unnecessary_pass.py | 49 + .../test/functional/unnecessary_pass.txt | 3 + .../pylint/test/functional/unneeded_not.py | 63 + .../pylint/test/functional/unneeded_not.txt | 14 + .../test/functional/unpacked_exceptions.py | 11 + .../test/functional/unpacked_exceptions.rc | 5 + .../test/functional/unpacked_exceptions.txt | 4 + .../pylint/test/functional/unpacking.py | 11 + .../functional/unpacking_generalizations.py | 29 + .../functional/unpacking_generalizations.rc | 2 + .../functional/unpacking_generalizations.txt | 6 + .../test/functional/unpacking_non_sequence.py | 140 + .../functional/unpacking_non_sequence.txt | 10 + .../pylint/test/functional/unreachable.py | 22 + .../pylint/test/functional/unreachable.txt | 4 + .../functional/unrecognized_inline_option.py | 3 + .../functional/unrecognized_inline_option.txt | 1 + .../test/functional/unsubscriptable_value.py | 114 + .../test/functional/unsubscriptable_value.txt | 14 + .../functional/unsubscriptable_value_py37.py | 19 + .../functional/unsubscriptable_value_py37.rc | 2 + .../functional/unsubscriptable_value_py37.txt | 1 + .../unsupported_assignment_operation.py | 94 + .../unsupported_assignment_operation.txt | 17 + .../unsupported_binary_operation.py | 66 + .../unsupported_binary_operation.rc | 2 + .../unsupported_binary_operation.txt | 21 + .../unsupported_delete_operation.py | 94 + .../unsupported_delete_operation.txt | 17 + .../pylint/test/functional/unused_argument.py | 48 + .../test/functional/unused_argument.txt | 3 + .../test/functional/unused_argument_py3.py | 4 + .../test/functional/unused_argument_py3.rc | 2 + .../test/functional/unused_argument_py3.txt | 2 + .../functional/unused_global_variable1.py | 2 + .../functional/unused_global_variable2.py | 2 + .../functional/unused_global_variable2.rc | 2 + .../functional/unused_global_variable2.txt | 1 + .../functional/unused_global_variable3.py | 6 + .../functional/unused_global_variable4.py | 3 + .../functional/unused_global_variable4.rc | 2 + .../functional/unused_global_variable4.txt | 2 + .../pylint/test/functional/unused_import.py | 35 + .../pylint/test/functional/unused_import.txt | 8 + .../functional/unused_import_assigned_to.py | 25 + .../test/functional/unused_typing_imports.py | 39 + .../test/functional/unused_typing_imports.rc | 3 + .../pylint/test/functional/unused_variable.py | 55 + .../test/functional/unused_variable.txt | 12 + .../test/functional/unused_variable_py36.py | 13 + .../test/functional/unused_variable_py36.rc | 2 + .../test/functional/unused_variable_py36.txt | 0 .../functional/used_before_assignment_488.py | 9 + .../used_before_assignment_issue1081.py | 40 + .../used_before_assignment_issue1081.txt | 7 + .../used_before_assignment_issue853.py | 23 + .../used_before_assignment_nonlocal.py | 60 + .../used_before_assignment_nonlocal.rc | 2 + .../used_before_assignment_nonlocal.txt | 6 + .../used_prior_global_declaration.py | 39 + .../used_prior_global_declaration.rc | 2 + .../used_prior_global_declaration.txt | 1 + .../test/functional/useless-import-alias.py | 21 + .../test/functional/useless-import-alias.txt | 9 + .../test/functional/useless_else_on_loop.py | 103 + .../test/functional/useless_else_on_loop.txt | 6 + .../functional/useless_object_inheritance.py | 27 + .../functional/useless_object_inheritance.txt | 4 + .../pylint/test/functional/useless_return.py | 15 + .../pylint/test/functional/useless_return.txt | 2 + .../functional/useless_super_delegation.py | 252 + .../functional/useless_super_delegation.txt | 17 + .../useless_super_delegation_py3.py | 43 + .../useless_super_delegation_py3.rc | 2 + .../useless_super_delegation_py3.txt | 2 + .../useless_super_delegation_py35.py | 12 + .../useless_super_delegation_py35.rc | 2 + .../useless_super_delegation_py35.txt | 1 + .../test/functional/using_constant_test.py | 141 + .../test/functional/using_constant_test.txt | 22 + .../pylint/test/functional/wildcard_import.py | 5 + .../test/functional/wildcard_import.txt | 2 + .../functional/wildcard_import_allowed.py | 4 + .../functional/wildcard_import_allowed.rc | 2 + .../functional/wildcard_import_allowed.txt | 2 + .../functional/with_used_before_assign.py | 11 + .../functional/with_used_before_assign.txt | 2 + .../test/functional/with_using_generator.py | 15 + .../test/functional/with_using_generator.txt | 1 + .../functional/wrong_exception_operation.py | 18 + .../functional/wrong_exception_operation.txt | 3 + .../test/functional/wrong_import_order.py | 43 + .../test/functional/wrong_import_order.txt | 6 + .../test/functional/wrong_import_order2.py | 16 + .../test/functional/wrong_import_position.py | 33 + .../test/functional/wrong_import_position.txt | 4 + .../functional/wrong_import_position10.py | 15 + .../functional/wrong_import_position11.py | 4 + .../functional/wrong_import_position11.txt | 1 + .../functional/wrong_import_position12.py | 5 + .../functional/wrong_import_position12.txt | 1 + .../functional/wrong_import_position13.py | 4 + .../functional/wrong_import_position13.txt | 1 + .../functional/wrong_import_position14.py | 5 + .../functional/wrong_import_position14.txt | 1 + .../functional/wrong_import_position15.py | 9 + .../test/functional/wrong_import_position2.py | 10 + .../test/functional/wrong_import_position3.py | 3 + .../test/functional/wrong_import_position4.py | 5 + .../test/functional/wrong_import_position5.py | 4 + .../test/functional/wrong_import_position6.py | 7 + .../test/functional/wrong_import_position7.py | 9 + .../test/functional/wrong_import_position8.py | 4 + .../test/functional/wrong_import_position9.py | 9 + ...ong_import_position_exclude_dunder_main.py | 12 + ...ng_import_position_exclude_dunder_main.txt | 0 .../functional/yield_from_iterable_py33.py | 7 + .../functional/yield_from_iterable_py33.rc | 2 + .../functional/yield_from_iterable_py33.txt | 1 + .../functional/yield_from_outside_func.py | 4 + .../functional/yield_from_outside_func.rc | 2 + .../functional/yield_from_outside_func.txt | 1 + .../functional/yield_inside_async_function.py | 12 + .../functional/yield_inside_async_function.rc | 3 + .../yield_inside_async_function.txt | 2 + .../yield_inside_async_function_py36.py | 12 + .../yield_inside_async_function_py36.rc | 2 + .../yield_inside_async_function_py36.txt | 1 + .../test/functional/yield_outside_func.py | 4 + .../test/functional/yield_outside_func.txt | 1 + .../pylint/test/input/__init__.py | 1 + .../input/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 217 bytes ...func_3k_removed_stuff_py_30.cpython-37.pyc | Bin 0 -> 563 bytes ...func_bad_cont_dictcomp_py27.cpython-37.pyc | Bin 0 -> 1801 bytes .../__pycache__/func_bug113231.cpython-37.pyc | Bin 0 -> 707 bytes .../func_disable_linebased.cpython-37.pyc | Bin 0 -> 760 bytes .../func_dotted_ancestor.cpython-37.pyc | Bin 0 -> 630 bytes .../__pycache__/func_e0012.cpython-37.pyc | Bin 0 -> 261 bytes .../__pycache__/func_e0204.cpython-37.pyc | Bin 0 -> 940 bytes .../__pycache__/func_e12xx.cpython-37.pyc | Bin 0 -> 673 bytes .../__pycache__/func_e13xx.cpython-37.pyc | Bin 0 -> 824 bytes .../func_excess_escapes.cpython-37.pyc | Bin 0 -> 665 bytes .../__pycache__/func_first_arg.cpython-37.pyc | Bin 0 -> 1499 bytes .../__pycache__/func_i0011.cpython-37.pyc | Bin 0 -> 273 bytes .../__pycache__/func_i0012.cpython-37.pyc | Bin 0 -> 272 bytes .../__pycache__/func_i0013.cpython-37.pyc | Bin 0 -> 301 bytes .../__pycache__/func_i0014.cpython-37.pyc | Bin 0 -> 301 bytes .../__pycache__/func_i0020.cpython-37.pyc | Bin 0 -> 431 bytes .../__pycache__/func_i0022.cpython-37.pyc | Bin 0 -> 323 bytes ...ogging_not_lazy_with_logger.cpython-37.pyc | Bin 0 -> 523 bytes ...c_loopvar_in_dict_comp_py27.cpython-37.pyc | Bin 0 -> 701 bytes .../func_module___dict__.cpython-37.pyc | Bin 0 -> 385 bytes ...rror_on_string_substitution.cpython-37.pyc | Bin 0 -> 352 bytes .../func_no_dummy_redefined.cpython-37.pyc | Bin 0 -> 629 bytes ..._return_from_inner_function.cpython-37.pyc | Bin 0 -> 745 bytes ...r_before_def_false_positive.cpython-37.pyc | Bin 0 -> 3397 bytes ...func_noerror_base_init_vars.cpython-37.pyc | Bin 0 -> 1454 bytes ...noerror_builtin_module_test.cpython-37.pyc | Bin 0 -> 500 bytes ...nc_noerror_class_attributes.cpython-37.pyc | Bin 0 -> 953 bytes ...es_meth_could_be_a_function.cpython-37.pyc | Bin 0 -> 1514 bytes ...ses_protected_member_access.cpython-37.pyc | Bin 0 -> 1099 bytes ...unc_noerror_decorator_scope.cpython-37.pyc | Bin 0 -> 1009 bytes ...1_9588_base_attr_aug_assign.cpython-37.pyc | Bin 0 -> 1941 bytes ..._external_classmethod_crash.cpython-37.pyc | Bin 0 -> 889 bytes .../func_noerror_inner_classes.cpython-37.pyc | Bin 0 -> 1446 bytes ...or_lambda_use_before_assign.cpython-37.pyc | Bin 0 -> 615 bytes ...unc_noerror_mcs_attr_access.cpython-37.pyc | Bin 0 -> 1099 bytes ...error_new_style_class_py_30.cpython-37.pyc | Bin 0 -> 1670 bytes ...oerror_no_warning_docstring.cpython-37.pyc | Bin 0 -> 1803 bytes ...r_object_as_class_attribute.cpython-37.pyc | Bin 0 -> 896 bytes ...noerror_overloaded_operator.cpython-37.pyc | Bin 0 -> 1029 bytes ...r_property_affectation_py26.cpython-37.pyc | Bin 0 -> 952 bytes ...c_noerror_yield_assign_py25.cpython-37.pyc | Bin 0 -> 803 bytes ...nc_noerror_yield_return_mix.cpython-37.pyc | Bin 0 -> 401 bytes ...unc_nonregr___file___global.cpython-37.pyc | Bin 0 -> 422 bytes ...func_return_yield_mix_py_33.cpython-37.pyc | Bin 0 -> 559 bytes ...ypecheck_callfunc_assigment.cpython-37.pyc | Bin 0 -> 2182 bytes .../func_unused_import_py30.cpython-37.pyc | Bin 0 -> 1021 bytes ...ed_name_from_wilcard_import.cpython-37.pyc | Bin 0 -> 331 bytes .../__pycache__/func_w0233.cpython-37.pyc | Bin 0 -> 2538 bytes .../__pycache__/func_w0401.cpython-37.pyc | Bin 0 -> 352 bytes .../func_w0401_disabled.cpython-37.pyc | Bin 0 -> 361 bytes ...func_w0401_disabled_in_func.cpython-37.pyc | Bin 0 -> 555 bytes .../__pycache__/func_w0404.cpython-37.pyc | Bin 0 -> 844 bytes .../__pycache__/func_w0405.cpython-37.pyc | Bin 0 -> 759 bytes .../__pycache__/func_w0406.cpython-37.pyc | Bin 0 -> 380 bytes .../__pycache__/func_w0611.cpython-37.pyc | Bin 0 -> 1037 bytes .../__pycache__/func_w0612.cpython-37.pyc | Bin 0 -> 1160 bytes .../__pycache__/func_w0613.cpython-37.pyc | Bin 0 -> 1958 bytes .../func_w0623_py30.cpython-37.pyc | Bin 0 -> 681 bytes .../__pycache__/func_w0801.cpython-37.pyc | Bin 0 -> 362 bytes .../hide_code_with_imports.cpython-37.pyc | Bin 0 -> 2929 bytes ...nore_except_pass_by_default.cpython-37.pyc | Bin 0 -> 361 bytes .../__pycache__/not__init__.cpython-37.pyc | Bin 0 -> 220 bytes .../__pycache__/w0401_cycle.cpython-37.pyc | Bin 0 -> 357 bytes .../__pycache__/w0801_same.cpython-37.pyc | Bin 0 -> 362 bytes .../test/input/func_3k_removed_stuff_py_30.py | 13 + .../test/input/func_bad_cont_dictcomp_py27.py | 38 + .../pylint/test/input/func_bug113231.py | 24 + .../test/input/func_disable_linebased.py | 14 + .../pylint/test/input/func_dotted_ancestor.py | 11 + .../pylint/test/input/func_e0012.py | 4 + .../pylint/test/input/func_e0204.py | 20 + .../pylint/test/input/func_e12xx.py | 28 + .../pylint/test/input/func_e13xx.py | 21 + .../pylint/test/input/func_excess_escapes.py | 30 + .../pylint/test/input/func_first_arg.py | 42 + .../pylint/test/input/func_i0011.py | 4 + .../pylint/test/input/func_i0012.py | 4 + .../pylint/test/input/func_i0013.py | 8 + .../pylint/test/input/func_i0014.py | 8 + .../pylint/test/input/func_i0020.py | 8 + .../pylint/test/input/func_i0022.py | 22 + .../func_logging_not_lazy_with_logger.py | 13 + .../input/func_loopvar_in_dict_comp_py27.py | 8 + .../pylint/test/input/func_module___dict__.py | 9 + .../func_nameerror_on_string_substitution.py | 8 + .../test/input/func_no_dummy_redefined.py | 14 + ...ror___init___return_from_inner_function.py | 12 + ...r_access_attr_before_def_false_positive.py | 98 + .../test/input/func_noerror_base_init_vars.py | 35 + .../input/func_noerror_builtin_module_test.py | 11 + .../input/func_noerror_class_attributes.py | 18 + ...oerror_classes_meth_could_be_a_function.py | 33 + ...noerror_classes_protected_member_access.py | 26 + .../input/func_noerror_decorator_scope.py | 19 + ...noerror_e1101_9588_base_attr_aug_assign.py | 38 + ...func_noerror_external_classmethod_crash.py | 21 + .../test/input/func_noerror_inner_classes.py | 33 + .../func_noerror_lambda_use_before_assign.py | 8 + .../input/func_noerror_mcs_attr_access.py | 20 + .../func_noerror_new_style_class_py_30.py | 45 + .../func_noerror_no_warning_docstring.py | 42 + .../func_noerror_object_as_class_attribute.py | 18 + .../input/func_noerror_overloaded_operator.py | 21 + .../func_noerror_property_affectation_py26.py | 24 + .../input/func_noerror_yield_assign_py25.py | 21 + .../input/func_noerror_yield_return_mix.py | 8 + .../input/func_nonregr___file___global.py | 8 + .../test/input/func_return_yield_mix_py_33.py | 15 + .../func_typecheck_callfunc_assigment.py | 61 + .../test/input/func_unused_import_py30.py | 20 + ...riables_unused_name_from_wilcard_import.py | 3 + .../pylint/test/input/func_w0122_py_30.py | 12 + .../pylint/test/input/func_w0233.py | 51 + .../pylint/test/input/func_w0332_py_30.py | 4 + .../pylint/test/input/func_w0401.py | 9 + .../pylint/test/input/func_w0401_disabled.py | 9 + .../test/input/func_w0401_disabled_in_func.py | 11 + .../test/input/func_w0401_package/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 268 bytes .../__pycache__/all_the_things.cpython-37.pyc | Bin 0 -> 412 bytes .../__pycache__/thing1.cpython-37.pyc | Bin 0 -> 293 bytes .../__pycache__/thing2.cpython-37.pyc | Bin 0 -> 391 bytes .../func_w0401_package/all_the_things.py | 9 + .../test/input/func_w0401_package/thing1.py | 3 + .../test/input/func_w0401_package/thing2.py | 7 + .../pylint/test/input/func_w0404.py | 27 + .../pylint/test/input/func_w0405.py | 31 + .../pylint/test/input/func_w0406.py | 10 + .../pylint/test/input/func_w0611.py | 25 + .../pylint/test/input/func_w0612.py | 37 + .../pylint/test/input/func_w0613.py | 42 + .../pylint/test/input/func_w0623_py30.py | 17 + .../pylint/test/input/func_w0801.py | 11 + .../test/input/hide_code_with_imports.py | 16 + .../input/ignore_except_pass_by_default.py | 6 + .../pylint/test/input/multiline-import | 8 + .../site-packages/pylint/test/input/noext | 4 + .../pylint/test/input/not__init__.py | 1 + .../site-packages/pylint/test/input/similar1 | 22 + .../site-packages/pylint/test/input/similar2 | 22 + .../pylint/test/input/w0401_cycle.py | 9 + .../pylint/test/input/w0801_same.py | 11 + .../pylint/test/messages/builtin_module.txt | 1 + .../messages/func_3k_removed_stuff_py_30.txt | 2 + .../messages/func_bad_cont_dictcomp_py27.txt | 6 + .../pylint/test/messages/func_bug113231.txt | 2 + .../test/messages/func_disable_linebased.txt | 2 + .../messages/func_disable_linebased_py30.txt | 2 + .../test/messages/func_dotted_ancestor.txt | 1 + .../pylint/test/messages/func_e0012.txt | 1 + .../pylint/test/messages/func_e0204.txt | 3 + .../pylint/test/messages/func_e12xx.txt | 6 + .../pylint/test/messages/func_e13xx.txt | 13 + .../pylint/test/messages/func_e13xx_py30.txt | 11 + .../test/messages/func_excess_escapes.txt | 9 + .../pylint/test/messages/func_first_arg.txt | 9 + .../pylint/test/messages/func_i0011.txt | 3 + .../pylint/test/messages/func_i0012.txt | 1 + .../pylint/test/messages/func_i0013.txt | 1 + .../pylint/test/messages/func_i0014.txt | 2 + .../pylint/test/messages/func_i0020.txt | 3 + .../pylint/test/messages/func_i0022.txt | 21 + .../func_logging_not_lazy_with_logger.txt | 4 + .../func_loopvar_in_dict_comp_py27.txt | 1 + .../test/messages/func_module___dict__.txt | 1 + .../func_nameerror_on_string_substitution.txt | 2 + .../test/messages/func_no_dummy_redefined.txt | 2 + .../messages/func_nonregr___file___global.txt | 2 + .../pylint/test/messages/func_raw_escapes.txt | 3 + .../messages/func_return_yield_mix_py_33.txt | 2 + .../test/messages/func_toolonglines_py30.txt | 4 + .../func_typecheck_callfunc_assigment.txt | 3 + .../messages/func_typecheck_getattr_py30.txt | 9 + .../func_typecheck_non_callable_call.txt | 8 + .../messages/func_unicode_literal_py26.txt | 0 .../messages/func_unicode_literal_py274.txt | 1 + .../test/messages/func_unused_import_py30.txt | 1 + .../func_use_for_or_listcomp_var_py29.txt | 3 + .../func_use_for_or_listcomp_var_py30.txt | 3 + ...iables_unused_name_from_wilcard_import.txt | 4 + .../pylint/test/messages/func_w0122_py_30.txt | 5 + .../pylint/test/messages/func_w0233.txt | 6 + .../pylint/test/messages/func_w0312.txt | 2 + .../pylint/test/messages/func_w0332_py_30.txt | 1 + .../pylint/test/messages/func_w0401.txt | 3 + .../test/messages/func_w0401_disabled.txt | 2 + .../messages/func_w0401_disabled_in_func.txt | 2 + .../test/messages/func_w0401_package.txt | 2 + .../pylint/test/messages/func_w0404.txt | 5 + .../pylint/test/messages/func_w0405.txt | 4 + .../pylint/test/messages/func_w0406.txt | 1 + .../pylint/test/messages/func_w0611.txt | 1 + .../pylint/test/messages/func_w0612.txt | 6 + .../pylint/test/messages/func_w0613.txt | 5 + .../pylint/test/messages/func_w0622.txt | 2 + .../pylint/test/messages/func_w0623.txt | 11 + .../pylint/test/messages/func_w0623_py30.txt | 2 + .../pylint/test/messages/func_w0623_py_30.txt | 12 + .../pylint/test/messages/func_w0801.txt | 11 + .../messages/func_with_without_as_py25.txt | 3 + .../pylint/test/regrtest_data/.pylintrc | 4 + .../application_crash.cpython-37.pyc | Bin 0 -> 245 bytes .../__pycache__/classdoc_usage.cpython-37.pyc | Bin 0 -> 848 bytes .../decimal_inference.cpython-37.pyc | Bin 0 -> 526 bytes .../__pycache__/empty.cpython-37.pyc | Bin 0 -> 206 bytes .../func_block_disable_msg.cpython-37.pyc | Bin 0 -> 3524 bytes .../__pycache__/import_assign.cpython-37.pyc | Bin 0 -> 328 bytes ...t_package_subpackage_module.cpython-37.pyc | Bin 0 -> 2465 bytes .../import_something.cpython-37.pyc | Bin 0 -> 246 bytes .../__pycache__/meta.cpython-37.pyc | Bin 0 -> 214 bytes .../__pycache__/module_global.cpython-37.pyc | Bin 0 -> 307 bytes .../no_stdout_encoding.cpython-37.pyc | Bin 0 -> 521 bytes .../numarray_import.cpython-37.pyc | Bin 0 -> 335 bytes .../__pycache__/numarray_inf.cpython-37.pyc | Bin 0 -> 379 bytes .../precedence_test.cpython-37.pyc | Bin 0 -> 638 bytes ...ial_attr_scope_lookup_crash.cpython-37.pyc | Bin 0 -> 414 bytes .../test_pylintrc_comments.cpython-37.pyc | Bin 0 -> 310 bytes ...y_finally_disable_msg_crash.cpython-37.pyc | Bin 0 -> 242 bytes .../unused_variable.cpython-37.pyc | Bin 0 -> 338 bytes .../__pycache__/wildcard.cpython-37.pyc | Bin 0 -> 231 bytes .../wrong_import_position.cpython-37.pyc | Bin 0 -> 533 bytes .../test/regrtest_data/absimp/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 324 bytes .../absimp/__pycache__/string.cpython-37.pyc | Bin 0 -> 414 bytes .../test/regrtest_data/absimp/string.py | 7 + .../test/regrtest_data/application_crash.py | 1 + .../regrtest_data/bad_package/__init__.py | 2 + .../__pycache__/wrong.cpython-37.pyc | Bin 0 -> 394 bytes .../test/regrtest_data/bad_package/wrong.py | 5 + .../test/regrtest_data/beyond_top/__init__.py | 6 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 358 bytes .../__pycache__/data.cpython-37.pyc | Bin 0 -> 232 bytes .../test/regrtest_data/beyond_top/data.py | 1 + .../test/regrtest_data/classdoc_usage.py | 17 + .../test/regrtest_data/comments_pylintrc | 7 + .../test/regrtest_data/decimal_inference.py | 10 + .../test/regrtest_data/descriptor_crash.py | 20 + .../test/regrtest_data/dummy/__init__.py | 3 + .../dummy/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 289 bytes .../dummy/__pycache__/another.cpython-37.pyc | Bin 0 -> 229 bytes .../dummy/__pycache__/dummy.cpython-37.pyc | Bin 0 -> 225 bytes .../test/regrtest_data/dummy/another.py | 3 + .../pylint/test/regrtest_data/dummy/dummy.py | 2 + .../pylint/test/regrtest_data/dummy_plugin.rc | 6 + .../dummy_conf_plugin.cpython-37.pyc | Bin 0 -> 481 bytes .../__pycache__/dummy_plugin.cpython-37.pyc | Bin 0 -> 1131 bytes .../dummy_plugin/dummy_conf_plugin.py | 6 + .../dummy_plugin/dummy_plugin.py | 30 + .../pylint/test/regrtest_data/empty.py | 0 .../regrtest_data/func_block_disable_msg.py | 1026 +++ .../test/regrtest_data/import_assign.py | 5 + .../import_package_subpackage_module.py | 49 + .../test/regrtest_data/import_something.py | 4 + .../regrtest_data/init_wildcard/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 245 bytes .../pylint/test/regrtest_data/meta.py | 3 + .../test/regrtest_data/module_global.py | 7 + .../test/regrtest_data/no_stdout_encoding.py | 4 + .../test/regrtest_data/numarray_import.py | 7 + .../pylint/test/regrtest_data/numarray_inf.py | 5 + .../test/regrtest_data/package/AudioTime.py | 3 + .../test/regrtest_data/package/__init__.py | 15 + .../__pycache__/AudioTime.cpython-37.pyc | Bin 0 -> 306 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 572 bytes .../package/subpackage/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 258 bytes .../__pycache__/module.cpython-37.pyc | Bin 0 -> 263 bytes .../package/subpackage/module.py | 1 + .../regrtest_data/package_all/__init__.py | 3 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 354 bytes .../__pycache__/notmissing.cpython-37.pyc | Bin 0 -> 267 bytes .../regrtest_data/package_all/notmissing.py | 2 + .../test/regrtest_data/precedence_test.py | 21 + .../test/regrtest_data/py3k-disabled.rc | 2 + .../test/regrtest_data/py3k_error_flag.py | 11 + .../regrtest_data/py3k_errors_and_warnings.py | 19 + .../special_attr_scope_lookup_crash.py | 3 + .../pylint/test/regrtest_data/syntax_error.py | 1 + .../regrtest_data/test_pylintrc_comments.py | 2 + .../try_finally_disable_msg_crash.py | 5 + .../test/regrtest_data/unused_variable.py | 6 + .../pylint/test/regrtest_data/wildcard.py | 1 + .../regrtest_data/wrong_import_position.py | 11 + .../site-packages/pylint/test/test_func.py | 158 + .../pylint/test/test_functional.py | 386 + .../pylint/test/test_import_graph.py | 84 + .../site-packages/pylint/test/test_regr.py | 139 + .../site-packages/pylint/test/test_self.py | 570 ++ .../pylint/test/unittest_checker_base.py | 527 ++ .../pylint/test/unittest_checker_classes.py | 114 + .../test/unittest_checker_exceptions.py | 49 + .../pylint/test/unittest_checker_format.py | 525 ++ .../pylint/test/unittest_checker_imports.py | 132 + .../pylint/test/unittest_checker_logging.py | 125 + .../pylint/test/unittest_checker_misc.py | 103 + .../pylint/test/unittest_checker_python3.py | 1239 +++ .../pylint/test/unittest_checker_similar.py | 198 + .../pylint/test/unittest_checker_spelling.py | 306 + .../pylint/test/unittest_checker_stdlib.py | 117 + .../pylint/test/unittest_checker_strings.py | 86 + .../pylint/test/unittest_checker_typecheck.py | 335 + .../pylint/test/unittest_checker_variables.py | 284 + .../pylint/test/unittest_checkers_utils.py | 172 + .../pylint/test/unittest_config.py | 62 + .../pylint/test/unittest_lint.py | 873 ++ .../pylint/test/unittest_pyreverse_diadefs.py | 177 + .../test/unittest_pyreverse_inspector.py | 125 + .../pylint/test/unittest_pyreverse_writer.py | 136 + .../pylint/test/unittest_reporters_json.py | 53 + .../pylint/test/unittest_reporting.py | 81 + .../pylint/test/unittest_utils.py | 453 + .../site-packages/pylint/testutils.py | 305 + .../python3.7/site-packages/pylint/utils.py | 1510 +++ .../setuptools-40.8.0.dist-info/INSTALLER | 1 + .../setuptools-40.8.0.dist-info/LICENSE | 19 + .../setuptools-40.8.0.dist-info/METADATA | 73 + .../setuptools-40.8.0.dist-info/RECORD | 186 + .../setuptools-40.8.0.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 65 + .../setuptools-40.8.0.dist-info/top_level.txt | 3 + .../setuptools-40.8.0.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 228 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 7710 bytes .../_deprecation_warning.cpython-37.pyc | Bin 0 -> 564 bytes .../__pycache__/archive_util.cpython-37.pyc | Bin 0 -> 5145 bytes .../__pycache__/build_meta.cpython-37.pyc | Bin 0 -> 7772 bytes .../__pycache__/config.cpython-37.pyc | Bin 0 -> 17707 bytes .../__pycache__/dep_util.cpython-37.pyc | Bin 0 -> 871 bytes .../__pycache__/depends.cpython-37.pyc | Bin 0 -> 5280 bytes .../__pycache__/dist.cpython-37.pyc | Bin 0 -> 42224 bytes .../__pycache__/extension.cpython-37.pyc | Bin 0 -> 1991 bytes .../__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1556 bytes .../__pycache__/glob.cpython-37.pyc | Bin 0 -> 3766 bytes .../__pycache__/launch.cpython-37.pyc | Bin 0 -> 870 bytes .../__pycache__/lib2to3_ex.cpython-37.pyc | Bin 0 -> 2449 bytes .../__pycache__/monkey.cpython-37.pyc | Bin 0 -> 4650 bytes .../__pycache__/msvc.cpython-37.pyc | Bin 0 -> 34447 bytes .../__pycache__/namespaces.cpython-37.pyc | Bin 0 -> 3628 bytes .../__pycache__/package_index.cpython-37.pyc | Bin 0 -> 32721 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7218 bytes .../__pycache__/py27compat.cpython-37.pyc | Bin 0 -> 827 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 1213 bytes .../__pycache__/py33compat.cpython-37.pyc | Bin 0 -> 1436 bytes .../__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 15552 bytes .../__pycache__/site-patch.cpython-37.pyc | Bin 0 -> 1518 bytes .../__pycache__/ssl_support.cpython-37.pyc | Bin 0 -> 6808 bytes .../__pycache__/unicode_utils.cpython-37.pyc | Bin 0 -> 1512 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 344 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 6997 bytes .../windows_support.cpython-37.pyc | Bin 0 -> 1027 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 206 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203049 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24407 bytes .../setuptools/_vendor/packaging/__about__.py | 21 + .../setuptools/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 742 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 580 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1032 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2884 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8889 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3891 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19810 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 511 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10577 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 | 5742 ++++++++++++ .../site-packages/setuptools/_vendor/six.py | 868 ++ .../site-packages/setuptools/archive_util.py | 173 + .../site-packages/setuptools/build_meta.py | 231 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 18 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 752 bytes .../command/__pycache__/alias.cpython-37.pyc | Bin 0 -> 2420 bytes .../__pycache__/bdist_egg.cpython-37.pyc | Bin 0 -> 14208 bytes .../__pycache__/bdist_rpm.cpython-37.pyc | Bin 0 -> 1799 bytes .../__pycache__/bdist_wininst.cpython-37.pyc | Bin 0 -> 990 bytes .../__pycache__/build_clib.cpython-37.pyc | Bin 0 -> 2469 bytes .../__pycache__/build_ext.cpython-37.pyc | Bin 0 -> 9723 bytes .../__pycache__/build_py.cpython-37.pyc | Bin 0 -> 8599 bytes .../__pycache__/develop.cpython-37.pyc | Bin 0 -> 6480 bytes .../__pycache__/dist_info.cpython-37.pyc | Bin 0 -> 1395 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 64851 bytes .../__pycache__/egg_info.cpython-37.pyc | Bin 0 -> 21697 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 4027 bytes .../install_egg_info.cpython-37.pyc | Bin 0 -> 2428 bytes .../__pycache__/install_lib.cpython-37.pyc | Bin 0 -> 4104 bytes .../install_scripts.cpython-37.pyc | Bin 0 -> 2307 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 4640 bytes .../__pycache__/register.cpython-37.pyc | Bin 0 -> 797 bytes .../command/__pycache__/rotate.cpython-37.pyc | Bin 0 -> 2546 bytes .../__pycache__/saveopts.cpython-37.pyc | Bin 0 -> 941 bytes .../command/__pycache__/sdist.cpython-37.pyc | Bin 0 -> 6799 bytes .../command/__pycache__/setopt.cpython-37.pyc | Bin 0 -> 4539 bytes .../command/__pycache__/test.cpython-37.pyc | Bin 0 -> 8134 bytes .../command/__pycache__/upload.cpython-37.pyc | Bin 0 -> 5205 bytes .../__pycache__/upload_docs.cpython-37.pyc | Bin 0 -> 6150 bytes .../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 | 221 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2342 +++++ .../setuptools/command/egg_info.py | 717 ++ .../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 | 18 + .../setuptools/command/rotate.py | 66 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 221 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 270 + .../setuptools/command/upload.py | 196 + .../setuptools/command/upload_docs.py | 206 + .../site-packages/setuptools/config.py | 656 ++ .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/depends.py | 186 + .../site-packages/setuptools/dist.py | 1285 +++ .../site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2429 bytes .../site-packages/setuptools/glibc.py | 86 + .../site-packages/setuptools/glob.py | 174 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/monkey.py | 179 + .../site-packages/setuptools/msvc.py | 1301 +++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1136 +++ .../site-packages/setuptools/pep425tags.py | 319 + .../site-packages/setuptools/py27compat.py | 28 + .../site-packages/setuptools/py31compat.py | 32 + .../site-packages/setuptools/py33compat.py | 55 + .../site-packages/setuptools/sandbox.py | 491 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 74 + .../site-packages/setuptools/ssl_support.py | 260 + .../site-packages/setuptools/unicode_utils.py | 57 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 211 + .../setuptools/windows_support.py | 29 + .../six-1.12.0.dist-info/INSTALLER | 1 + .../six-1.12.0.dist-info/LICENSE | 18 + .../six-1.12.0.dist-info/METADATA | 52 + .../site-packages/six-1.12.0.dist-info/RECORD | 8 + .../site-packages/six-1.12.0.dist-info/WHEEL | 6 + .../six-1.12.0.dist-info/top_level.txt | 1 + venv/lib/python3.7/site-packages/six.py | 952 ++ .../typed_ast-1.3.5.dist-info/INSTALLER | 1 + .../typed_ast-1.3.5.dist-info/METADATA | 29 + .../typed_ast-1.3.5.dist-info/RECORD | 17 + .../typed_ast-1.3.5.dist-info/WHEEL | 5 + .../typed_ast-1.3.5.dist-info/top_level.txt | 3 + .../site-packages/typed_ast/__init__.py | 1 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 217 bytes .../__pycache__/ast27.cpython-37.pyc | Bin 0 -> 12435 bytes .../typed_ast/__pycache__/ast3.cpython-37.pyc | Bin 0 -> 13355 bytes .../__pycache__/conversions.cpython-37.pyc | Bin 0 -> 7936 bytes .../typed_ast/_ast27.cpython-37m-darwin.so | Bin 0 -> 256684 bytes .../typed_ast/_ast3.cpython-37m-darwin.so | Bin 0 -> 314396 bytes .../site-packages/typed_ast/ast27.py | 324 + .../python3.7/site-packages/typed_ast/ast3.py | 348 + .../site-packages/typed_ast/conversions.py | 232 + .../__pycache__/test_basics.cpython-37.pyc | Bin 0 -> 6910 bytes .../typed_ast/tests/test_basics.py | 302 + .../site-packages/werkzeug/__init__.py | 233 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 4787 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 7199 bytes .../__pycache__/_internal.cpython-37.pyc | Bin 0 -> 13284 bytes .../__pycache__/_reloader.cpython-37.pyc | Bin 0 -> 9800 bytes .../__pycache__/datastructures.cpython-37.pyc | Bin 0 -> 100837 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 25812 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 2181 bytes .../__pycache__/formparser.cpython-37.pyc | Bin 0 -> 16128 bytes .../werkzeug/__pycache__/http.cpython-37.pyc | Bin 0 -> 36004 bytes .../werkzeug/__pycache__/local.cpython-37.pyc | Bin 0 -> 18622 bytes .../__pycache__/posixemulation.cpython-37.pyc | Bin 0 -> 2753 bytes .../__pycache__/routing.cpython-37.pyc | Bin 0 -> 64437 bytes .../__pycache__/security.cpython-37.pyc | Bin 0 -> 7766 bytes .../__pycache__/serving.cpython-37.pyc | Bin 0 -> 28580 bytes .../werkzeug/__pycache__/test.cpython-37.pyc | Bin 0 -> 33590 bytes .../__pycache__/testapp.cpython-37.pyc | Bin 0 -> 9369 bytes .../werkzeug/__pycache__/urls.cpython-37.pyc | Bin 0 -> 35805 bytes .../__pycache__/useragents.cpython-37.pyc | Bin 0 -> 5992 bytes .../werkzeug/__pycache__/utils.cpython-37.pyc | Bin 0 -> 25256 bytes .../werkzeug/__pycache__/wsgi.cpython-37.pyc | Bin 0 -> 33356 bytes .../site-packages/werkzeug/_compat.py | 219 + .../site-packages/werkzeug/_internal.py | 484 + .../site-packages/werkzeug/_reloader.py | 334 + .../werkzeug/contrib/__init__.py | 16 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 739 bytes .../contrib/__pycache__/atom.cpython-37.pyc | Bin 0 -> 14199 bytes .../contrib/__pycache__/cache.cpython-37.pyc | Bin 0 -> 32599 bytes .../contrib/__pycache__/fixers.cpython-37.pyc | Bin 0 -> 9540 bytes .../contrib/__pycache__/iterio.cpython-37.pyc | Bin 0 -> 11106 bytes .../contrib/__pycache__/lint.cpython-37.pyc | Bin 0 -> 466 bytes .../__pycache__/profiler.cpython-37.pyc | Bin 0 -> 1583 bytes .../__pycache__/securecookie.cpython-37.pyc | Bin 0 -> 10807 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 0 -> 13187 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 12424 bytes .../site-packages/werkzeug/contrib/atom.py | 362 + .../site-packages/werkzeug/contrib/cache.py | 933 ++ .../site-packages/werkzeug/contrib/fixers.py | 262 + .../site-packages/werkzeug/contrib/iterio.py | 358 + .../site-packages/werkzeug/contrib/lint.py | 11 + .../werkzeug/contrib/profiler.py | 42 + .../werkzeug/contrib/securecookie.py | 362 + .../werkzeug/contrib/sessions.py | 389 + .../werkzeug/contrib/wrappers.py | 385 + .../site-packages/werkzeug/datastructures.py | 2852 ++++++ .../site-packages/werkzeug/debug/__init__.py | 524 ++ .../debug/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 13199 bytes .../debug/__pycache__/console.cpython-37.pyc | Bin 0 -> 7305 bytes .../debug/__pycache__/repr.cpython-37.pyc | Bin 0 -> 8617 bytes .../debug/__pycache__/tbtools.cpython-37.pyc | Bin 0 -> 18460 bytes .../site-packages/werkzeug/debug/console.py | 216 + .../site-packages/werkzeug/debug/repr.py | 297 + .../werkzeug/debug/shared/FONT_LICENSE | 96 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 210 + .../werkzeug/debug/shared/jquery.js | 2 + .../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 | 154 + .../werkzeug/debug/shared/ubuntu.ttf | Bin 0 -> 70220 bytes .../site-packages/werkzeug/debug/tbtools.py | 629 ++ .../site-packages/werkzeug/exceptions.py | 774 ++ .../site-packages/werkzeug/filesystem.py | 64 + .../site-packages/werkzeug/formparser.py | 586 ++ .../python3.7/site-packages/werkzeug/http.py | 1303 +++ .../python3.7/site-packages/werkzeug/local.py | 421 + .../werkzeug/middleware/__init__.py | 25 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 762 bytes .../__pycache__/dispatcher.cpython-37.pyc | Bin 0 -> 2451 bytes .../__pycache__/http_proxy.cpython-37.pyc | Bin 0 -> 6366 bytes .../__pycache__/lint.cpython-37.pyc | Bin 0 -> 11674 bytes .../__pycache__/profiler.cpython-37.pyc | Bin 0 -> 4628 bytes .../__pycache__/proxy_fix.cpython-37.pyc | Bin 0 -> 7679 bytes .../__pycache__/shared_data.cpython-37.pyc | Bin 0 -> 8338 bytes .../werkzeug/middleware/dispatcher.py | 66 + .../werkzeug/middleware/http_proxy.py | 219 + .../site-packages/werkzeug/middleware/lint.py | 408 + .../werkzeug/middleware/profiler.py | 132 + .../werkzeug/middleware/proxy_fix.py | 228 + .../werkzeug/middleware/shared_data.py | 260 + .../site-packages/werkzeug/posixemulation.py | 117 + .../site-packages/werkzeug/routing.py | 2026 ++++ .../site-packages/werkzeug/security.py | 241 + .../site-packages/werkzeug/serving.py | 1074 +++ .../python3.7/site-packages/werkzeug/test.py | 1146 +++ .../site-packages/werkzeug/testapp.py | 241 + .../python3.7/site-packages/werkzeug/urls.py | 1134 +++ .../site-packages/werkzeug/useragents.py | 220 + .../python3.7/site-packages/werkzeug/utils.py | 836 ++ .../werkzeug/wrappers/__init__.py | 36 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1690 bytes .../__pycache__/accept.cpython-37.pyc | Bin 0 -> 2219 bytes .../wrappers/__pycache__/auth.cpython-37.pyc | Bin 0 -> 1706 bytes .../__pycache__/base_request.cpython-37.pyc | Bin 0 -> 22675 bytes .../__pycache__/base_response.cpython-37.pyc | Bin 0 -> 23323 bytes .../common_descriptors.cpython-37.pyc | Bin 0 -> 12205 bytes .../wrappers/__pycache__/etag.cpython-37.pyc | Bin 0 -> 11731 bytes .../wrappers/__pycache__/json.cpython-37.pyc | Bin 0 -> 4321 bytes .../__pycache__/request.cpython-37.pyc | Bin 0 -> 1825 bytes .../__pycache__/response.cpython-37.pyc | Bin 0 -> 3336 bytes .../__pycache__/user_agent.cpython-37.pyc | Bin 0 -> 853 bytes .../site-packages/werkzeug/wrappers/accept.py | 50 + .../site-packages/werkzeug/wrappers/auth.py | 33 + .../werkzeug/wrappers/base_request.py | 693 ++ .../werkzeug/wrappers/base_response.py | 702 ++ .../werkzeug/wrappers/common_descriptors.py | 322 + .../site-packages/werkzeug/wrappers/etag.py | 304 + .../site-packages/werkzeug/wrappers/json.py | 145 + .../werkzeug/wrappers/request.py | 44 + .../werkzeug/wrappers/response.py | 78 + .../werkzeug/wrappers/user_agent.py | 15 + .../python3.7/site-packages/werkzeug/wsgi.py | 1067 +++ .../wrapt-1.11.1-py3.7.egg-info/PKG-INFO | 166 + .../wrapt-1.11.1-py3.7.egg-info/SOURCES.txt | 11 + .../dependency_links.txt | 1 + .../installed-files.txt | 13 + .../wrapt-1.11.1-py3.7.egg-info/top_level.txt | 1 + .../python3.7/site-packages/wrapt/__init__.py | 16 + .../wrapt/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 992 bytes .../__pycache__/decorators.cpython-37.pyc | Bin 0 -> 8913 bytes .../wrapt/__pycache__/importer.cpython-37.pyc | Bin 0 -> 4248 bytes .../wrapt/__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 24036 bytes .../wrapt/_wrappers.cpython-37m-darwin.so | Bin 0 -> 53260 bytes .../site-packages/wrapt/decorators.py | 511 + .../python3.7/site-packages/wrapt/importer.py | 230 + .../python3.7/site-packages/wrapt/wrappers.py | 943 ++ venv/pyvenv.cfg | 3 + 2978 files changed, 291181 insertions(+) create mode 100644 .gitattributes create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 __pycache__/hello.cpython-37.pyc create mode 100644 hello.py create mode 100644 venv/bin/activate create mode 100644 venv/bin/activate.csh create mode 100644 venv/bin/activate.fish create mode 100755 venv/bin/easy_install create mode 100755 venv/bin/easy_install-3.7 create mode 100755 venv/bin/epylint create mode 100755 venv/bin/flask create mode 100755 venv/bin/isort create mode 100755 venv/bin/pip create mode 100755 venv/bin/pip3 create mode 100755 venv/bin/pip3.7 create mode 100755 venv/bin/pylint create mode 100755 venv/bin/pyreverse create mode 120000 venv/bin/python create mode 120000 venv/bin/python3 create mode 100755 venv/bin/symilar create mode 100644 venv/lib/python3.7/site-packages/Click-7.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/Click-7.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.7/site-packages/Click-7.0.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/Click-7.0.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/Click-7.0.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/Click-7.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/LICENSE create mode 100644 venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/LICENSE create mode 100644 venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/__pycache__/mccabe.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/COPYING create mode 100644 venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/COPYING.LESSER create mode 100644 venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/astroid/__init__.py create mode 100644 venv/lib/python3.7/site-packages/astroid/__pkginfo__.py create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/__pkginfo__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/_ast.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/arguments.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/as_string.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/bases.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/builder.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/context.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/decorators.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/helpers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/inference.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/manager.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/mixins.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/modutils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/node_classes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/nodes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/objects.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/protocols.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/raw_building.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/rebuilder.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/scoped_nodes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/test_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/transforms.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/__pycache__/util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/_ast.py create mode 100644 venv/lib/python3.7/site-packages/astroid/arguments.py create mode 100644 venv/lib/python3.7/site-packages/astroid/as_string.py create mode 100644 venv/lib/python3.7/site-packages/astroid/bases.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_attrs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_collections.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_curses.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_functools.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_gi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_http.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_io.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_nose.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_numpy.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_pytest.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_qt.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_random.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_re.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_threading.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_typing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_argparse.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_attrs.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_builtin_inference.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_collections.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_curses.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_dateutil.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_fstrings.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_functools.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_gi.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_hashlib.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_http.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_io.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_mechanize.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_multiprocessing.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_namedtuple_enum.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_nose.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_numpy.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_pkg_resources.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_pytest.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_qt.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_random.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_re.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_six.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_ssl.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_subprocess.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_threading.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_typing.py create mode 100644 venv/lib/python3.7/site-packages/astroid/brain/brain_uuid.py create mode 100644 venv/lib/python3.7/site-packages/astroid/builder.py create mode 100644 venv/lib/python3.7/site-packages/astroid/context.py create mode 100644 venv/lib/python3.7/site-packages/astroid/decorators.py create mode 100644 venv/lib/python3.7/site-packages/astroid/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/astroid/helpers.py create mode 100644 venv/lib/python3.7/site-packages/astroid/inference.py create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/__init__.py create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/_import/__init__.py create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/_import/spec.py create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/_import/util.py create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/dunder_lookup.py create mode 100644 venv/lib/python3.7/site-packages/astroid/interpreter/objectmodel.py create mode 100644 venv/lib/python3.7/site-packages/astroid/manager.py create mode 100644 venv/lib/python3.7/site-packages/astroid/mixins.py create mode 100644 venv/lib/python3.7/site-packages/astroid/modutils.py create mode 100644 venv/lib/python3.7/site-packages/astroid/node_classes.py create mode 100644 venv/lib/python3.7/site-packages/astroid/nodes.py create mode 100644 venv/lib/python3.7/site-packages/astroid/objects.py create mode 100644 venv/lib/python3.7/site-packages/astroid/protocols.py create mode 100644 venv/lib/python3.7/site-packages/astroid/raw_building.py create mode 100644 venv/lib/python3.7/site-packages/astroid/rebuilder.py create mode 100644 venv/lib/python3.7/site-packages/astroid/scoped_nodes.py create mode 100644 venv/lib/python3.7/site-packages/astroid/test_utils.py create mode 100644 venv/lib/python3.7/site-packages/astroid/transforms.py create mode 100644 venv/lib/python3.7/site-packages/astroid/util.py create mode 100644 venv/lib/python3.7/site-packages/click/__init__.py create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_bashcomplete.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_termui_impl.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_textwrap.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_unicodefun.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/_winconsole.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/core.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/decorators.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/formatting.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/globals.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/termui.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/testing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/types.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/click/_bashcomplete.py create mode 100644 venv/lib/python3.7/site-packages/click/_compat.py create mode 100644 venv/lib/python3.7/site-packages/click/_termui_impl.py create mode 100644 venv/lib/python3.7/site-packages/click/_textwrap.py create mode 100644 venv/lib/python3.7/site-packages/click/_unicodefun.py create mode 100644 venv/lib/python3.7/site-packages/click/_winconsole.py create mode 100644 venv/lib/python3.7/site-packages/click/core.py create mode 100644 venv/lib/python3.7/site-packages/click/decorators.py create mode 100644 venv/lib/python3.7/site-packages/click/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/click/formatting.py create mode 100644 venv/lib/python3.7/site-packages/click/globals.py create mode 100644 venv/lib/python3.7/site-packages/click/parser.py create mode 100644 venv/lib/python3.7/site-packages/click/termui.py create mode 100644 venv/lib/python3.7/site-packages/click/testing.py create mode 100644 venv/lib/python3.7/site-packages/click/types.py create mode 100644 venv/lib/python3.7/site-packages/click/utils.py create mode 100644 venv/lib/python3.7/site-packages/easy_install.py create mode 100644 venv/lib/python3.7/site-packages/flask/__init__.py create mode 100644 venv/lib/python3.7/site-packages/flask/__main__.py create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/app.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/blueprints.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/cli.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/config.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/ctx.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/debughelpers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/globals.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/helpers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/logging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/sessions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/signals.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/templating.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/testing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/views.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/__pycache__/wrappers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/_compat.py create mode 100644 venv/lib/python3.7/site-packages/flask/app.py create mode 100644 venv/lib/python3.7/site-packages/flask/blueprints.py create mode 100644 venv/lib/python3.7/site-packages/flask/cli.py create mode 100644 venv/lib/python3.7/site-packages/flask/config.py create mode 100644 venv/lib/python3.7/site-packages/flask/ctx.py create mode 100644 venv/lib/python3.7/site-packages/flask/debughelpers.py create mode 100644 venv/lib/python3.7/site-packages/flask/globals.py create mode 100644 venv/lib/python3.7/site-packages/flask/helpers.py create mode 100644 venv/lib/python3.7/site-packages/flask/json/__init__.py create mode 100644 venv/lib/python3.7/site-packages/flask/json/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/json/__pycache__/tag.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/flask/json/tag.py create mode 100644 venv/lib/python3.7/site-packages/flask/logging.py create mode 100644 venv/lib/python3.7/site-packages/flask/sessions.py create mode 100644 venv/lib/python3.7/site-packages/flask/signals.py create mode 100644 venv/lib/python3.7/site-packages/flask/templating.py create mode 100644 venv/lib/python3.7/site-packages/flask/testing.py create mode 100644 venv/lib/python3.7/site-packages/flask/views.py create mode 100644 venv/lib/python3.7/site-packages/flask/wrappers.py create mode 100644 venv/lib/python3.7/site-packages/isort-4.3.20.dist-info/INSTALLER create mode 100755 venv/lib/python3.7/site-packages/isort-4.3.20.dist-info/LICENSE create mode 100644 venv/lib/python3.7/site-packages/isort-4.3.20.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/isort-4.3.20.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/isort-4.3.20.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/isort-4.3.20.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/isort-4.3.20.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/isort/__init__.py create mode 100644 venv/lib/python3.7/site-packages/isort/__main__.py create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/finders.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/hooks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/isort.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/main.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/natural.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/pie_slice.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/pylama_isort.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/settings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/isort/finders.py create mode 100644 venv/lib/python3.7/site-packages/isort/hooks.py create mode 100644 venv/lib/python3.7/site-packages/isort/isort.py create mode 100644 venv/lib/python3.7/site-packages/isort/main.py create mode 100644 venv/lib/python3.7/site-packages/isort/natural.py create mode 100644 venv/lib/python3.7/site-packages/isort/pie_slice.py create mode 100644 venv/lib/python3.7/site-packages/isort/pylama_isort.py create mode 100644 venv/lib/python3.7/site-packages/isort/settings.py create mode 100644 venv/lib/python3.7/site-packages/isort/utils.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous-1.1.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/itsdangerous-1.1.0.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.7/site-packages/itsdangerous-1.1.0.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/itsdangerous-1.1.0.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/itsdangerous-1.1.0.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/itsdangerous-1.1.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__init__.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/_json.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/encoding.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/exc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/jws.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/serializer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/signer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/timed.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/__pycache__/url_safe.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/_compat.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/_json.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/encoding.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/exc.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/jws.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/serializer.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/signer.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/timed.py create mode 100644 venv/lib/python3.7/site-packages/itsdangerous/url_safe.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/__init__.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/_identifier.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/asyncfilters.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/asyncsupport.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/bccache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/compiler.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/constants.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/debug.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/defaults.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/environment.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/ext.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/filters.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/idtracking.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/lexer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/loaders.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/meta.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/nativetypes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/nodes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/optimizer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/runtime.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/sandbox.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/tests.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/__pycache__/visitor.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/jinja2/_compat.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/_identifier.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/asyncfilters.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/asyncsupport.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/bccache.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/compiler.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/constants.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/debug.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/defaults.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/environment.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/ext.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/filters.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/idtracking.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/lexer.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/loaders.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/meta.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/nativetypes.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/nodes.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/optimizer.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/parser.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/runtime.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/sandbox.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/tests.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/utils.py create mode 100644 venv/lib/python3.7/site-packages/jinja2/visitor.py create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy-1.4.1.dist-info/AUTHORS.rst create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy-1.4.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy-1.4.1.dist-info/LICENSE create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy-1.4.1.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy-1.4.1.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy-1.4.1.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy-1.4.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/__init__.py create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/__pycache__/_version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/__pycache__/simple.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/__pycache__/slots.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/_version.py create mode 100755 venv/lib/python3.7/site-packages/lazy_object_proxy/cext.cpython-37m-darwin.so create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/compat.py create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/simple.py create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/slots.py create mode 100644 venv/lib/python3.7/site-packages/lazy_object_proxy/utils.py create mode 100644 venv/lib/python3.7/site-packages/markupsafe/__init__.py create mode 100644 venv/lib/python3.7/site-packages/markupsafe/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/markupsafe/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/markupsafe/__pycache__/_constants.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/markupsafe/__pycache__/_native.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/markupsafe/_compat.py create mode 100644 venv/lib/python3.7/site-packages/markupsafe/_constants.py create mode 100644 venv/lib/python3.7/site-packages/markupsafe/_native.py create mode 100644 venv/lib/python3.7/site-packages/markupsafe/_speedups.c create mode 100644 venv/lib/python3.7/site-packages/markupsafe/_speedups.cpython-37m-darwin.so create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/metadata.json create mode 100644 venv/lib/python3.7/site-packages/mccabe-0.6.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/mccabe.py create mode 100644 venv/lib/python3.7/site-packages/pip-19.0.3.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/pip-19.0.3.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.7/site-packages/pip-19.0.3.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/pip-19.0.3.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/pip-19.0.3.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/pip-19.0.3.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/pip-19.0.3.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/pip/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/__main__.py create mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/locations.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/build_env.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/base_command.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/download.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/show.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/completion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/configuration.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/download.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/freeze.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/hash.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/help.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/install.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/list.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/search.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/show.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/commands/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/configuration.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/download.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/locations.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/candidate.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/format_control.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/models/link.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/freeze.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/operations/prepare.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/pep425tags.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/pyproject.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_set.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/constructors.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_file.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_install.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_set.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/resolve.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/typing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/encoding.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/glibc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/hashes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/logging.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/misc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/models.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/outdated.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/packaging.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/typing.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/utils/ui.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/git.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py create mode 100644 venv/lib/python3.7/site-packages/pip/_internal/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/certifi/core.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/chardet/version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/database.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/index.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/util.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/distro.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/codec.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/core.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/ipaddress.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/build.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/check.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/bar.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/counter.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/test.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/api.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/auth.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/certs.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/compat.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/help.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/models.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/packages.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/structures.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/requests/utils.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/retrying.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 venv/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pkg_resources/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/pylint-2.3.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/pylint-2.3.1.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/pylint-2.3.1.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/pylint-2.3.1.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/pylint-2.3.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/pylint-2.3.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/__main__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/__pkginfo__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/__main__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/__pkginfo__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/config.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/epylint.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/graph.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/interfaces.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/lint.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/testutils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/async.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/classes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/format.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/imports.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/logging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/misc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/newstyle.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/python3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/raw_metrics.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/refactoring.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/similar.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/spelling.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/stdlib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/strings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/typecheck.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/__pycache__/variables.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/async.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/base.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/classes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/design_analysis.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/format.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/imports.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/logging.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/misc.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/newstyle.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/python3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/raw_metrics.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/refactoring.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/similar.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/spelling.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/stdlib.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/strings.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/typecheck.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/utils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/checkers/variables.py create mode 100644 venv/lib/python3.7/site-packages/pylint/config.py create mode 100644 venv/lib/python3.7/site-packages/pylint/epylint.py create mode 100644 venv/lib/python3.7/site-packages/pylint/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/_check_docs_utils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/bad_builtin.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/check_docs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/check_elif.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/comparetozero.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/docparams.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/docstyle.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/emptystring.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/mccabe.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/overlapping_exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/extensions/redefined_variable_type.py create mode 100644 venv/lib/python3.7/site-packages/pylint/graph.py create mode 100644 venv/lib/python3.7/site-packages/pylint/interfaces.py create mode 100644 venv/lib/python3.7/site-packages/pylint/lint.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/diadefslib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/diagrams.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/inspector.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/main.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/vcgutils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/__pycache__/writer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/diadefslib.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/diagrams.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/inspector.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/main.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/utils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/vcgutils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/pyreverse/writer.py create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/__pycache__/json.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/__pycache__/text.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/json.py create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/text.py create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/ureports/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/ureports/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/ureports/__pycache__/nodes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/ureports/__pycache__/text_writer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/ureports/nodes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/reporters/ureports/text_writer.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/conftest.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/test_func.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/test_functional.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/test_import_graph.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/test_regr.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/test_self.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_base.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_classes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_format.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_imports.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_logging.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_misc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_python3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_similar.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_spelling.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_stdlib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_strings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_typecheck.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checker_variables.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_checkers_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_config.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_lint.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_pyreverse_diadefs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_pyreverse_inspector.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_pyreverse_writer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_reporters_json.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_reporting.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/__pycache__/unittest_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/acceptance/__pycache__/test_stdlib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/acceptance/test_stdlib.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/conftest.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/__pycache__/clientmodule_test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/__pycache__/suppliermodule_test.cpython-37.pyc create mode 100755 venv/lib/python3.7/site-packages/pylint/test/data/ascript create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/classes_No_Name.dot create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/clientmodule_test.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/packages_No_Name.dot create mode 100644 venv/lib/python3.7/site-packages/pylint/test/data/suppliermodule_test.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_bad_builtin.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_check_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_check_docs_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_check_mccabe.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_check_raise_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_check_return_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_check_yields_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_comparetozero.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_docstyle.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_elseif_used.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_emptystring.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_overlapping_exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/__pycache__/test_redefined.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/bad_builtin.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/compare_to_zero.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/docstring.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/elif.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/empty_string_comparison.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/mccabe.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions_py33.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/__pycache__/redefined.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/bad_builtin.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/compare_to_zero.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/docstring.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/elif.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/empty_string_comparison.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/mccabe.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/overlapping_exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/overlapping_exceptions_py33.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/data/redefined.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_bad_builtin.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_check_docs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_check_docs_utils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_check_mccabe.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_check_raise_docs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_check_return_docs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_check_yields_docs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_comparetozero.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_docstyle.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_elseif_used.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_emptystring.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_overlapping_exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/extensions/test_redefined.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/abstract_abc_methods.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_in_class.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py34.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/abstract_method_py2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/abstract_method_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/access_member_before_definition.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/access_to__name__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/access_to_protected_members.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/anomalous_unicode_escape_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/arguments.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/arguments_differ.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/arguments_differ_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/assert_on_tuple.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/assigning_non_slot.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/attribute_defined_outside_init.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_continuation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_continuation_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_continuation_tabs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_exception_context.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_indentation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_inline_option.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_open_mode.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_open_mode_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_reversed_sequence.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_staticmethod_argument.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_thread_instantiation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bad_whitespace.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bare_except.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/blacklisted_name.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/boolean_datetime.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/broad_except.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/bugfix_local_scope_metaclass_1177.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/cellvar_escaping_loop.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/class_members_py30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/class_scope.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/comparison_with_callable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/confidence_filter.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/confusing_with_statement.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_iterating_dictionary.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_join.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_merging_isinstance.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_swap_variables.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_using_dict_comprehension.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_using_enumerate.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_using_get.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_using_in.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/consider_using_set_comprehension.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/control_pragmas.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/crash_missing_module_type.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/ctor_arguments.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/dangerous_default_value.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/dangerous_default_value_py30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/defined_and_used_on_same_line.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_lambda.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_method_getmoduleinfo.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_module_py2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_module_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_module_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_module_py4.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/deprecated_module_uninstalled.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/disable_msg_github_issue_1389.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/disable_ungrouped_imports.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_order.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_position.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/docstrings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/duplicate_bases.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/duplicate_dict_literal_key.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/duplicate_except.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/duplicate_string_formatting_argument.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/eval_used.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/exception_is_binary_op.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/exception_message.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/exec_used_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/fallback_import_disabled.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/fallback_import_enabled.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/fixme.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/fixme_bad_formatting_1139.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/formatted_string_literal_with_if_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/function_redefined.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/future_import.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/future_unicode_literals.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/generated_members.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/genexp_in_class_scope.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/genexpr_variable_scope.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/globals.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_latin1.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_multiline.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_utf8.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/import_error.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/inconsistent_mro.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/inconsistent_returns.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/indexing_exception.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/inherit_non_class.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/init_is_generator.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/init_not_called.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/init_subclass_classmethod_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_all_object.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_encoding_py27.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_envvar_value.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_caught.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_raised.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_length_returned.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_metaclass.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_metaclass_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_name.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_sequence_index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_slice_index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/invalid_unary_operand_type.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/iterable_context.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/iterable_context_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/iterable_context_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/keyword_arg_before_vararg.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/len_checks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/line_endings.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/line_too_long.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/line_too_long_end_of_module.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/literal_comparison.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/logging_fstring_interpolation_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/logging_not_lazy.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/logical_tautology.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/long_lines_with_utf8.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/long_utf8_lines.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/lost_exception.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/mapping_context.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/mapping_context_py2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/mapping_context_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/member_checks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/member_checks_hints.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/member_checks_ignore_none.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/member_checks_inference_improvements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/member_checks_no_hints.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/member_checks_opaque.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/member_checks_py37.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/membership_protocol.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/membership_protocol_py2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/membership_protocol_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/messages_managed_by_id.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/method_hidden.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/misplaced_bare_raise.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/misplaced_comparison_constant.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/misplaced_format_function.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/missing_docstring.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/missing_final_newline.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/missing_kwoa_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/missing_self_argument.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/mixed_indentation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/monkeypatch_method.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/multiple_imports.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/namePresetCamelCase.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/name_preset_snake_case.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/name_styles.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/namedtuple_member_inference.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/names_in__all__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/nested_blocks_issue1088.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_classmethod_decorator.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_else_raise.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_else_return.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_name_in_module.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_self_argument_py37.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_self_use.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_self_use_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/no_staticmethod_decorator.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/non_iterator_returned.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/none_dunder_protocols_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/nonexistent_operator.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/not_async_context_manager.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/not_callable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/not_context_manager.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_activated.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_not_activated.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/protected_access_access_different_scopes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/raising_format_tuple.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/raising_non_exception_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/raising_self.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/recursion_error_2667.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/recursion_error_940.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/recursion_error_crash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/recursion_error_crash_2683.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/recursion_error_crash_astroid_623.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/redefined_argument_from_local.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/redefined_builtin.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/redundant_unittest_assert.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/regression_1326_crash_uninferable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/regression_no_value_for_parameter.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/reimported.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/repeated_keyword.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/return_in_init.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/self_cls_assignment.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/signature_differs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/simplifiable_if_expression.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/simplifiable_if_statement.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/simplify_chained_comparison.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/singledispatch_functions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/singledispatch_functions_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/singleton_comparison.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/slots_checks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/socketerror_import.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/statement_without_effect.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/statement_without_effect_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/stop_iteration_inside_generator.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/string_formatting.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/string_formatting_disable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/string_formatting_failed_inference.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/string_formatting_failed_inference_py35.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/string_formatting_py27.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/string_formatting_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/subprocess_popen_preexec_fn.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/super_checks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/superfluous_parens.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/sys_stream_regression_1004.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/ternary.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/test_compile.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/tokenize_error.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/tokenize_error_jython.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_few_public_methods.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_few_public_methods_37.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_ancestors.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_arguments.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_arguments_issue_1045.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_boolean_expressions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_branches.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_instance_attributes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_lines.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_lines_disabled.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_locals.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_nested_blocks.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_public_methods.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_return_statements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/too_many_statements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/trailing_comma_tuple.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/trailing_newlines.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/trailing_whitespaces.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/try_except_raise_crash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking_py30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/undefined_loop_variable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/undefined_variable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/undefined_variable_py30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unexpected_special_method_signature.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/ungrouped_imports.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unhashable_dict_key.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unidiomatic_typecheck.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/uninferable_all_object.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unnecessary_lambda.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unnecessary_pass.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unneeded_not.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unpacking.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unpacking_generalizations.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unpacking_non_sequence.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unreachable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unrecognized_inline_option.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unsubscriptable_value.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unsubscriptable_value_py37.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unsupported_assignment_operation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unsupported_binary_operation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unsupported_delete_operation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_argument.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_argument_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_global_variable1.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_global_variable2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_global_variable3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_global_variable4.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_import.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_import_assigned_to.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_typing_imports.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_variable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/unused_variable_py36.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/used_before_assignment_488.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue1081.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue853.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/used_before_assignment_nonlocal.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/useless-import-alias.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/useless_else_on_loop.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/useless_object_inheritance.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/useless_return.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/useless_super_delegation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py35.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/using_constant_test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wildcard_import.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wildcard_import_allowed.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/with_used_before_assign.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/with_using_generator.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_exception_operation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_order.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_order2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position10.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position11.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position12.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position13.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position14.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position15.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position4.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position5.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position6.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position7.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position8.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position9.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/wrong_import_position_exclude_dunder_main.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/__pycache__/yield_from_iterable_py33.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_abc_methods.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_in_class.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py34.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py34.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_class_instantiated_py34.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_method_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_method_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_method_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_method_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_method_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/abstract_method_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/access_member_before_definition.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/access_member_before_definition.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/access_to__name__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/access_to__name__.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/access_to_protected_members.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/access_to_protected_members.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/arguments.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/arguments.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/arguments_differ.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/arguments_differ.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/arguments_differ_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/arguments_differ_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/arguments_differ_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assert_on_tuple.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assert_on_tuple.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assigning_non_slot.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assigning_non_slot.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assignment_from_no_return.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assignment_from_no_return.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assignment_from_no_return_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assignment_from_no_return_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/assignment_from_no_return_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/async_functions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/async_functions.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/async_functions.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/attribute_defined_outside_init.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/attribute_defined_outside_init.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_continuation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_continuation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_continuation_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_continuation_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_continuation_tabs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_continuation_tabs.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_continuation_tabs.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_except_order.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_except_order.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_exception_context.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_exception_context.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_exception_context.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_indentation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_indentation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_inline_option.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_inline_option.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_inline_option.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_open_mode.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_open_mode.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_open_mode.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_open_mode_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_open_mode_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_open_mode_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_reversed_sequence.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_reversed_sequence.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_staticmethod_argument.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_staticmethod_argument.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_thread_instantiation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_thread_instantiation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_whitespace.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bad_whitespace.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bare_except.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bare_except.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/blacklisted_name.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/blacklisted_name.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/boolean_datetime.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/boolean_datetime.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/boolean_datetime.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/broad_except.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/broad_except.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/cellvar_escaping_loop.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/cellvar_escaping_loop.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_members_py27.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_members_py27.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_members_py27.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_members_py30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_members_py30.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_members_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_scope.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/class_scope.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/comparison_with_callable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/comparison_with_callable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/confidence_filter.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/confidence_filter.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/confidence_filter.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/confusing_with_statement.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/confusing_with_statement.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_iterating_dictionary.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_iterating_dictionary.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_join.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_join.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_merging_isinstance.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_merging_isinstance.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_swap_variables.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_swap_variables.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_dict_comprehension.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_dict_comprehension.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_enumerate.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_enumerate.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_get.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_get.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_in.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_in.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_set_comprehension.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/consider_using_set_comprehension.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/continue_in_finally.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/continue_in_finally.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/control_pragmas.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/control_pragmas.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/crash_missing_module_type.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/crash_missing_module_type.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/ctor_arguments.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/ctor_arguments.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/dangerous_default_value.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/dangerous_default_value.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/dangerous_default_value.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/dangerous_default_value_py30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/dangerous_default_value_py30.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/dangerous_default_value_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/defined_and_used_on_same_line.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_lambda.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_lambda.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_lambda.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_methods_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py4.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py4.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_py4.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_uninstalled.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_uninstalled.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/deprecated_module_uninstalled.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/disable_msg_github_issue_1389.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/disable_msg_github_issue_1389.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/disable_ungrouped_imports.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/disable_ungrouped_imports.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/disable_wrong_import_order.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/disable_wrong_import_order.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/disable_wrong_import_position.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/docstrings.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/docstrings.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_argument_name.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_argument_name.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_argument_name_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_argument_name_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_argument_name_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_bases.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_bases.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_dict_literal_key.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_dict_literal_key.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_except.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_except.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_string_formatting_argument.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/duplicate_string_formatting_argument.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/eval_used.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/eval_used.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exception_is_binary_op.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exception_is_binary_op.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exception_message.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exception_message.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exception_message.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exec_used_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exec_used_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exec_used_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exec_used_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exec_used_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/exec_used_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fallback_import_disabled.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fallback_import_disabled.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fallback_import_enabled.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fallback_import_enabled.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fallback_import_enabled.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fixme.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fixme.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fixme_bad_formatting_1139.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fixme_bad_formatting_1139.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/fixme_bad_formatting_1139.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/formatting.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/function_redefined.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/function_redefined.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/future_import.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/future_unicode_literals.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/future_unicode_literals.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/future_unicode_literals.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/generated_members.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/generated_members.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/genexp_in_class_scope.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/genexp_in_class_scope.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/genexpr_variable_scope.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/genexpr_variable_scope.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/globals.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/globals.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_latin1.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_latin1.txt create mode 100755 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_multiline.py create mode 100755 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_multiline.rc create mode 100755 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_multiline.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_utf8.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_utf8.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/import_error.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/import_error.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/import_error.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/inconsistent_mro.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/inconsistent_mro.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/inconsistent_returns.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/inconsistent_returns.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/inconsistent_returns.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/indexing_exception.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/indexing_exception.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/indexing_exception.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/inherit_non_class.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/inherit_non_class.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/init_is_generator.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/init_is_generator.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/init_not_called.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/init_not_called.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/init_subclass_classmethod_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/init_subclass_classmethod_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_all_object.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_all_object.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_encoding_py27.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_encoding_py27.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_encoding_py27.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_envvar_value.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_envvar_value.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_exceptions_caught.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_exceptions_caught.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_exceptions_raised.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_exceptions_raised.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_length_returned.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_length_returned.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_metaclass.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_metaclass.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_metaclass_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_metaclass_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_metaclass_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_name.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_name.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_sequence_index.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_sequence_index.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_slice_index.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_slice_index.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_star_assignment_target.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_star_assignment_target.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_star_assignment_target.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_unary_operand_type.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/invalid_unary_operand_type.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/iterable_context_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/keyword_arg_before_vararg.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/keyword_arg_before_vararg.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/len_checks.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/len_checks.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/line_endings.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/line_endings.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/line_endings.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/line_too_long.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/line_too_long.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/line_too_long_end_of_module.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/literal_comparison.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/literal_comparison.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_format_interpolation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_format_interpolation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_format_interpolation_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_format_interpolation_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_format_interpolation_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_not_lazy.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logging_not_lazy.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logical_tautology.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/logical_tautology.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/long_lines_with_utf8.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/long_lines_with_utf8.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/long_utf8_lines.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/long_utf8_lines.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/lost_exception.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/lost_exception.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mapping_context_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_hints.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_hints.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_hints.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_ignore_none.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_ignore_none.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_ignore_none.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_inference_improvements.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_no_hints.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_no_hints.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_no_hints.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_opaque.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_opaque.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_opaque.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_py37.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_py37.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/member_checks_py37.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol_py2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol_py2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol_py2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/membership_protocol_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/messages_managed_by_id.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/messages_managed_by_id.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/method_hidden.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/method_hidden.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_bare_raise.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_bare_raise.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_comparison_constant.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_comparison_constant.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_format_function.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_format_function.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_future.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/misplaced_future.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_docstring.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_docstring.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_final_newline.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_final_newline.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_kwoa_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_kwoa_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_kwoa_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_self_argument.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/missing_self_argument.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mixed_indentation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/mixed_indentation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/monkeypatch_method.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/monkeypatch_method.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/multiple_imports.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/multiple_imports.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/namePresetCamelCase.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/namePresetCamelCase.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/namePresetCamelCase.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/name_preset_snake_case.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/name_preset_snake_case.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/name_preset_snake_case.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/name_styles.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/name_styles.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/name_styles.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/namedtuple_member_inference.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/namedtuple_member_inference.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/names_in__all__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/names_in__all__.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nested_blocks_issue1088.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nested_blocks_issue1088.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_classmethod_decorator.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_classmethod_decorator.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_else_raise.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_else_raise.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_else_return.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_else_return.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_name_in_module.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_name_in_module.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_argument_py37.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_argument_py37.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_argument_py37.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_use.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_use.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_use_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_use_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_self_use_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_staticmethod_decorator.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/no_staticmethod_decorator.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/non_iterator_returned.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/non_iterator_returned.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/none_dunder_protocols_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/none_dunder_protocols_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/none_dunder_protocols_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonexistent_operator.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonexistent_operator.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonlocal_and_global.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonlocal_and_global.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonlocal_and_global.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonlocal_without_binding.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonlocal_without_binding.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/nonlocal_without_binding.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_async_context_manager.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_async_context_manager.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_async_context_manager.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_async_context_manager_py37.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_async_context_manager_py37.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_async_context_manager_py37.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_callable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_callable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_context_manager.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_context_manager.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_in_loop.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/not_in_loop.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/old_division_manually.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/old_division_manually.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/postponed_evaluation_activated.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/postponed_evaluation_activated.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/postponed_evaluation_activated.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/postponed_evaluation_not_activated.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/postponed_evaluation_not_activated.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/postponed_evaluation_not_activated.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/print_always_warns.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/print_always_warns.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/print_always_warns.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/protected_access_access_different_scopes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/protected_access_access_different_scopes.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/protected_access_access_different_scopes.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/raising_format_tuple.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/raising_format_tuple.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/raising_non_exception_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/raising_non_exception_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/raising_non_exception_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/raising_self.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/raising_self.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_2667.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_2667.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_940.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_crash.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_crash.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_crash_2683.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_crash_2683.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_crash_astroid_623.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/recursion_error_crash_astroid_623.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redefine_in_handler.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redefine_in_handler.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redefine_in_handler.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redefined_argument_from_local.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redefined_argument_from_local.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redefined_builtin.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redefined_builtin.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redundant_unittest_assert.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/redundant_unittest_assert.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/regression_1326_crash_uninferable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/regression_no_value_for_parameter.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/regression_no_value_for_parameter.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/reimported.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/reimported.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/repeated_keyword.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/repeated_keyword.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/return_in_init.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/return_in_init.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/return_outside_function.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/return_outside_function.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/reused_outer_loop_variable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/reused_outer_loop_variable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/self_cls_assignment.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/self_cls_assignment.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/signature_differs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/signature_differs.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/simplifiable_if_expression.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/simplifiable_if_expression.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/simplifiable_if_statement.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/simplifiable_if_statement.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/simplify_chained_comparison.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/simplify_chained_comparison.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singledispatch_functions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singledispatch_functions.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singledispatch_functions.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singledispatch_functions_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singledispatch_functions_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singledispatch_functions_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singleton_comparison.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/singleton_comparison.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/slots_checks.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/slots_checks.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/socketerror_import.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/star_needs_assignment_target.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/star_needs_assignment_target.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/star_needs_assignment_target.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/star_needs_assignment_target_py35.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/star_needs_assignment_target_py35.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/star_needs_assignment_target_py35.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/statement_without_effect.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/statement_without_effect.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/statement_without_effect_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/statement_without_effect_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/statement_without_effect_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/stop_iteration_inside_generator.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/stop_iteration_inside_generator.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/stop_iteration_inside_generator.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_disable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_disable.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_disable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_failed_inference.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_failed_inference_py35.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_failed_inference_py35.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_py27.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_py27.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_py27.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/string_formatting_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/super_checks.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/super_checks.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/superfluous_parens.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/superfluous_parens.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/suspicious_str_strip_call.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/suspicious_str_strip_call.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/suspicious_str_strip_call.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/syntax_error.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/syntax_error.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/syntax_error.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/syntax_error_jython.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/syntax_error_jython.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/syntax_error_jython.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/sys_stream_regression_1004.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/sys_stream_regression_1004.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/sys_stream_regression_1004.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/ternary.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/ternary.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/test_compile.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/tokenize_error.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/tokenize_error.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/tokenize_error.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/tokenize_error_jython.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/tokenize_error_jython.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/tokenize_error_jython.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_few_public_methods.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_few_public_methods.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_few_public_methods_37.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_few_public_methods_37.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_few_public_methods_37.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_ancestors.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_ancestors.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_arguments.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_arguments.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_arguments_issue_1045.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_arguments_issue_1045.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_arguments_issue_1045.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_boolean_expressions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_boolean_expressions.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_branches.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_branches.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_instance_attributes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_instance_attributes.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_lines.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_lines.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_lines_disabled.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_locals.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_locals.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_nested_blocks.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_nested_blocks.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_public_methods.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_public_methods.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_return_statements.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_return_statements.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_star_expressions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_star_expressions.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_star_expressions.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_statements.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/too_many_statements.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/trailing_comma_tuple.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/trailing_comma_tuple.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/trailing_comma_tuple.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/trailing_newlines.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/trailing_newlines.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/trailing_whitespaces.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/trailing_whitespaces.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/try_except_raise.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/try_except_raise.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/try_except_raise_crash.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/try_except_raise_crash.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/undefined_loop_variable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/undefined_loop_variable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/undefined_variable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/undefined_variable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/undefined_variable_py30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/undefined_variable_py30.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/undefined_variable_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unexpected_special_method_signature.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unexpected_special_method_signature.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/ungrouped_imports.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/ungrouped_imports.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unhashable_dict_key.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unhashable_dict_key.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unidiomatic_typecheck.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unidiomatic_typecheck.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/uninferable_all_object.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unnecessary_lambda.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unnecessary_lambda.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unnecessary_pass.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unnecessary_pass.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unneeded_not.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unneeded_not.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacked_exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacked_exceptions.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacked_exceptions.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacking.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacking_generalizations.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacking_generalizations.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacking_generalizations.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacking_non_sequence.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unpacking_non_sequence.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unreachable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unreachable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unrecognized_inline_option.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unrecognized_inline_option.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsubscriptable_value.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsubscriptable_value.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsubscriptable_value_py37.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsubscriptable_value_py37.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsubscriptable_value_py37.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsupported_assignment_operation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsupported_assignment_operation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsupported_binary_operation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsupported_binary_operation.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsupported_binary_operation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsupported_delete_operation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unsupported_delete_operation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_argument.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_argument.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_argument_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_argument_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_argument_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable1.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable2.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable2.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable4.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable4.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_global_variable4.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_import.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_import.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_import_assigned_to.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_typing_imports.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_typing_imports.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_variable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_variable.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_variable_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_variable_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/unused_variable_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_before_assignment_488.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_before_assignment_issue1081.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_before_assignment_issue1081.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_before_assignment_issue853.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_before_assignment_nonlocal.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_before_assignment_nonlocal.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_before_assignment_nonlocal.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_prior_global_declaration.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_prior_global_declaration.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/used_prior_global_declaration.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless-import-alias.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless-import-alias.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_else_on_loop.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_else_on_loop.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_object_inheritance.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_object_inheritance.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_return.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_return.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation_py3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation_py3.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation_py3.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation_py35.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation_py35.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/useless_super_delegation_py35.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/using_constant_test.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/using_constant_test.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wildcard_import.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wildcard_import.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wildcard_import_allowed.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wildcard_import_allowed.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wildcard_import_allowed.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/with_used_before_assign.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/with_used_before_assign.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/with_using_generator.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/with_using_generator.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_exception_operation.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_exception_operation.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_order.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_order.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_order2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position10.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position11.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position11.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position12.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position12.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position13.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position13.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position14.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position14.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position15.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position4.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position5.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position6.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position7.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position8.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position9.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position_exclude_dunder_main.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/wrong_import_position_exclude_dunder_main.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_from_iterable_py33.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_from_iterable_py33.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_from_iterable_py33.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_from_outside_func.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_from_outside_func.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_from_outside_func.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_inside_async_function.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_inside_async_function.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_inside_async_function.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_inside_async_function_py36.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_inside_async_function_py36.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_inside_async_function_py36.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_outside_func.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/functional/yield_outside_func.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_3k_removed_stuff_py_30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_bad_cont_dictcomp_py27.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_bug113231.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_disable_linebased.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_dotted_ancestor.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_e0012.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_e0204.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_e12xx.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_e13xx.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_excess_escapes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_first_arg.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_i0011.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_i0012.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_i0013.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_i0014.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_i0020.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_i0022.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_logging_not_lazy_with_logger.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_loopvar_in_dict_comp_py27.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_module___dict__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_nameerror_on_string_substitution.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_no_dummy_redefined.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror___init___return_from_inner_function.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_access_attr_before_def_false_positive.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_base_init_vars.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_builtin_module_test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_class_attributes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_classes_meth_could_be_a_function.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_classes_protected_member_access.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_decorator_scope.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_e1101_9588_base_attr_aug_assign.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_external_classmethod_crash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_inner_classes.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_lambda_use_before_assign.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_mcs_attr_access.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_new_style_class_py_30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_no_warning_docstring.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_object_as_class_attribute.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_overloaded_operator.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_property_affectation_py26.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_yield_assign_py25.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_noerror_yield_return_mix.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_nonregr___file___global.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_return_yield_mix_py_33.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_typecheck_callfunc_assigment.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_unused_import_py30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_variables_unused_name_from_wilcard_import.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0233.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0401.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0401_disabled.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0401_disabled_in_func.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0404.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0405.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0406.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0611.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0612.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0613.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0623_py30.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/func_w0801.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/hide_code_with_imports.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/ignore_except_pass_by_default.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/not__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/w0401_cycle.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/__pycache__/w0801_same.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_3k_removed_stuff_py_30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_bad_cont_dictcomp_py27.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_bug113231.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_disable_linebased.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_dotted_ancestor.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_e0012.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_e0204.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_e12xx.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_e13xx.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_excess_escapes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_first_arg.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_i0011.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_i0012.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_i0013.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_i0014.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_i0020.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_i0022.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_logging_not_lazy_with_logger.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_loopvar_in_dict_comp_py27.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_module___dict__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_nameerror_on_string_substitution.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_no_dummy_redefined.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror___init___return_from_inner_function.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_access_attr_before_def_false_positive.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_base_init_vars.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_builtin_module_test.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_class_attributes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_classes_meth_could_be_a_function.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_classes_protected_member_access.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_decorator_scope.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_e1101_9588_base_attr_aug_assign.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_external_classmethod_crash.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_inner_classes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_lambda_use_before_assign.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_mcs_attr_access.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_new_style_class_py_30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_no_warning_docstring.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_object_as_class_attribute.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_overloaded_operator.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_property_affectation_py26.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_yield_assign_py25.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_noerror_yield_return_mix.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_nonregr___file___global.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_return_yield_mix_py_33.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_typecheck_callfunc_assigment.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_unused_import_py30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_variables_unused_name_from_wilcard_import.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0122_py_30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0233.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0332_py_30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_disabled.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_disabled_in_func.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/__pycache__/all_the_things.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing1.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing2.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/all_the_things.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/thing1.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0401_package/thing2.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0404.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0405.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0406.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0611.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0612.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0613.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0623_py30.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/func_w0801.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/hide_code_with_imports.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/ignore_except_pass_by_default.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/multiline-import create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/noext create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/not__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/similar1 create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/similar2 create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/w0401_cycle.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/input/w0801_same.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/builtin_module.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_3k_removed_stuff_py_30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_bad_cont_dictcomp_py27.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_bug113231.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_disable_linebased.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_disable_linebased_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_dotted_ancestor.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_e0012.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_e0204.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_e12xx.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_e13xx.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_e13xx_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_excess_escapes.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_first_arg.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_i0011.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_i0012.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_i0013.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_i0014.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_i0020.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_i0022.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_logging_not_lazy_with_logger.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_loopvar_in_dict_comp_py27.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_module___dict__.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_nameerror_on_string_substitution.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_no_dummy_redefined.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_nonregr___file___global.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_raw_escapes.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_return_yield_mix_py_33.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_toolonglines_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_typecheck_callfunc_assigment.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_typecheck_getattr_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_typecheck_non_callable_call.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_unicode_literal_py26.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_unicode_literal_py274.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_unused_import_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py29.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_variables_unused_name_from_wilcard_import.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0122_py_30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0233.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0312.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0332_py_30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0401.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0401_disabled.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0401_disabled_in_func.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0401_package.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0404.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0405.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0406.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0611.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0612.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0613.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0622.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0623.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0623_py30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0623_py_30.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_w0801.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/messages/func_with_without_as_py25.txt create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/.pylintrc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/application_crash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/classdoc_usage.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/decimal_inference.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/empty.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/func_block_disable_msg.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/import_assign.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/import_package_subpackage_module.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/import_something.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/meta.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/module_global.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/no_stdout_encoding.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/numarray_import.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/numarray_inf.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/precedence_test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/special_attr_scope_lookup_crash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/test_pylintrc_comments.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/try_finally_disable_msg_crash.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/unused_variable.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/wildcard.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/__pycache__/wrong_import_position.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/absimp/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/absimp/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/absimp/__pycache__/string.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/absimp/string.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/application_crash.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/bad_package/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/bad_package/__pycache__/wrong.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/bad_package/wrong.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/beyond_top/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/data.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/beyond_top/data.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/classdoc_usage.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/comments_pylintrc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/decimal_inference.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/descriptor_crash.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy/__pycache__/another.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy/__pycache__/dummy.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy/another.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy/dummy.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy_plugin.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy_plugin/__pycache__/dummy_conf_plugin.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy_plugin/__pycache__/dummy_plugin.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy_plugin/dummy_conf_plugin.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/dummy_plugin/dummy_plugin.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/empty.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/func_block_disable_msg.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/import_assign.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/import_package_subpackage_module.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/import_something.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/init_wildcard/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/init_wildcard/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/meta.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/module_global.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/no_stdout_encoding.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/numarray_import.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/numarray_inf.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/AudioTime.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/__pycache__/AudioTime.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/subpackage/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/module.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package/subpackage/module.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package_all/__init__.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package_all/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package_all/__pycache__/notmissing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/package_all/notmissing.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/precedence_test.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/py3k-disabled.rc create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/py3k_error_flag.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/py3k_errors_and_warnings.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/special_attr_scope_lookup_crash.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/syntax_error.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/test_pylintrc_comments.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/try_finally_disable_msg_crash.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/unused_variable.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/wildcard.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/regrtest_data/wrong_import_position.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/test_func.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/test_functional.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/test_import_graph.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/test_regr.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/test_self.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_base.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_classes.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_exceptions.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_format.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_imports.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_logging.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_misc.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_python3.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_similar.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_spelling.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_stdlib.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_strings.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_typecheck.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checker_variables.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_checkers_utils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_config.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_lint.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_pyreverse_diadefs.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_pyreverse_inspector.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_pyreverse_writer.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_reporters_json.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_reporting.py create mode 100644 venv/lib/python3.7/site-packages/pylint/test/unittest_utils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/testutils.py create mode 100644 venv/lib/python3.7/site-packages/pylint/utils.py create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/LICENSE create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/dependency_links.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/setuptools-40.8.0.dist-info/zip-safe create mode 100644 venv/lib/python3.7/site-packages/setuptools/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_deprecation_warning.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/_vendor/six.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/archive_util.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/build_meta.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-32.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli-64.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/cli.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/alias.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_egg.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_clib.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_ext.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/build_py.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/develop.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/dist_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/easy_install.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/egg_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_egg_info.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_lib.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/install_scripts.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/py36compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/register.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/rotate.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/saveopts.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/sdist.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/setopt.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/test.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/command/upload_docs.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/config.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/dep_util.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/depends.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/dist.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extension.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__init__.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/setuptools/glibc.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/glob.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-32.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui-64.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/gui.exe create mode 100644 venv/lib/python3.7/site-packages/setuptools/launch.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/lib2to3_ex.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/monkey.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/msvc.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/namespaces.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/package_index.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/pep425tags.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py27compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py31compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/py33compat.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/sandbox.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/script (dev).tmpl create mode 100644 venv/lib/python3.7/site-packages/setuptools/script.tmpl create mode 100644 venv/lib/python3.7/site-packages/setuptools/site-patch.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/ssl_support.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/unicode_utils.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/version.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/wheel.py create mode 100644 venv/lib/python3.7/site-packages/setuptools/windows_support.py create mode 100644 venv/lib/python3.7/site-packages/six-1.12.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/six-1.12.0.dist-info/LICENSE create mode 100644 venv/lib/python3.7/site-packages/six-1.12.0.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/six-1.12.0.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/six-1.12.0.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/six-1.12.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/six.py create mode 100644 venv/lib/python3.7/site-packages/typed_ast-1.3.5.dist-info/INSTALLER create mode 100644 venv/lib/python3.7/site-packages/typed_ast-1.3.5.dist-info/METADATA create mode 100644 venv/lib/python3.7/site-packages/typed_ast-1.3.5.dist-info/RECORD create mode 100644 venv/lib/python3.7/site-packages/typed_ast-1.3.5.dist-info/WHEEL create mode 100644 venv/lib/python3.7/site-packages/typed_ast-1.3.5.dist-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/typed_ast/__init__.py create mode 100644 venv/lib/python3.7/site-packages/typed_ast/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/typed_ast/__pycache__/ast27.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/typed_ast/__pycache__/ast3.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/typed_ast/__pycache__/conversions.cpython-37.pyc create mode 100755 venv/lib/python3.7/site-packages/typed_ast/_ast27.cpython-37m-darwin.so create mode 100755 venv/lib/python3.7/site-packages/typed_ast/_ast3.cpython-37m-darwin.so create mode 100644 venv/lib/python3.7/site-packages/typed_ast/ast27.py create mode 100644 venv/lib/python3.7/site-packages/typed_ast/ast3.py create mode 100644 venv/lib/python3.7/site-packages/typed_ast/conversions.py create mode 100644 venv/lib/python3.7/site-packages/typed_ast/tests/__pycache__/test_basics.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/typed_ast/tests/test_basics.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__init__.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/_compat.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/_internal.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/_reloader.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/datastructures.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/exceptions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/filesystem.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/formparser.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/http.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/local.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/posixemulation.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/routing.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/security.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/serving.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/test.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/testapp.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/urls.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/useragents.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/utils.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/__pycache__/wsgi.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/_compat.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/_internal.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/_reloader.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__init__.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/atom.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/cache.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/fixers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/iterio.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/lint.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/profiler.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/securecookie.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/sessions.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/__pycache__/wrappers.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/atom.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/cache.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/fixers.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/iterio.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/lint.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/profiler.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/securecookie.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/sessions.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/contrib/wrappers.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/datastructures.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__init__.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/console.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/repr.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/console.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/repr.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/FONT_LICENSE create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/console.png create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/jquery.js create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/less.png create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/more.png create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/source.png create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/style.css create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/shared/ubuntu.ttf create mode 100644 venv/lib/python3.7/site-packages/werkzeug/debug/tbtools.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/exceptions.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/filesystem.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/formparser.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/http.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/local.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/lint.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/posixemulation.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/routing.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/security.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/serving.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/test.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/testapp.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/urls.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/useragents.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/utils.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/accept.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/auth.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_request.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/common_descriptors.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/etag.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/json.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/request.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/response.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py create mode 100644 venv/lib/python3.7/site-packages/werkzeug/wsgi.py create mode 100644 venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/PKG-INFO create mode 100644 venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/SOURCES.txt create mode 100644 venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/dependency_links.txt create mode 100644 venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/installed-files.txt create mode 100644 venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/top_level.txt create mode 100644 venv/lib/python3.7/site-packages/wrapt/__init__.py create mode 100644 venv/lib/python3.7/site-packages/wrapt/__pycache__/__init__.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/wrapt/__pycache__/decorators.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/wrapt/__pycache__/importer.cpython-37.pyc create mode 100644 venv/lib/python3.7/site-packages/wrapt/__pycache__/wrappers.cpython-37.pyc create mode 100755 venv/lib/python3.7/site-packages/wrapt/_wrappers.cpython-37m-darwin.so create mode 100644 venv/lib/python3.7/site-packages/wrapt/decorators.py create mode 100644 venv/lib/python3.7/site-packages/wrapt/importer.py create mode 100644 venv/lib/python3.7/site-packages/wrapt/wrappers.py create mode 100644 venv/pyvenv.cfg diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..84c8f83 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "venv/bin/python3" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5f8e2bf --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# basic_flask_app + diff --git a/__pycache__/hello.cpython-37.pyc b/__pycache__/hello.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0305a3f0ab0fea623ff45f56fd37bd56f358d5a GIT binary patch literal 333 zcmYLEu}TCn5X~f;W%0a!uw4sN*ougXSY0C`90ws@Mm#oqS&}_PTm2BN#NV+@Yh`bB zm6Mg@9?Z+jWadrgbUfZ+gs+d^nWOVNUp5dVPAK9&k!2PfYhen&5RkvXRG@e(EPn?p zZ1Kt{Bdxq*b@@Z}tcD~noQcgE)I29P01{^uu^_TQ4Se!ExU%kH0m55(D|;#Wv^~cT+H=do}^9Jsrzhn&^@Kmp!8$5lzAQ}Vmy?@le$cD r=m|NSDy^5MMXi${k0gU%^*B^+fAO!fQ>u. +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/talksik/Development/basic_flask_app/venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if ("venv" != "") then + set env_name = "venv" + else + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` + else + set env_name = `basename "$VIRTUAL_ENV"` + endif + endif + set prompt = "[$env_name] $prompt" + unset env_name +endif + +alias pydoc python -m pydoc + +rehash diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish new file mode 100644 index 0000000..78050ad --- /dev/null +++ b/venv/bin/activate.fish @@ -0,0 +1,75 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelevant variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/talksik/Development/basic_flask_app/venv" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt + functions -c fish_prompt _old_fish_prompt + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command + set -l old_status $status + + # Prompt override? + if test -n "(venv) " + printf "%s%s" "(venv) " (set_color normal) + else + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) + else + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) + end + end + + # Restore the return status of the previous command. + echo "exit $old_status" | . + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/venv/bin/easy_install b/venv/bin/easy_install new file mode 100755 index 0000000..d95e6a8 --- /dev/null +++ b/venv/bin/easy_install @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/easy_install-3.7 b/venv/bin/easy_install-3.7 new file mode 100755 index 0000000..d95e6a8 --- /dev/null +++ b/venv/bin/easy_install-3.7 @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/epylint b/venv/bin/epylint new file mode 100755 index 0000000..de59449 --- /dev/null +++ b/venv/bin/epylint @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_epylint + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_epylint()) diff --git a/venv/bin/flask b/venv/bin/flask new file mode 100755 index 0000000..a6c4aed --- /dev/null +++ b/venv/bin/flask @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from flask.cli import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/isort b/venv/bin/isort new file mode 100755 index 0000000..aee64f2 --- /dev/null +++ b/venv/bin/isort @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from isort.main import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip b/venv/bin/pip new file mode 100755 index 0000000..71f9ce3 --- /dev/null +++ b/venv/bin/pip @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3 b/venv/bin/pip3 new file mode 100755 index 0000000..71f9ce3 --- /dev/null +++ b/venv/bin/pip3 @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3.7 b/venv/bin/pip3.7 new file mode 100755 index 0000000..71f9ce3 --- /dev/null +++ b/venv/bin/pip3.7 @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pylint b/venv/bin/pylint new file mode 100755 index 0000000..d9b79f6 --- /dev/null +++ b/venv/bin/pylint @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_pylint + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pylint()) diff --git a/venv/bin/pyreverse b/venv/bin/pyreverse new file mode 100755 index 0000000..e6ce636 --- /dev/null +++ b/venv/bin/pyreverse @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_pyreverse + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pyreverse()) diff --git a/venv/bin/python b/venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/venv/bin/python3 b/venv/bin/python3 new file mode 120000 index 0000000..79ab74b --- /dev/null +++ b/venv/bin/python3 @@ -0,0 +1 @@ +/usr/local/bin/python3 \ No newline at end of file diff --git a/venv/bin/symilar b/venv/bin/symilar new file mode 100755 index 0000000..a4ca480 --- /dev/null +++ b/venv/bin/symilar @@ -0,0 +1,10 @@ +#!/Users/talksik/Development/basic_flask_app/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_symilar + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_symilar()) diff --git a/venv/lib/python3.7/site-packages/Click-7.0.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/Click-7.0.dist-info/LICENSE.txt b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..87ce152 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/LICENSE.txt @@ -0,0 +1,39 @@ +Copyright © 2014 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. + +---- + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright © 2001-2006 Gregory P. Ward. All rights reserved. +Copyright © 2002-2006 Python Software Foundation. All rights reserved. diff --git a/venv/lib/python3.7/site-packages/Click-7.0.dist-info/METADATA b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/METADATA new file mode 100644 index 0000000..625bdad --- /dev/null +++ b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/METADATA @@ -0,0 +1,121 @@ +Metadata-Version: 2.1 +Name: Click +Version: 7.0 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets Team +Maintainer-email: contact@palletsprojects.com +License: BSD +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Code, https://github.com/pallets/click +Project-URL: Issue tracker, https://github.com/pallets/click/issues +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +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: Programming Language :: Python :: 3.7 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install click + +Click supports Python 3.4 and newer, Python 2.7, and PyPy. + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +A Simple Example +---------------- + +What does it look like? Here is an example of a simple Click program: + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", + help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo("Hello, %s!" % name) + + if __name__ == '__main__': + hello() + +And what it looks like when run: + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. 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://palletsprojects.com/donate + + +Links +----- + +* Website: https://palletsprojects.com/p/click/ +* Documentation: https://click.palletsprojects.com/ +* License: `BSD `_ +* Releases: https://pypi.org/project/click/ +* Code: https://github.com/pallets/click +* Issue tracker: https://github.com/pallets/click/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/click + * Windows: https://ci.appveyor.com/project/pallets/click + +* Test coverage: https://codecov.io/gh/pallets/click + + diff --git a/venv/lib/python3.7/site-packages/Click-7.0.dist-info/RECORD b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/RECORD new file mode 100644 index 0000000..ecf17c1 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/RECORD @@ -0,0 +1,40 @@ +Click-7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Click-7.0.dist-info/LICENSE.txt,sha256=4hIxn676T0Wcisk3_chVcECjyrivKTZsoqSNI5AlIlw,1876 +Click-7.0.dist-info/METADATA,sha256=-r8jeke3Zer4diRvT1MjFZuiJ6yTT_qFP39svLqdaLI,3516 +Click-7.0.dist-info/RECORD,, +Click-7.0.dist-info/WHEEL,sha256=gduuPyBvFJQSQ0zdyxF7k0zynDXbIbvg5ZBHoXum5uk,110 +Click-7.0.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=HjGThQ7tef9kkwCV371TBnrf0SAi6fKfU_jtEnbYTvQ,2789 +click/__pycache__/__init__.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__/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/_bashcomplete.py,sha256=iaNUmtxag0YPfxba3TDYCNietiTMQIrvhRLj-H8okFU,11014 +click/_compat.py,sha256=vYmvoj4opPxo-c-2GMQQjYT_r_QkOKybkfGoeVrt0dA,23399 +click/_termui_impl.py,sha256=xHmLtOJhKUCVD6168yucJ9fknUJPAMs0eUTPgVUO-GQ,19611 +click/_textwrap.py,sha256=gwS4m7bdQiJnzaDG8osFcRb-5vn4t4l2qSCy-5csCEc,1198 +click/_unicodefun.py,sha256=QHy2_5jYlX-36O-JVrTHNnHOqg8tquUR0HmQFev7Ics,4364 +click/_winconsole.py,sha256=PPWVak8Iikm_gAPsxMrzwsVFCvHgaW3jPaDWZ1JBl3U,8965 +click/core.py,sha256=q8FLcDZsagBGSRe5Y9Hi_FGvAeZvusNfoO5EkhkSQ8Y,75305 +click/decorators.py,sha256=idKt6duLUUfAFftrHoREi8MJSd39XW36pUVHthdglwk,11226 +click/exceptions.py,sha256=CNpAjBAE7qjaV4WChxQeak95e5yUOau8AsvT-8m6wss,7663 +click/formatting.py,sha256=eh-cypTUAhpI3HD-K4ZpR3vCiURIO62xXvKkR3tNUTM,8889 +click/globals.py,sha256=oQkou3ZQ5DgrbVM6BwIBirwiqozbjfirzsLGAlLRRdg,1514 +click/parser.py,sha256=m-nGZz4VwprM42_qtFlWFGo7yRJQxkBlRcZodoH593Y,15510 +click/termui.py,sha256=o_ZXB2jyvL2Rce7P_bFGq452iyBq9ykJyRApIPMCZO0,23207 +click/testing.py,sha256=aYGqY_iWLu2p4k7lkuJ6t3fqpf6aPGqTsyLzNY_ngKg,13062 +click/types.py,sha256=2Q929p-aBP_ZYuMFJqJR-Ipucofv3fmDc5JzBDPmzJU,23287 +click/utils.py,sha256=6-D0WkAxvv9FkgHXSHwDIv0l9Gdx9Mm6Z5vuKNLIfZI,15763 diff --git a/venv/lib/python3.7/site-packages/Click-7.0.dist-info/WHEEL b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/WHEEL new file mode 100644 index 0000000..1316c41 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Click-7.0.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/venv/lib/python3.7/site-packages/Click-7.0.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Click-7.0.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/LICENSE b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/LICENSE new file mode 100644 index 0000000..8f9252f --- /dev/null +++ b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/LICENSE @@ -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/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/METADATA b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/METADATA new file mode 100644 index 0000000..0a7e5b6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/METADATA @@ -0,0 +1,124 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 1.0.3 +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 +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: https://dev.azure.com/pallets/pallets/_build?definitionId=2 +* Test coverage: https://codecov.io/gh/pallets/flask +* Official chat: https://discord.gg/t6rrQZH + +.. _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/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/RECORD b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/RECORD new file mode 100644 index 0000000..2bc55b6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/RECORD @@ -0,0 +1,48 @@ +../../../bin/flask,sha256=VKQJSNQuuchNU40EapCgVj8QzTUduUETl2ylVodKN3E,254 +Flask-1.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Flask-1.0.3.dist-info/LICENSE,sha256=ziEXA3AIuaiUn1qe4cd1XxCESWTYrk4TjN7Qb06J3l8,1575 +Flask-1.0.3.dist-info/METADATA,sha256=2fD2dkRksjxOHmBgcoz_QfqN5ghyP-njBUMItWo2Exo,4119 +Flask-1.0.3.dist-info/RECORD,, +Flask-1.0.3.dist-info/WHEEL,sha256=HX-v9-noUkyUoxyZ1PMSuS7auUxDAR4VBdoYLqD0xws,110 +Flask-1.0.3.dist-info/entry_points.txt,sha256=gBLA1aKg0OYR8AhbAfg8lnburHtKcgJLDU52BBctN0k,42 +Flask-1.0.3.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 +flask/__init__.py,sha256=SEPu7STunDgeHTDwji6JeSoKNcSBtULkKzY4spj3z6E,1673 +flask/__main__.py,sha256=pgIXrHhxM5MAMvgzAqWpw_t6AXZ1zG38us4JRgJKtxk,291 +flask/__pycache__/__init__.cpython-37.pyc,, +flask/__pycache__/__main__.cpython-37.pyc,, +flask/__pycache__/_compat.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/_compat.py,sha256=x1LK5kpv_6roOeybIFBmme15cGnXWpLtQAGsNfNwRvQ,2980 +flask/app.py,sha256=NC2JgfXOHpqRFxSdfWsSqWUhCfMSB84fHspOaTvUL88,94803 +flask/blueprints.py,sha256=SnIW5hCOhKMa8_N42sw-3LUTg_hPnvxqBJOYNBHkT5c,18296 +flask/cli.py,sha256=XtgWfUHyOABgdGkc34YyP-1b765xxeHLLgl1zPSqUvI,29913 +flask/config.py,sha256=Etv43UCp6I1rg5fDb7DPjp5sNUlQOqP6ZqyhTrTrqgc,10145 +flask/ctx.py,sha256=tLrqKokGoD6ZDqjak9r2ffeEprN06h-CoaelVihKBJ4,16224 +flask/debughelpers.py,sha256=1ceC-UyqZTd4KsJkf0OObHPsVt5R3T6vnmYhiWBjV-w,6479 +flask/globals.py,sha256=pGg72QW_-4xUfsI33I5L_y76c21AeqfSqXDcbd8wvXU,1649 +flask/helpers.py,sha256=M_C0zBY2WtnHG0Y7n0-1lNz0imzj6HmffGEGjMEcXLs,40424 +flask/json/__init__.py,sha256=0x3zrRd8mjYHVxbb7ZXr7OZ2Q1aSvVoturl4Tsp_F0Y,11859 +flask/json/__pycache__/__init__.cpython-37.pyc,, +flask/json/__pycache__/tag.cpython-37.pyc,, +flask/json/tag.py,sha256=9ehzrmt5k7hxf7ZEK0NOs3swvQyU9fWNe-pnYe69N60,8223 +flask/logging.py,sha256=qV9h0vt7NIRkKM9OHDWndzO61E5CeBMlqPJyTt-W2Wc,2231 +flask/sessions.py,sha256=Zgfk3cevqWM3yFlYT-nvhBFtgsCFnGrhneI0u5rT5SM,14471 +flask/signals.py,sha256=BGQbVyCYXnzKK2DVCzppKFyWN1qmrtW1QMAYUs-1Nr8,2211 +flask/templating.py,sha256=FDfWMbpgpC3qObW8GGXRAVrkHFF8K4CHOJymB1wvULI,4914 +flask/testing.py,sha256=I6h58A42ZTKizPjwmVtl-37d8R4A8Mkz5rflY1RsCYg,9329 +flask/views.py,sha256=Wy-_WkUVtCfE2zCXYeJehNgHuEtviE4v3HYfJ--MpbY,5733 +flask/wrappers.py,sha256=1Z9hF5-hXQajn_58XITQFRY8efv3Vy3uZ0avBfZu6XI,7511 diff --git a/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/WHEEL b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/WHEEL new file mode 100644 index 0000000..c8240f0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/entry_points.txt b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/entry_points.txt new file mode 100644 index 0000000..1eb0252 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask = flask.cli:main + diff --git a/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/top_level.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Flask-1.0.3.dist-info/top_level.txt @@ -0,0 +1 @@ +flask diff --git a/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/LICENSE b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/LICENSE new file mode 100644 index 0000000..31bf900 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/LICENSE @@ -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/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/METADATA b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/METADATA new file mode 100644 index 0000000..fb4a867 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/METADATA @@ -0,0 +1,67 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 2.10.1 +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 +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/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/RECORD b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/RECORD new file mode 100644 index 0000000..1507ef1 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/RECORD @@ -0,0 +1,61 @@ +Jinja2-2.10.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Jinja2-2.10.1.dist-info/LICENSE,sha256=JvzUNv3Io51EiWrAPm8d_SXjhJnEjyDYvB3Tvwqqils,1554 +Jinja2-2.10.1.dist-info/METADATA,sha256=rx0eN8lX8iq8-YVppmCzV1Qx4y3Pj9IWi08mXUCrewI,2227 +Jinja2-2.10.1.dist-info/RECORD,, +Jinja2-2.10.1.dist-info/WHEEL,sha256=HX-v9-noUkyUoxyZ1PMSuS7auUxDAR4VBdoYLqD0xws,110 +Jinja2-2.10.1.dist-info/entry_points.txt,sha256=NdzVcOrqyNyKDxD09aERj__3bFx2paZhizFDsKmVhiA,72 +Jinja2-2.10.1.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=V1D-JHQKklZseXOMA-uAW7-BeKe_TfPpOFi9-dV04ZA,2616 +jinja2/__pycache__/__init__.cpython-37.pyc,, +jinja2/__pycache__/_compat.cpython-37.pyc,, +jinja2/__pycache__/_identifier.cpython-37.pyc,, +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/_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=UmX8hVjdaERCbA3RXBwrV1f-beA23KmijG5kzPJyU4A,17106 +jinja2/tests.py,sha256=iJQLwbapZr-EKquTG_fVOVdwHUUKf3SX9eNkjQDF8oU,4237 +jinja2/utils.py,sha256=q24VupGZotQ-uOyrJxCaXtDWhZC1RgsQG7kcdmjck2Q,20629 +jinja2/visitor.py,sha256=JD1H1cANA29JcntFfN5fPyqQxB4bI4wC00BzZa-XHks,3316 diff --git a/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/WHEEL b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/WHEEL new file mode 100644 index 0000000..c8240f0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/entry_points.txt b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/entry_points.txt new file mode 100644 index 0000000..32e6b75 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.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/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/venv/lib/python3.7/site-packages/Jinja2-2.10.1.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. 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. + +3. 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 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, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/METADATA b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/METADATA new file mode 100644 index 0000000..b208d93 --- /dev/null +++ b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 1.1.1 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: The Pallets Team +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Code, https://github.com/pallets/markupsafe +Project-URL: Issue tracker, https://github.com/pallets/markupsafe/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: Programming Language :: Python :: 3.7 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* + +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + >>> # escape replaces special characters and wraps in Markup + >>> escape('') + Markup(u'<script>alert(document.cookie);</script>') + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup('Hello') + Markup('hello') + >>> escape(Markup('Hello')) + Markup('hello') + >>> # Markup is a text subclass (str on Python 3, unicode on Python 2) + >>> # methods and operators escape their arguments + >>> template = Markup("Hello %s") + >>> template % '"World"' + Markup('Hello "World"') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +libraries that use it. 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://palletsprojects.com/donate + + +Links +----- + +* Website: https://palletsprojects.com/p/markupsafe/ +* Documentation: https://markupsafe.palletsprojects.com/ +* License: `BSD-3-Clause `_ +* Releases: https://pypi.org/project/MarkupSafe/ +* Code: https://github.com/pallets/markupsafe +* Issue tracker: https://github.com/pallets/markupsafe/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/markupsafe + * Windows: https://ci.appveyor.com/project/pallets/markupsafe + +* Test coverage: https://codecov.io/gh/pallets/markupsafe + + diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/RECORD b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/RECORD new file mode 100644 index 0000000..db8f8df --- /dev/null +++ b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/RECORD @@ -0,0 +1,16 @@ +MarkupSafe-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-1.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-1.1.1.dist-info/METADATA,sha256=nJHwJ4_4ka-V39QH883jPrslj6inNdyyNASBXbYgHXQ,3570 +MarkupSafe-1.1.1.dist-info/RECORD,, +MarkupSafe-1.1.1.dist-info/WHEEL,sha256=LukkRg4Nyu7ElUUdIG66wCYZvtuCKTu3PkyFPJmB8vI,109 +MarkupSafe-1.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=oTblO5f9KFM-pvnq9bB0HgElnqkJyqHnFN1Nx2NIvnY,10126 +markupsafe/__pycache__/__init__.cpython-37.pyc,, +markupsafe/__pycache__/_compat.cpython-37.pyc,, +markupsafe/__pycache__/_constants.cpython-37.pyc,, +markupsafe/__pycache__/_native.cpython-37.pyc,, +markupsafe/_compat.py,sha256=uEW1ybxEjfxIiuTbRRaJpHsPFf4yQUMMKaPgYEC5XbU,558 +markupsafe/_constants.py,sha256=zo2ajfScG-l1Sb_52EP3MlDCqO7Y1BVHUXXKRsVDRNk,4690 +markupsafe/_native.py,sha256=d-8S_zzYt2y512xYcuSxq0NeG2DUUvG80wVdTn-4KI8,1873 +markupsafe/_speedups.c,sha256=k0fzEIK3CP6MmMqeY0ob43TP90mVN0DTyn7BAl3RqSg,9884 +markupsafe/_speedups.cpython-37m-darwin.so,sha256=jdynRZDihetj62NEG_WZnKxdH6WbyPqDnGhK51xWgW0,35080 diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL new file mode 100644 index 0000000..22c0e9a --- /dev/null +++ b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.1) +Root-Is-Purelib: false +Tag: cp37-cp37m-macosx_10_6_intel + diff --git a/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/venv/lib/python3.7/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/LICENSE.rst b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. 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. + +3. 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 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, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/METADATA b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/METADATA new file mode 100644 index 0000000..ae87c92 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/METADATA @@ -0,0 +1,133 @@ +Metadata-Version: 2.1 +Name: Werkzeug +Version: 0.15.4 +Summary: The comprehensive WSGI web application library. +Home-page: https://palletsprojects.com/p/werkzeug/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: The Pallets Team +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Documentation, https://werkzeug.palletsprojects.com/ +Project-URL: Code, https://github.com/pallets/werkzeug +Project-URL: Issue tracker, https://github.com/pallets/werkzeug/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: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Provides-Extra: dev +Requires-Dist: pytest ; 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: sphinx-issues ; extra == 'dev' +Provides-Extra: termcolor +Requires-Dist: termcolor ; extra == 'termcolor' +Provides-Extra: watchdog +Requires-Dist: watchdog ; extra == 'watchdog' + +Werkzeug +======== + +*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff") + +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/ +- Documentation: https://werkzeug.palletsprojects.com/ +- 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/pallets/werkzeug + +- Test coverage: https://codecov.io/gh/pallets/werkzeug +- Official chat: https://discord.gg/t6rrQZH + +.. _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/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/RECORD b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/RECORD new file mode 100644 index 0000000..66917ad --- /dev/null +++ b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/RECORD @@ -0,0 +1,119 @@ +Werkzeug-0.15.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Werkzeug-0.15.4.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Werkzeug-0.15.4.dist-info/METADATA,sha256=BFCzIm51w-fKsnG13iHz4No7Upu9-y_vJUq_rkY_bqY,4864 +Werkzeug-0.15.4.dist-info/RECORD,, +Werkzeug-0.15.4.dist-info/WHEEL,sha256=HX-v9-noUkyUoxyZ1PMSuS7auUxDAR4VBdoYLqD0xws,110 +Werkzeug-0.15.4.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 +werkzeug/__init__.py,sha256=LBPc9xBJsifxGUsUY5EkreS0o_D8ixJD3YYSh9ARtxE,6805 +werkzeug/__pycache__/__init__.cpython-37.pyc,, +werkzeug/__pycache__/_compat.cpython-37.pyc,, +werkzeug/__pycache__/_internal.cpython-37.pyc,, +werkzeug/__pycache__/_reloader.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__/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__/wsgi.cpython-37.pyc,, +werkzeug/_compat.py,sha256=oBEVVrJT4sqYdIZbUWmgV9T9w257RhTSDBlTjh0Zbb0,6431 +werkzeug/_internal.py,sha256=Wx7cpTRWqeBd0LAqobo0lCO4pNUW4oav6XKf7Taumgk,14590 +werkzeug/_reloader.py,sha256=8B8T1npsQT-96nGeVJjV1KXWK_ong6ZlTXOWgxfRLpg,11241 +werkzeug/contrib/__init__.py,sha256=EvNyiiCF49j5P0fZYJ3ZGe82ofXdSBvUNqWFwwBMibQ,553 +werkzeug/contrib/__pycache__/__init__.cpython-37.pyc,, +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__/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__/wrappers.cpython-37.pyc,, +werkzeug/contrib/atom.py,sha256=KpPJcTfzNW1J0VNQckCbVtVGBe3V8s451tOUya4qByI,15415 +werkzeug/contrib/cache.py,sha256=AEh5UIw-Ui7sHZnlpvrD7ueOKUhCaAD55FXiPtXbbRs,32115 +werkzeug/contrib/fixers.py,sha256=peEtAiIWYT5bh00EWEPOGKzGZXivOzVhhzKPvvzk1RM,9193 +werkzeug/contrib/iterio.py,sha256=KKHa_8aCF_uhoeQVyPGUwrivuB6y6nNdXYo2D2vzOA8,10928 +werkzeug/contrib/lint.py,sha256=NdIxP0E2kVt1xDIxoaIz3Rcl8ZdgmHaFbGTOaybGpN4,296 +werkzeug/contrib/profiler.py,sha256=k_oMLU-AtsVvQ9TxNdermY6FuzSTYr-WE-ZmWb_DMyU,1229 +werkzeug/contrib/securecookie.py,sha256=xbtElskGmtbiApgOJ5WhGgqGDs_68_PcWzqDIAY_QZY,13076 +werkzeug/contrib/sessions.py,sha256=oVXh_7-6_CWOMxDKqcaK05H8RpYoWqAd3al-KzMFPYs,13042 +werkzeug/contrib/wrappers.py,sha256=ZmNk0wpzD66yomPnQxapndZQs4c0kNJaRzqI-BVxeQk,13199 +werkzeug/datastructures.py,sha256=8HoA4Gu9i7ZWi5OBjx244OLWvDEE4JTQQUUTRoAYKog,91761 +werkzeug/debug/__init__.py,sha256=Bo3HvgTNY4NQ_2jROTSk3r1ScZcT_g_4EnuHTjKyrKM,18275 +werkzeug/debug/__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/console.py,sha256=HoBL21bbcmtiCLqiLDJLZi1LYnWMZxjoXYH5WaZB1XY,5469 +werkzeug/debug/repr.py,sha256=lIwuhbyrMwVe3P_cFqNyqzHL7P93TLKod7lw9clydEw,9621 +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=rOhqZMRfpZnnu6_XCGn6wMWPhtfwRAcyZKksdIxPJas,6400 +werkzeug/debug/shared/jquery.js,sha256=FgpCb_KJQlLNfOu91ta32o_NMZxltwRo8QtmkMRdAu8,86927 +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=_Y98F6dR2CBUZNKylsOdgSHjwVaVy717WqE3-xJVcmE,6581 +werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220 +werkzeug/debug/tbtools.py,sha256=SkAAA4KKfwsXJinUbf-AEP4GqONTsR4uU7WPUloXcSE,20318 +werkzeug/exceptions.py,sha256=SNbLn_vitnNiG_nwirLT0k6Nf6CZ_1R0Fyk_ub2XCbE,23230 +werkzeug/filesystem.py,sha256=HzKl-j0Hd8Jl66j778UbPTAYNnY6vUZgYLlBZ0e7uw0,2101 +werkzeug/formparser.py,sha256=tN6SO4mn6RUsxRZq4qVBWXbNWNuasn2KaBznTieMaVk,21790 +werkzeug/http.py,sha256=t0ET2tySAf9ZWdEelVWJoLaZzFViYpjoUmiYHPz10-E,43304 +werkzeug/local.py,sha256=USVEcgIg-oCiUJFPIecFIW9jkIejfw4Fjf1u5yN-Np4,14456 +werkzeug/middleware/__init__.py,sha256=f1SFZo67IlW4k1uqKzNHxYQlsakUS-D6KK_j0e3jjwQ,549 +werkzeug/middleware/__pycache__/__init__.cpython-37.pyc,, +werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc,, +werkzeug/middleware/__pycache__/http_proxy.cpython-37.pyc,, +werkzeug/middleware/__pycache__/lint.cpython-37.pyc,, +werkzeug/middleware/__pycache__/profiler.cpython-37.pyc,, +werkzeug/middleware/__pycache__/proxy_fix.cpython-37.pyc,, +werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc,, +werkzeug/middleware/dispatcher.py,sha256=_-KoMzHtcISHS7ouWKAOraqlCLprdh83YOAn_8DjLp8,2240 +werkzeug/middleware/http_proxy.py,sha256=lRjTdMmghHiZuZrS7_UJ3gZc-vlFizhBbFZ-XZPLwIA,7117 +werkzeug/middleware/lint.py,sha256=ItTwuWJnflF8xMT1uqU_Ty1ryhux-CjeUfskqaUpxsw,12967 +werkzeug/middleware/profiler.py,sha256=8B_s23d6BGrU_q54gJsm6kcCbOJbTSqrXCsioHON0Xs,4471 +werkzeug/middleware/proxy_fix.py,sha256=Y86VcU2oAQ--x0mi4iFVJyEFMzp3Ao8q0zvr_SsrpNw,8506 +werkzeug/middleware/shared_data.py,sha256=6aUzMABeOLul0Krf5S_hs-T7oUc7ZIQ3B8tAO4p8C7E,8541 +werkzeug/posixemulation.py,sha256=gSSiv1SCmOyzOM_nq1ZaZCtxP__C5MeDJl_4yXJmi4Q,3541 +werkzeug/routing.py,sha256=51zsLuN3qZcpRxpy3K3XoEuL8kyFfuqo28MquJsjZjw,72902 +werkzeug/security.py,sha256=mfxfcM-D6U8LhsyDK5W_rnL1oVTZWgyt-E8E4FlSdrI,8026 +werkzeug/serving.py,sha256=tUFUMg7Bj9iw3nA8ZgC_czMDJJKN7vFskajEmgEFhzE,36597 +werkzeug/test.py,sha256=Cnb5xa3vLDL0hzFCH1fkG_YRpndViGQgCh4D744iSQk,40645 +werkzeug/testapp.py,sha256=hcKBzorVlSHC-uGvGXXjCm3FzCwGWq4yjbTG3Pr7MV8,9301 +werkzeug/urls.py,sha256=8yHdYI99N__-isoTwvGqvuj9QhOh66dd1Xh1DIp0q0g,39261 +werkzeug/useragents.py,sha256=FIonyUF790Ro8OG8cJqG1zixhg5YzXdHmkZbrnK0QRo,5965 +werkzeug/utils.py,sha256=O20Y0qWk5O1IWamC_A5gkmzR5cgBd3yDIHviwBTfNB0,27387 +werkzeug/wrappers/__init__.py,sha256=S4VioKAmF_av9Ec9zQvG71X1EOkYfPx1TYck9jyDiyY,1384 +werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/accept.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/auth.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/base_request.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/common_descriptors.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/etag.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/json.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/request.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/response.cpython-37.pyc,, +werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc,, +werkzeug/wrappers/accept.py,sha256=TIvjUc0g73fhTWX54wg_D9NNzKvpnG1X8u1w26tK1o8,1760 +werkzeug/wrappers/auth.py,sha256=Pmn6iaGHBrUyHbJpW0lZhO_q9RVoAa5QalaTqcavdAI,1158 +werkzeug/wrappers/base_request.py,sha256=k5mu1UU99X_xrPqmXj44pzJbkPRpgvwMuP2j9vl8QFU,26873 +werkzeug/wrappers/base_response.py,sha256=ZA1XlxtsbvG4SpbdOEMT5--z7aZM0w6C5y33W8wOXa4,27906 +werkzeug/wrappers/common_descriptors.py,sha256=OJ8jOwMun4L-BxCuFPkK1vaefx_-Y5IndVXvvn_ems4,12089 +werkzeug/wrappers/etag.py,sha256=TwMO1fvluXbBqnFTj2DvrCNa3mYhbHYe1UZAVzfXvuU,12533 +werkzeug/wrappers/json.py,sha256=HvK_A4NpO0sLqgb10sTJcoZydYOwyNiPCJPV7SVgcgE,4343 +werkzeug/wrappers/request.py,sha256=qPo2zmmBv4HxboywtWZb2pJL8OPXo07BUXBKw2j9Fi8,1338 +werkzeug/wrappers/response.py,sha256=vDZFEGzDOG0jjmS0uVVjeT3hqRt1hFaf15npnx7RD28,2329 +werkzeug/wrappers/user_agent.py,sha256=4bTgQKTLQmGUyxOREYOzbeiFP2VwIOE7E14AhUB5NqM,444 +werkzeug/wsgi.py,sha256=h-zyAeInwE6X6ciSnHI14ImA85adV-F861PmR7UGtRk,36681 diff --git a/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/WHEEL b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/WHEEL new file mode 100644 index 0000000..c8240f0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/top_level.txt new file mode 100644 index 0000000..6fe8da8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/Werkzeug-0.15.4.dist-info/top_level.txt @@ -0,0 +1 @@ +werkzeug diff --git a/venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc b/venv/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec1822cf88972c6bfa0590fe2c6be5a15628c962 GIT binary patch literal 333 zcmYk0u}Z{15QcY?s6o6Z5H#4OxNPLmJ3-_SENm>)DhR`RyWYj@ChP9zASrBo7s1N+ zNo!?qW#vXs^oN;$28QpS)4^a9IlVrA+&nse>z7}7ZkW0NGFOHBq@5uCT*Ywj)SK1^LS-|8o=7bm6hASS|Po OcHyS~An-!Gg}(sJiC~cc literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/__pycache__/mccabe.cpython-37.pyc b/venv/lib/python3.7/site-packages/__pycache__/mccabe.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be381dae0c81d683acf254b525daa4ffbbcda531 GIT binary patch literal 11156 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/__pycache__/six.cpython-37.pyc b/venv/lib/python3.7/site-packages/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6e37b94d8e510cb9bc79bc695aa38d4d169efa9 GIT binary patch literal 26410 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 dA!&c#+P;Clf$TcskGkUcL|g*YL;W + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/COPYING.LESSER b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/COPYING.LESSER new file mode 100644 index 0000000..2d2d780 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/COPYING.LESSER @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/INSTALLER b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/METADATA b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/METADATA new file mode 100644 index 0000000..8df5eec --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/METADATA @@ -0,0 +1,102 @@ +Metadata-Version: 2.1 +Name: astroid +Version: 2.2.5 +Summary: An abstract syntax tree for Python with inference support. +Home-page: https://github.com/PyCQA/astroid +Author: Python Code Quality Authority +Author-email: code-quality@python.org +License: LGPL +Platform: UNKNOWN +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Quality Assurance +Classifier: Programming Language :: Python +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 +Requires-Python: >=3.4.* +Requires-Dist: lazy-object-proxy +Requires-Dist: six +Requires-Dist: wrapt +Requires-Dist: typed-ast (>=1.3.0) ; implementation_name == "cpython" +Requires-Dist: typing ; python_version < "3.5" + +Astroid +======= + +.. image:: https://travis-ci.org/PyCQA/astroid.svg?branch=master + :target: https://travis-ci.org/PyCQA/astroid + +.. image:: https://ci.appveyor.com/api/projects/status/co3u42kunguhbh6l/branch/master?svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/PCManticore/astroid + +.. image:: https://coveralls.io/repos/github/PyCQA/astroid/badge.svg?branch=master + :target: https://coveralls.io/github/PyCQA/astroid?branch=master + +.. image:: https://readthedocs.org/projects/astroid/badge/?version=latest + :target: http://astroid.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + + + +What's this? +------------ + +The aim of this module is to provide a common base representation of +python source code. It is currently the library powering pylint's capabilities. + +It provides a compatible representation which comes from the `_ast` +module. It rebuilds the tree generated by the builtin _ast module by +recursively walking down the AST and building an extended ast. The new +node classes have additional methods and attributes for different +usages. They include some support for static inference and local name +scopes. Furthermore, astroid can also build partial trees by inspecting living +objects. + + +Installation +------------ + +Extract the tarball, jump into the created directory and run:: + + pip install . + + +If you want to do an editable installation, you can run:: + + pip install -e . + + +If you have any questions, please mail the code-quality@python.org +mailing list for support. See +http://mail.python.org/mailman/listinfo/code-quality for subscription +information and archives. + +Documentation +------------- +http://astroid.readthedocs.io/en/latest/ + + +Python Versions +--------------- + +astroid 2.0 is currently available for Python 3 only. If you want Python 2 +support, older versions of astroid will still supported until 2020. + +Test +---- + +Tests are in the 'test' subdirectory. To launch the whole tests suite, you can use +either `tox` or `pytest`:: + + tox + pytest astroid + + diff --git a/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/RECORD b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/RECORD new file mode 100644 index 0000000..4976de5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/RECORD @@ -0,0 +1,125 @@ +astroid-2.2.5.dist-info/COPYING,sha256=qxX9UmvY3Rip5368E5ZWv00z6X_HI4zRG_YOK5uGZsY,17987 +astroid-2.2.5.dist-info/COPYING.LESSER,sha256=qb3eVhbs3R6YC0TzYGAO6Hg7H5m4zIOivrFjoKOQ6GE,26527 +astroid-2.2.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +astroid-2.2.5.dist-info/METADATA,sha256=_0Eu_wSg7s0nPtqYiIZZYG7Owax3vxAcNUDiBrCfYho,3213 +astroid-2.2.5.dist-info/RECORD,, +astroid-2.2.5.dist-info/WHEEL,sha256=U88EhGIw8Sj2_phqajeu_EAi3RAo8-C6zV3REsWbWbs,92 +astroid-2.2.5.dist-info/top_level.txt,sha256=HsdW4O2x7ZXRj6k-agi3RaQybGLobI3VSE-jt4vQUXM,8 +astroid/__init__.py,sha256=tJJMsKzMv8hUgw3y0VQAAMx9BO-nrNUcNy_wI0XBFXo,5538 +astroid/__pkginfo__.py,sha256=-QFbcr8CyWJD6Vd4hR2kiaSly4ZjvwHKv91DJ81fvnE,2125 +astroid/__pycache__/__init__.cpython-37.pyc,, +astroid/__pycache__/__pkginfo__.cpython-37.pyc,, +astroid/__pycache__/_ast.cpython-37.pyc,, +astroid/__pycache__/arguments.cpython-37.pyc,, +astroid/__pycache__/as_string.cpython-37.pyc,, +astroid/__pycache__/bases.cpython-37.pyc,, +astroid/__pycache__/builder.cpython-37.pyc,, +astroid/__pycache__/context.cpython-37.pyc,, +astroid/__pycache__/decorators.cpython-37.pyc,, +astroid/__pycache__/exceptions.cpython-37.pyc,, +astroid/__pycache__/helpers.cpython-37.pyc,, +astroid/__pycache__/inference.cpython-37.pyc,, +astroid/__pycache__/manager.cpython-37.pyc,, +astroid/__pycache__/mixins.cpython-37.pyc,, +astroid/__pycache__/modutils.cpython-37.pyc,, +astroid/__pycache__/node_classes.cpython-37.pyc,, +astroid/__pycache__/nodes.cpython-37.pyc,, +astroid/__pycache__/objects.cpython-37.pyc,, +astroid/__pycache__/protocols.cpython-37.pyc,, +astroid/__pycache__/raw_building.cpython-37.pyc,, +astroid/__pycache__/rebuilder.cpython-37.pyc,, +astroid/__pycache__/scoped_nodes.cpython-37.pyc,, +astroid/__pycache__/test_utils.cpython-37.pyc,, +astroid/__pycache__/transforms.cpython-37.pyc,, +astroid/__pycache__/util.cpython-37.pyc,, +astroid/_ast.py,sha256=osewGNkfO4LbgzI-mJOWg8Seo9YgtxCo6p5VrqIa8vs,1186 +astroid/arguments.py,sha256=cui-UmbEeywSk0eitSrOhi9F0Ci2clS4qYXTi8uXRs4,11783 +astroid/as_string.py,sha256=WOnmoyFPbRV3M_Oe5ykkncPlaXY_eu9nQzzREHoRFRg,22231 +astroid/bases.py,sha256=Da-eo4o0VAIidQn2aHINZXa20_SEbc59HlrgiaeS1qU,19030 +astroid/brain/__pycache__/brain_argparse.cpython-37.pyc,, +astroid/brain/__pycache__/brain_attrs.cpython-37.pyc,, +astroid/brain/__pycache__/brain_builtin_inference.cpython-37.pyc,, +astroid/brain/__pycache__/brain_collections.cpython-37.pyc,, +astroid/brain/__pycache__/brain_curses.cpython-37.pyc,, +astroid/brain/__pycache__/brain_dateutil.cpython-37.pyc,, +astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc,, +astroid/brain/__pycache__/brain_functools.cpython-37.pyc,, +astroid/brain/__pycache__/brain_gi.cpython-37.pyc,, +astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc,, +astroid/brain/__pycache__/brain_http.cpython-37.pyc,, +astroid/brain/__pycache__/brain_io.cpython-37.pyc,, +astroid/brain/__pycache__/brain_mechanize.cpython-37.pyc,, +astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc,, +astroid/brain/__pycache__/brain_namedtuple_enum.cpython-37.pyc,, +astroid/brain/__pycache__/brain_nose.cpython-37.pyc,, +astroid/brain/__pycache__/brain_numpy.cpython-37.pyc,, +astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc,, +astroid/brain/__pycache__/brain_pytest.cpython-37.pyc,, +astroid/brain/__pycache__/brain_qt.cpython-37.pyc,, +astroid/brain/__pycache__/brain_random.cpython-37.pyc,, +astroid/brain/__pycache__/brain_re.cpython-37.pyc,, +astroid/brain/__pycache__/brain_six.cpython-37.pyc,, +astroid/brain/__pycache__/brain_ssl.cpython-37.pyc,, +astroid/brain/__pycache__/brain_subprocess.cpython-37.pyc,, +astroid/brain/__pycache__/brain_threading.cpython-37.pyc,, +astroid/brain/__pycache__/brain_typing.cpython-37.pyc,, +astroid/brain/__pycache__/brain_uuid.cpython-37.pyc,, +astroid/brain/brain_argparse.py,sha256=VEeMCr3OIjHmCy35uc-kX6nJ5_NUOAimpGJMr6CChoA,1024 +astroid/brain/brain_attrs.py,sha256=c5l1ijYZB-6HWvPX_5Kb9AlNpMJXDZZ1UK58qtqaUVo,1992 +astroid/brain/brain_builtin_inference.py,sha256=ymD7so94WDz16Wtgn7JFuNpdjPMwty8wtD5vMAGPOy4,26926 +astroid/brain/brain_collections.py,sha256=XBlyS-6J3rlEqv_44EyB6z6YbJq4KJCoN_pKTxdBhOA,2828 +astroid/brain/brain_curses.py,sha256=tDnlCP1bEvleqCMz856yua9mM5um1p_JendFhT4rBFk,3303 +astroid/brain/brain_dateutil.py,sha256=q2dyV2907Bw4n7m2W4EEdok3Ndv8NzeIQxAZwXBiS14,795 +astroid/brain/brain_fstrings.py,sha256=VKVMijgLE2pg2dtXM6GGFgONOxOg8qA9D5V6dYzWTbQ,2121 +astroid/brain/brain_functools.py,sha256=hjSZleIDmFBbnFwrOFlZJJIDNF3FA5fR3zEYywS0rZY,5342 +astroid/brain/brain_gi.py,sha256=-EpcKf9z3wT_7v0k0WXIZtgk3-213lkfUX9bxeKOM3Y,6810 +astroid/brain/brain_hashlib.py,sha256=cp30hX5HhWqbWG3zqcNu8N3aHGeQK4DPi4ac8owBonU,2163 +astroid/brain/brain_http.py,sha256=th-m5kE890y1M2cyr2AtaiYz4HT46Pk5Tordh_Piug4,3476 +astroid/brain/brain_io.py,sha256=DJcTFMTexrsHaGg2-kHoXwonddu13ImT7NEjiF1xPiU,1470 +astroid/brain/brain_mechanize.py,sha256=xTBc-u2DMmMPeci7DVFs4L2T98DwwLF_Ob5YZviLPp8,889 +astroid/brain/brain_multiprocessing.py,sha256=zXqLXg6dVYTkik1qSjo1cPJMZAGrkobVslp7ArwEXYQ,3108 +astroid/brain/brain_namedtuple_enum.py,sha256=ginA4riLe-gQSIrpWz0Z8mvWYdXEi9sI8J1hy4MvAxU,15473 +astroid/brain/brain_nose.py,sha256=kECw2jHmX0IUPX4Gx3XVGrflKGnlgPB79QHt6WU2cwQ,2211 +astroid/brain/brain_numpy.py,sha256=VSrOi7Jbdr_eAGOgFmh-8W2rUrUEsoz8OP6Czaep65A,20546 +astroid/brain/brain_pkg_resources.py,sha256=S_5UED1Zg8ObEJumRdpYGnjxZzemh_G_NFj3p5NGPfc,2262 +astroid/brain/brain_pytest.py,sha256=RXaNUVqy2R0et0Upn4GJkVgq5SG8Pl7zLlhqQg8Xx3Q,2384 +astroid/brain/brain_qt.py,sha256=U3VOrHer0cLvpxJC55MLEYrKn1Z3RQRXsc6fQ7u5hvI,2437 +astroid/brain/brain_random.py,sha256=2RZY-QEXMNWp7E6h0l0-ke-DtjKTOFlTdjiQZi3XdQc,2432 +astroid/brain/brain_re.py,sha256=le7VJHUAf80HyE_aQCh7_8FyDVK6JwNWA--c9RaMVQ8,1128 +astroid/brain/brain_six.py,sha256=6QHcKXoYf8yMMXWkx3g3lK0kqB5OFeYcXwjUTdgWTMw,6146 +astroid/brain/brain_ssl.py,sha256=2quiZVA_BW8PWmkAsOuYanq9Hvb93LT7c9YVslw3r14,3634 +astroid/brain/brain_subprocess.py,sha256=TLl7qrvP-3XUeE7g9sebmjPN4_m5KKnDbsTzFBzBUu4,4228 +astroid/brain/brain_threading.py,sha256=Qv06IeuEwDlk8cibAlUxlPx2FWMyRpoSCMQTkCrL04Q,767 +astroid/brain/brain_typing.py,sha256=iFw33beNCitCJjJNvccIY6SsFJcdKVDdl-56DxDioh0,2780 +astroid/brain/brain_uuid.py,sha256=flWrk1Ve7oqYrO8GTZ3To8RBYteRfYwvash-s9KiU9o,564 +astroid/builder.py,sha256=0wrC4-ausU_nEEkgI8LJTsrNFN_XCbOkqoG2DsKCsks,16023 +astroid/context.py,sha256=VsyUDVB1J9fk1o8MQoE4ygfC7gdNjVYVUD4Bhgs9JM0,5164 +astroid/decorators.py,sha256=m0v63YRiQKc66-g8ckkYeJ0d5cji8AhkUxFPbTfLVDc,4229 +astroid/exceptions.py,sha256=_IJRdLfyNSPVjxYgEd11Uu9XpdqE7uBCVOEIxt3ua70,7047 +astroid/helpers.py,sha256=3r5ip51zPeOTCKgG4fYWjWxAzjaJEFot3TYnZDnBJWs,9079 +astroid/inference.py,sha256=zwJDRemh5NuvW0FaPGKkJQyNL0zW6LEefWnfidjlfeQ,31454 +astroid/interpreter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +astroid/interpreter/__pycache__/__init__.cpython-37.pyc,, +astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc,, +astroid/interpreter/__pycache__/objectmodel.cpython-37.pyc,, +astroid/interpreter/_import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc,, +astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc,, +astroid/interpreter/_import/__pycache__/util.cpython-37.pyc,, +astroid/interpreter/_import/spec.py,sha256=oDdgvZZCuagrsjaiNOq3MbmEhabWyWUfX7xjJaTXEpE,10942 +astroid/interpreter/_import/util.py,sha256=inubUz6F3_kaMFaeleKUW6E6wCMIPrhU882zvwEZ02I,255 +astroid/interpreter/dunder_lookup.py,sha256=dP-AZU_aGPNt03b1ttrMglxzeU3NtgnG0MfpSLPH6sg,2155 +astroid/interpreter/objectmodel.py,sha256=0jLiTbN8I8GZKF4Rf61YfD-xZCJOOigwKn2EC3BwYlg,23114 +astroid/manager.py,sha256=y1LOtZYGhoeOSmyu5k46kPQfSiQmyJDwo3Bs54u3YTI,12573 +astroid/mixins.py,sha256=F2rv2Ow7AU3YT_2jitVJik95ZWRVK6hpf8BrkkspzUY,5571 +astroid/modutils.py,sha256=8zpeNSGwKLA_hlk36o0Q7m3bzCumVP5c-1DJ1dkllYU,23568 +astroid/node_classes.py,sha256=DeAi6YMtUmv-9dbP1iJOro5z1Irw4lsGHn5uSMCL-T0,137726 +astroid/nodes.py,sha256=FIa3fF-rJ5BlhlGIcJGrEoyO_r5rMmWeajdAxtGEYFk,2927 +astroid/objects.py,sha256=q6ffgYLpyHENUY8BtiZAPHhnz91LJbQFkuaQnrNtf7g,9879 +astroid/protocols.py,sha256=fGHk6aTmHiH62sbHqZilRpqBsjOi-BwBWTBuiy94FxE,26513 +astroid/raw_building.py,sha256=stLA5VZqM25LtIwge3YkOKaZyjj85kxSWcp8Pqz-zn0,16111 +astroid/rebuilder.py,sha256=lUpUlCMJvQrbN-b4QELzgPfkJ4LM99V2Fw0ZK6SwlFY,40506 +astroid/scoped_nodes.py,sha256=2O7kodUoSRp052BGHu7eWPsTPvz-XGB8f9AKSk1KOmk,92399 +astroid/test_utils.py,sha256=NmVu0GTYA3Fz3BG9sF0KQt2nrd6vMSBoKpGkkIjKz28,2309 +astroid/transforms.py,sha256=1npwJWcQUSIjcpcWd1pc-dJhtHOyiboQHsETAIQd5co,3377 +astroid/util.py,sha256=jg5LnqbWSZTZP1KgpxGBuC6Lfwhn9Jb2T2TohXghmC0,4785 diff --git a/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/WHEEL b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/WHEEL new file mode 100644 index 0000000..e499438 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/top_level.txt b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/top_level.txt new file mode 100644 index 0000000..450d4fe --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid-2.2.5.dist-info/top_level.txt @@ -0,0 +1 @@ +astroid diff --git a/venv/lib/python3.7/site-packages/astroid/__init__.py b/venv/lib/python3.7/site-packages/astroid/__init__.py new file mode 100644 index 0000000..d36a5b4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/__init__.py @@ -0,0 +1,166 @@ +# Copyright (c) 2006-2013, 2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Python Abstract Syntax Tree New Generation + +The aim of this module is to provide a common base representation of +python source code for projects such as pychecker, pyreverse, +pylint... Well, actually the development of this library is essentially +governed by pylint's needs. + +It extends class defined in the python's _ast module with some +additional methods and attributes. Instance attributes are added by a +builder object, which can either generate extended ast (let's call +them astroid ;) by visiting an existent ast tree or by inspecting living +object. Methods are added by monkey patching ast classes. + +Main modules are: + +* nodes and scoped_nodes for more information about methods and + attributes added to different node classes + +* the manager contains a high level object to get astroid trees from + source files and living objects. It maintains a cache of previously + constructed tree for quick access + +* builder contains the class responsible to build astroid trees +""" + +import enum +import itertools +import os +import sys + +import wrapt + + +_Context = enum.Enum("Context", "Load Store Del") +Load = _Context.Load +Store = _Context.Store +Del = _Context.Del +del _Context + + +from .__pkginfo__ import version as __version__ + +# WARNING: internal imports order matters ! + +# pylint: disable=redefined-builtin + +# make all exception classes accessible from astroid package +from astroid.exceptions import * + +# make all node classes accessible from astroid package +from astroid.nodes import * + +# trigger extra monkey-patching +from astroid import inference + +# more stuff available +from astroid import raw_building +from astroid.bases import BaseInstance, Instance, BoundMethod, UnboundMethod +from astroid.node_classes import are_exclusive, unpack_infer +from astroid.scoped_nodes import builtin_lookup +from astroid.builder import parse, extract_node +from astroid.util import Uninferable + +# make a manager instance (borg) accessible from astroid package +from astroid.manager import AstroidManager + +MANAGER = AstroidManager() +del AstroidManager + +# transform utilities (filters and decorator) + + +# pylint: disable=dangerous-default-value +@wrapt.decorator +def _inference_tip_cached(func, instance, args, kwargs, _cache={}): + """Cache decorator used for inference tips""" + node = args[0] + try: + return iter(_cache[func, node]) + except KeyError: + result = func(*args, **kwargs) + # Need to keep an iterator around + original, copy = itertools.tee(result) + _cache[func, node] = list(copy) + return original + + +# pylint: enable=dangerous-default-value + + +def inference_tip(infer_function, raise_on_overwrite=False): + """Given an instance specific inference function, return a function to be + given to MANAGER.register_transform to set this inference function. + + :param bool raise_on_overwrite: Raise an `InferenceOverwriteError` + if the inference tip will overwrite another. Used for debugging + + Typical usage + + .. sourcecode:: python + + MANAGER.register_transform(Call, inference_tip(infer_named_tuple), + predicate) + + .. Note:: + + Using an inference tip will override + any previously set inference tip for the given + node. Use a predicate in the transform to prevent + excess overwrites. + """ + + def transform(node, infer_function=infer_function): + if ( + raise_on_overwrite + and node._explicit_inference is not None + and node._explicit_inference is not infer_function + ): + raise InferenceOverwriteError( + "Inference already set to {existing_inference}. " + "Trying to overwrite with {new_inference} for {node}".format( + existing_inference=infer_function, + new_inference=node._explicit_inference, + node=node, + ) + ) + # pylint: disable=no-value-for-parameter + node._explicit_inference = _inference_tip_cached(infer_function) + return node + + return transform + + +def register_module_extender(manager, module_name, get_extension_mod): + def transform(node): + extension_module = get_extension_mod() + for name, objs in extension_module.locals.items(): + node.locals[name] = objs + for obj in objs: + if obj.parent is extension_module: + obj.parent = node + + manager.register_transform(Module, transform, lambda n: n.name == module_name) + + +# load brain plugins +BRAIN_MODULES_DIR = os.path.join(os.path.dirname(__file__), "brain") +if BRAIN_MODULES_DIR not in sys.path: + # add it to the end of the list so user path take precedence + sys.path.append(BRAIN_MODULES_DIR) +# load modules in this directory +for module in os.listdir(BRAIN_MODULES_DIR): + if module.endswith(".py"): + __import__(module[:-3]) diff --git a/venv/lib/python3.7/site-packages/astroid/__pkginfo__.py b/venv/lib/python3.7/site-packages/astroid/__pkginfo__.py new file mode 100644 index 0000000..a1f58a8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/__pkginfo__.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2017 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 RadosÅ‚aw Ganczarek +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""astroid packaging information""" + +distname = "astroid" + +modname = "astroid" + +version = "2.2.5" +numversion = tuple(int(elem) for elem in version.split(".") if elem.isdigit()) + +extras_require = {} +install_requires = [ + "lazy_object_proxy", + "six", + "wrapt", + 'typing;python_version<"3.5"', + 'typed-ast>=1.3.0;implementation_name== "cpython"', +] + +# pylint: disable=redefined-builtin; why license is a builtin anyway? +license = "LGPL" + +author = "Python Code Quality Authority" +author_email = "code-quality@python.org" +mailinglist = "mailto://%s" % author_email +web = "https://github.com/PyCQA/astroid" + +description = "An abstract syntax tree for Python with inference support." + +classifiers = [ + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Quality Assurance", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31fa644f156097b0dad451f817f3e680a2a6d25f GIT binary patch literal 4454 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 Kw06P$O8*9oFT`*F literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/_ast.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/_ast.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6be685a783d44760aa8840ea11716cf4930b477a GIT binary patch literal 1359 zcmY*YOOM<{5bkO}#xvu2>@wk*!-`XkNM_lHY(Pi3kSyZtPm$&Aq~ped|Nsi+ciG76);EebfFuD28$W z)z`2X#R0JISvhl=9G?wT4vd~3S;>E3k_%7xqPOJFcsvoiaw_^SKn%q2xfkz|{ zRhi~(cywMa$bY=9WgDbwY0%MaPf2sGN_~W@r}(3mNxe2tsxmQ8s|C;rI5EoF&py3(rk97GAh^Sy6QNG-@8ejO^T+c#t8Zte zHff&UKGEq?7yH>9&r?+IG3i1C?Z_rD7ig!x|891smS*6>J>C)vX5fE#owfaaZ2T7yOEEFlyK{>YIZtvwKDm zPflfu{LAD5tHtg_J$rcTbqGno%0bgQdac{=)v6>bPpj4|va(WINm=Aw$~R;^l+? zDWl6`x4kCeLtNVFga_dAF{pPj69HbGqv(bjV$cp3Rh}bE{8uZIOb5?YRj#{6`iPW7 zMLJSDWcp+XY&@nagq14F^=|B1J9#5}a2R`-J~(WL-xPJF%p;|cMJlm%Pw<>hKn`lx pw$g&!D$^EhH4r@Lbn=jHw!VobfY3ex7Rb??!WevK>`a5*;6J|oPr(2H literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/arguments.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/arguments.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab0c619d4e9916240b63c7ec3e8253876a45841e GIT binary patch literal 7037 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 WZk5!&BKL5W6l6rUk7OYJ^#1^THz5%K literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/as_string.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/as_string.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b78e20bc9ece8acb73435eae8c5bbfd475607f49 GIT binary patch literal 26198 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 B0)hYl literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/builder.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/builder.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf0f08a55a128f159ce6a15b08d6e0e3392366f8 GIT binary patch literal 12312 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/context.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/context.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3f18bd92877c54f6f42c325f5006eac5b14d26a GIT binary patch literal 4297 zcmZ`+&5zs073Y^IuJ*&5)HR&+iwJ7eO4eGtO%rF~8gVwT8#GXi+DQQ=3xcZ|N!+DK zdS}VN0xa>h+pznXQ~!y?{9ntoG{kv#(;2!%ZzWJB}@T=1;V!#HDMKTgy6JlXjc%39sFT?Sti zD#^1r?bDn2Rd4EZyx|r$W6?%>E^~SwTi2Vgdkv$0&u0N!f|^a%V#}m1U)pQ26}Eb6 zo!Gr)w#F{t?Fw_Ti8spi&*pkrpq z0vpeA#$~ATP{s#5RLPj@(Rcd&e3B_GXg=p4kqOzVo&x(M8D51_!C*43>ybBdoP^tPc}pII=W-EB8ZS8^ph2oMcwd}^B11k@~{ zX}hH-c{(to==DD>v4Y!+(Pkl%0|009AQqd0JY`(S&EooIx_48l=|{i(U|$YDyipvf z4;g4$f!~D6Ra!O z&{+0L;J19=4_blmPv1HZhR%FOpUgxTnT$57O}2r~%-XY#otZsz1`hi6zAr8_`vJYT zpH=Ul+qR{H#-0A>{zQ(n*WqIzMf*sH1^LyWix9RYxSEJ;D|{#>JWK}F6uAJp8lW^Y zxF7*yBuE$ zc0g@xz^q1zT-ZTn>W6pRuE7Brs&r$<@M4+zo(85zu+`2t&8q%Xz%cjGlbYQE-(Isl zXWgED{}rdu$i9uCbdh6Ta){EVhxtJfPn}~MJ$GhDF76)g9_|g?@dtXH>A$yAGR5os za2LVPAIIY&b6m@DEv7 zV&Apbb|)%iFu53lN#ug;xlIwdXOeO);Jhgy8a$eDxMUZSX(z00>!@q{g0OlPZwpbW z1JW@rY3Nz!ydl1asS*Ch8O?P&(7)-W^BQ#Y^qNs9{K*@An)^PQp>^y&{^88|)Y`dt z?9JR~*36@Dn0a4Ww)Lp>J4@L!_k_HJV7Y~SrM>doZJ3%PqsU3B$l61mk(D(S1GX&b z>qH@r&Vc=;gc>%N16&LzqYjqXc=i1&X%f^@R6cHX7!&1?m(RL&FhP7t&T z0#5A9V9clB)JuB%j~tz^y=mi${M8ltEfEFkg~nmR)TrC`O20rB$yC`akgmruIzz5v zr9|nbJZn3p)45(Y1_@6oK!}Xa?DS&k7P;|pA#VSkl+%>rOy7IOKv9I`5=EU`X^xyL zZ+Gf>Q~!#*dPTOU{)UcOXtadUX|7}xl^*dhr5_?bdfv+u=u`zDSV9>(oNJ~Dv01Hl zOe$4=a{#K#uT!h-bi3_U@iUAsTTwL5*(9aaR-)+9Bu=ZfA(rL+C=yr529yNFo77Om z3qoGms(3t2cFVP@KaR6_$c6X;je3`wGpOkvsjLa-0y=UXP0;XMFKFEeE(EK=@|vL| z!gqZUq&~)9{us?Gb)8?=byTS}%jIq4`R%Gmd*|1v6Ljv;-X`*;GA%ZRC6!hk_}q)d zP?iBA`!E+wzNYZGiq&;^Su;nxO@;C)dK%bH=7GSR88SNxBGSW~KCMZ4tB6HB4nI$% z`nrpXt9x%Jq!qV9QZ+1c=%K4wdOI2OOv&?ezsxY;Yb`-nf}P(OU3WIZF35Z*oatkgFEZUfA$`>w}*)Qv-8M%U_1xoxKOHW9K`8_1B&lphM>?~ za4h-sMeA0I{q^&4ar-ZL*1_Rh)2j>KsH>!fz^Es6A^Zl(rI4@cfU_6pR?~R=6D^~e zwBg&Hz3zDS^x}6dN42M~@h;w@6^Nb0HEPbV{arA zMIH17adYWod3Z(;s7zT&@nV*x84F9**`N$=nG|%J%1wRT@^lfo;;tR8y?HVCKb&bz ANdN!< literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/decorators.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/decorators.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cb386eb218d336b7844cbd98fe23f9fc3f5a571 GIT binary patch literal 3538 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/helpers.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..907f7d2288fd9fe5d9dfb1371dcb51827dd63a7f GIT binary patch literal 7265 zcmd5>&u<*bb?)D64u?NPaV3h<+HHBg)Nr|^Rf?WZ6t4+7YRh+>tzLPW6yI zoar7`)kqw=X&})C$RSGNAm@NQ1VJvj=O4%=mz?_)ActUm4stLIB;Tv*84j7XolAg> zG(FYTud83bAK&|4@w3Uvih<9c{@s5(d-YAj_%}Kkd~6Ip!B_kz4$KG*W-_a7h8BM9 zw%u_;$D}z2V>k5F*u{7(98+TtV?XrOcnst5a9oXjj4NS9jmI&b2q)CIf^jvhnnrB3 zCc`Ni)@YneeT%&d$!pBo zG-|7dS1X@KJjr?@*p1uWm9DZ{o9)u5PV%lkWRiPe$$b``aSg5uKaKY9u7j5;pwRW)v&kele@xzOEjxHN8e} z=iy+O71J~M3`SpVf=9R_jogrC%X)3`cXQ*|J~3L3boVSCFqmckhs-*%((6jfYmGtb zV`gJ!rkwFHqh#cG4kNxM13DYwLTQ+KvzIo=f%S~nJF(o&Sm6)m3Qy0}Dn%s`>aEj8 z%zbE8cn_k^Hj4^}XPGP1Vte3KfdeO

GtWVdS`g?0_1p= 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 la4a9DIrGoIe3%A7yxyZCqczX29JNpb)H literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/inference.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/inference.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c05bf10633d4466994f925a57db619b725ec3e0e GIT binary patch literal 20659 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 T>ZQmsDJk$;v~zZ0JeT@^jbwJf literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/manager.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/manager.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92d0f4055568d6970f32073524992f842178e81e GIT binary patch literal 9295 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 W78$cBN#|diUzlH5EG#b1pZgC^^=X*^ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/modutils.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/modutils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c923473fd85fc0ff316dee86135015520658ea58 GIT binary patch literal 17193 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/node_classes.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/node_classes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47d00073ec2aae174bf6cbe4605f1e8b98fa0290 GIT binary patch literal 119379 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 F{}&rBfo=c* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/nodes.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/nodes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0eb33e6745d5c562e968a9b0813216d424ad4368 GIT binary patch literal 2050 zcmd7TM|0ao6aZjK?3Ae9i$(QLsu!xVs#uXdrX5e-WQKx>M+p%gfGj{+^daY*^9ypz z>@}y{bIK*z2ifr@KOo@n+lK|Pgdl|=L}3V11R@lLD8(Q~afnj_64VB5)DG>Ggd}x92X#Ux zbwL+(LpSw65A{MX^+6x?Lq83`01d(*4Z#o%!!V7&2#vxhjlmd=!#KTw7c>DAl!6pZ z!X!<>6ivf4&A<%J!Ys|f9L>W#Ex-aT!Xhof5-r0rt-uPc!YZX9O&Q408m!SetkVW; z&?aos7HrWrY|{?x&@SxK9_-OR>{Ax9bN~l*2#0h8M|2FwbOI-I3a2fcgP@tCJmjeW z1u8<3N>HLQl<5r4=p4@J0xswhE?WY4iCH|v18l`0hA@l~jA9Jqn7}q{$0S~02XWp5p`-Folyih0{2LvslDAEaN;bU>+B7372sN zSMdzfn87t%#|_-XE!@T(+{HaS!sB`wUh1JrU@`ph=h7pJW=eb13{$%`F=g30rfR0< zy6HqBold!kn(5lvY$BzOtZvt`H=66ERL~%_Jk2v~D|L7$5Ur}Gth$!=fNqu>a*uBk ziJWQrt-2}0x<_Gnsk*Q!mGwKx-u$3i6SkqJ`GKlmiEjE@om`*Yq!WMe4qQBu@tnBx zJ9K3t=eow7mGe9yBPvGW`K78;w^`Qn<cD^b?1{;F^w9^ zVA&QjaY2qPyt2xinv9ycaobRBN6t+9Rx@SmMO}t3>Z%VJdA?JfS~@<-=u2#Vu!Sx| zSB4sV$RAql+O|x)rXCEv)?8PHUkk(XWcZC{xT?`N=rx2TgB4VD&x43oJWUAHWxUe3 zb!)SWsH;KM^QCtKWHmAtQv3b zBG%QK^Dly?bV-n;?P z&Lo)*rjzMnx|trPm+52rnE_^y8DfT+5oVMbW5$^m%mkBSCYdQ_nweo{nK@>jSzs2K zC1#mfVOE(mlVR4Fb!LOvWVV=XW{25j_LzMp%N#I=%n@_UoG_<~F9~&Pwu5@rf2)Wb zU(YiIrpS~S{+kkK%sF$RfUextRrUH+u~aQwKR8EkD7;>M@?kv zwyC3VGtOGZ{BFrT_#{l2P;+r2e)+*z5o8OLx|4YhUEreD2vwL6#A njLfI?|F`tVn|9Q`J|urD9`lm9KPf`NzXRd?N=IwU|K;-!h0{FC literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/objects.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/objects.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1d01ef1eb407edf40aab633739d2c302835587e GIT binary patch literal 8521 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/raw_building.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/raw_building.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..64e96f4679ea553c39ac103bfa48656fe64de29f GIT binary patch literal 10940 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/rebuilder.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/rebuilder.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..edc890310c87e87a77d5fab48f36436004c40834 GIT binary patch literal 38356 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/scoped_nodes.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/scoped_nodes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1429d51f0d1ae231b42c4b47adcb4d1be92e5c4 GIT binary patch literal 69892 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/test_utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/test_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a06f40dbdc837509185157345d85e6a74645388 GIT binary patch literal 2509 zcmb7G%X1qw7?-r`XVNr4$+V@EWu}GMGPTngNJ~jWOX2EaCZV*3&dz3~b=F?*ZX`Jm zV{;&8;vP8gAG9Zie`&9rdgs&=-zPuPFtkkN(WjL@J%0M>d-$s}XQ~9s_>aGTEK~^j z3p=x7!N*;w>H!E&nuJr%V%nspWld&Ut7)0mZradVaiLpm7AfIXZu7#3HcNbg7kLT3 z%7V5lyv!>jazvX|&Nhj=*uVRoj^aokI$(Q@=d6!31UF9;(!jx;dyNc9>K^{Ao3ag8fZGAo5UuXb*gfUk|Cp{ zzoHqp+tz^a!f&7-uwU5s@H`x}KeLDA5lKLDIKVA70tzQ!K~j(mg>?nQfIMCrQcVW1 z#REdgE;CCg5^2F@U6!-jYEJk5B(ezeUv%o3jP`sj>U+Mdhvssso~_p7_ARaZpMSR2 zQLURdfUcXn9+%s(UUx0T;g-PNc*eam@^#Cbh11y#!qUsTpx zA`u6f+_;2*5xq_NH>B9@MN)Xv=c%p7Y2e3dqXv(r#7TF)I;XY%+D~9MQPLVZk#dq$ zJ3iQzlp@gcXTI&IowOHoXInTAYma`YH6Pc2hvHs%VLoiR0gJ+S0DIsPkbX~ zD)S;3YuDGVCGl1B5*MN0i*;^^gTN3s5hYX>49p97qh%0;mMNp>=`u*0mRbMu>+d&z zOngWi>N`+X8-ylp3Kl?rWf#bhj;%4{?1&Ah4R78dvIZkyQAeyplGp>V4{kqY zyugbivmUMO8GS;u^%S(vD0;{-0Us&x@~C`7r(RNNJjdg63byg7gpfhzu-?qZfLoVI zyoM~GKqEWhN|vGPLY=++y;pJ*?1-S_y;425g*i^dk4Juh+usHO%U}FIy@vcJ{G_(PGy>0AGMMO0Zo3QfJO_!X*SovG0YS z;B^;45LO0zTQ;(P=at0$53goVw~$-vQ00qLkMyD>Omn-PMoC^V0Xc@|be4l9GJBoO?;L{-#<7#>D3q;LrCrKx7Zk%>MA=8{PK z?O1qI^_K_(gArki5T~oQTs1p4AW=%h>MrCZ&*N#}d3iNR;cvo$j-zeqfKI-T;yQ?C zX`1j1dB#%AwezLvlCGclEg{YBFF`uNRbKC=ycdg&1=!By56BslA6vAlA6M;v02|YC A1ONa4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/transforms.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/transforms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..717a0734cac1975d8ff96c4772dcb487c2b1700d GIT binary patch literal 3456 zcmbVPOLN@D5uO3CPd>!Zifomfc&aSLUfLohyCNwHqga;ZBrbd95@}1>k_rSdv%4U% zz;b3lid)!R$g22~L;ituO8J<-gKJK{=j1~w-Gj%9CRK@zS`2`B^h|&K&DXOZFD$eP zT;KfT-%qYD5b`hlC@&jcK7w2Q3JOj*4M`85R!B!y&!XfHgxlOXCfqr)dN!vUq*MD2 z`jT#kX01>ruJ8Fn;bT>KRYrSIBS?>O(z7^);a1Pd&Gl-cE*xI_8|8K0I3`E5*WgXw zIwrj)Z}T~Lw)ks&fiE7@UYnoi=lBx5&GDb{WoVn{^RSSgXG@#Xi&Q_Bqpt%M=vYqv zbC>PsuMDc$(2IB&L<6SFj%u~tW^io|1ydTDJ;|9j9?KZ~U~!)%3i}6|1&ZmI`Cb^B z0k=m&4{vY%#hBk>2Z0_kFJdd6(lQSC3LC{d2?f+~rop%$dPmZI)HpfNZOG3>9UuRAjD4n%u^Fz=b zCBpukfx~;r{8eI$43M{MVY~t1NVb*lrAPThWzJdN&P!Kw~xLHQF zpulR`3)b2gdCycZ5x(gR{Tpysh;aBw=?wV!>I+Mkf8 zx1Ly2XIe{ZobEQ&dRj~A5tWxy2cOe=T8H|U{4%XiXr*tgPj_hIpe1aIvtT}bQOpi8i3nS^K*F702QZ4mi+kH4G0Pa*x#R8+Dai5 zN7mF%$#XlkU(l%ou-gFevIh7eaL$oU$=)(RO`bzwUKqf;**Ui$liLqO$W^DFHHMz@ zw3hNUm@jJ#gvPII(KTDz9f(NCz|R^gZ;;E-ty41q%0(RFMBYebwS6y4MAk5)1pgsc z_1xSCFhJobLfdp6?lx@#PLtP9qhkzJ$RJf6xRIvnF%*c5Mr7XnE9nD9+&XTifX@+l zYT5uFxvnkKieg=~VtY#EXQq!0eY!}-Z^(1N&7f54R!V`BVmJ^PbpeV2!1;7>N})R# zc|ref?KvCyrteURJ%DW1>b0x}j1D=}ARd?W}9Dib!2+fCR5IG2IT$-)%YXU^DN?j{gDc^*S@)uB?USw+>gZ^wR@BAK3 z=Fm?*`2W{f4)4^mHl!WYv&a{+4%V`oPR1eZC&&*HcTLBdQON*Rt_Qc6f%Lbyh>|nQ zz?ciLw;XHo*8f;g*GE+F!YAHlTjdCW9?^@S`><8)K4?FMERUMx-Gub;Pz(TNA=#EL zW%ON?ip~~8UBHxpNpKtT(s&#OAURl3%2lOF#a4Squ`L{(OVAby*;XYi@TpigjvxU_ zNPehmkYHspQ?`R4C?Murn8u`6oCxhPPccspl97mXk-kyyHcief4gjz03OS3@ElFI7L zH7Q2%z9?Lim(hnSSe)g}`J}Qs^XEb3k2Se+%Ad1FoDe}2KqG<-US5{I9fIPQQWwPx zo<_{<$v+>#S?VR93R1EajNM9pE-OjS&OAfqCqoSIgD5;SrZAwY;Lp(8$3t2{I0Yoj zH;&|w}5A*bwYgSgz54Wde3z8w8wl{Dpqe1lxbaLVB$?&iVzXd$UVIp;1 zI9Is2VR)Z+-93P>Xlb}EkA2tey|MZ5Zg=C;2M@n+zqtF@y?6KCAMd*xf9l3Zu5jEBG%&6z2G5!+~>5(_VhP*=n}oawN6`^U(jwYSA{|jJGgK7W( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/__pycache__/util.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7061afa747aae96e07a1b376ad6fcc6d4fedc3bd GIT binary patch literal 5724 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 Q%}YOB@mGJoy6ofce+Z>vA^-pY literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/_ast.py b/venv/lib/python3.7/site-packages/astroid/_ast.py new file mode 100644 index 0000000..da95f1d --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/_ast.py @@ -0,0 +1,40 @@ +import ast +from collections import namedtuple +from functools import partial +from typing import Optional +import sys + +_ast_py2 = _ast_py3 = None +try: + import typed_ast.ast3 as _ast_py3 + import typed_ast.ast27 as _ast_py2 +except ImportError: + pass + + +FunctionType = namedtuple("FunctionType", ["argtypes", "returns"]) + + +def _get_parser_module(parse_python_two: bool = False): + if parse_python_two: + parser_module = _ast_py2 + else: + parser_module = _ast_py3 + return parser_module or ast + + +def _parse(string: str, parse_python_two: bool = False): + parse_module = _get_parser_module(parse_python_two=parse_python_two) + parse_func = parse_module.parse + if _ast_py3 and not parse_python_two: + parse_func = partial(parse_func, feature_version=sys.version_info.minor) + return parse_func(string) + + +def parse_function_type_comment(type_comment: str) -> Optional[FunctionType]: + """Given a correct type comment, obtain a FunctionType object""" + if _ast_py3 is None: + return None + + func_type = _ast_py3.parse(type_comment, "", "func_type") + return FunctionType(argtypes=func_type.argtypes, returns=func_type.returns) diff --git a/venv/lib/python3.7/site-packages/astroid/arguments.py b/venv/lib/python3.7/site-packages/astroid/arguments.py new file mode 100644 index 0000000..c4bdc6d --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/arguments.py @@ -0,0 +1,285 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import nodes +from astroid import util + + +class CallSite: + """Class for understanding arguments passed into a call site + + It needs a call context, which contains the arguments and the + keyword arguments that were passed into a given call site. + In order to infer what an argument represents, call + :meth:`infer_argument` with the corresponding function node + and the argument name. + """ + + def __init__(self, callcontext, argument_context_map=None): + if argument_context_map is None: + argument_context_map = {} + self.argument_context_map = argument_context_map + args = callcontext.args + keywords = callcontext.keywords + self.duplicated_keywords = set() + self._unpacked_args = self._unpack_args(args) + self._unpacked_kwargs = self._unpack_keywords(keywords) + + self.positional_arguments = [ + arg for arg in self._unpacked_args if arg is not util.Uninferable + ] + self.keyword_arguments = { + key: value + for key, value in self._unpacked_kwargs.items() + if value is not util.Uninferable + } + + @classmethod + def from_call(cls, call_node): + """Get a CallSite object from the given Call node.""" + callcontext = contextmod.CallContext(call_node.args, call_node.keywords) + return cls(callcontext) + + def has_invalid_arguments(self): + """Check if in the current CallSite were passed *invalid* arguments + + This can mean multiple things. For instance, if an unpacking + of an invalid object was passed, then this method will return True. + Other cases can be when the arguments can't be inferred by astroid, + for example, by passing objects which aren't known statically. + """ + return len(self.positional_arguments) != len(self._unpacked_args) + + def has_invalid_keywords(self): + """Check if in the current CallSite were passed *invalid* keyword arguments + + For instance, unpacking a dictionary with integer keys is invalid + (**{1:2}), because the keys must be strings, which will make this + method to return True. Other cases where this might return True if + objects which can't be inferred were passed. + """ + return len(self.keyword_arguments) != len(self._unpacked_kwargs) + + def _unpack_keywords(self, keywords): + values = {} + context = contextmod.InferenceContext() + context.extra_context = self.argument_context_map + for name, value in keywords: + if name is None: + # Then it's an unpacking operation (**) + try: + inferred = next(value.infer(context=context)) + except exceptions.InferenceError: + values[name] = util.Uninferable + continue + + if not isinstance(inferred, nodes.Dict): + # Not something we can work with. + values[name] = util.Uninferable + continue + + for dict_key, dict_value in inferred.items: + try: + dict_key = next(dict_key.infer(context=context)) + except exceptions.InferenceError: + values[name] = util.Uninferable + continue + if not isinstance(dict_key, nodes.Const): + values[name] = util.Uninferable + continue + if not isinstance(dict_key.value, str): + values[name] = util.Uninferable + continue + if dict_key.value in values: + # The name is already in the dictionary + values[dict_key.value] = util.Uninferable + self.duplicated_keywords.add(dict_key.value) + continue + values[dict_key.value] = dict_value + else: + values[name] = value + return values + + def _unpack_args(self, args): + values = [] + context = contextmod.InferenceContext() + context.extra_context = self.argument_context_map + for arg in args: + if isinstance(arg, nodes.Starred): + try: + inferred = next(arg.value.infer(context=context)) + except exceptions.InferenceError: + values.append(util.Uninferable) + continue + + if inferred is util.Uninferable: + values.append(util.Uninferable) + continue + if not hasattr(inferred, "elts"): + values.append(util.Uninferable) + continue + values.extend(inferred.elts) + else: + values.append(arg) + return values + + def infer_argument(self, funcnode, name, context): + """infer a function argument value according to the call context + + Arguments: + funcnode: The function being called. + name: The name of the argument whose value is being inferred. + context: Inference context object + """ + if name in self.duplicated_keywords: + raise exceptions.InferenceError( + "The arguments passed to {func!r} " " have duplicate keywords.", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + + # Look into the keywords first, maybe it's already there. + try: + return self.keyword_arguments[name].infer(context) + except KeyError: + pass + + # Too many arguments given and no variable arguments. + if len(self.positional_arguments) > len(funcnode.args.args): + if not funcnode.args.vararg: + raise exceptions.InferenceError( + "Too many positional arguments " + "passed to {func!r} that does " + "not have *args.", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + + positional = self.positional_arguments[: len(funcnode.args.args)] + vararg = self.positional_arguments[len(funcnode.args.args) :] + argindex = funcnode.args.find_argname(name)[0] + kwonlyargs = {arg.name for arg in funcnode.args.kwonlyargs} + kwargs = { + key: value + for key, value in self.keyword_arguments.items() + if key not in kwonlyargs + } + # If there are too few positionals compared to + # what the function expects to receive, check to see + # if the missing positional arguments were passed + # as keyword arguments and if so, place them into the + # positional args list. + if len(positional) < len(funcnode.args.args): + for func_arg in funcnode.args.args: + if func_arg.name in kwargs: + arg = kwargs.pop(func_arg.name) + positional.append(arg) + + if argindex is not None: + # 2. first argument of instance/class method + if argindex == 0 and funcnode.type in ("method", "classmethod"): + if context.boundnode is not None: + boundnode = context.boundnode + else: + # XXX can do better ? + boundnode = funcnode.parent.frame() + + if isinstance(boundnode, nodes.ClassDef): + # Verify that we're accessing a method + # of the metaclass through a class, as in + # `cls.metaclass_method`. In this case, the + # first argument is always the class. + method_scope = funcnode.parent.scope() + if method_scope is boundnode.metaclass(): + return iter((boundnode,)) + + if funcnode.type == "method": + if not isinstance(boundnode, bases.Instance): + boundnode = bases.Instance(boundnode) + return iter((boundnode,)) + if funcnode.type == "classmethod": + return iter((boundnode,)) + # if we have a method, extract one position + # from the index, so we'll take in account + # the extra parameter represented by `self` or `cls` + if funcnode.type in ("method", "classmethod"): + argindex -= 1 + # 2. search arg index + try: + return self.positional_arguments[argindex].infer(context) + except IndexError: + pass + + if funcnode.args.kwarg == name: + # It wants all the keywords that were passed into + # the call site. + if self.has_invalid_keywords(): + raise exceptions.InferenceError( + "Inference failed to find values for all keyword arguments " + "to {func!r}: {unpacked_kwargs!r} doesn't correspond to " + "{keyword_arguments!r}.", + keyword_arguments=self.keyword_arguments, + unpacked_kwargs=self._unpacked_kwargs, + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + kwarg = nodes.Dict( + lineno=funcnode.args.lineno, + col_offset=funcnode.args.col_offset, + parent=funcnode.args, + ) + kwarg.postinit( + [(nodes.const_factory(key), value) for key, value in kwargs.items()] + ) + return iter((kwarg,)) + if funcnode.args.vararg == name: + # It wants all the args that were passed into + # the call site. + if self.has_invalid_arguments(): + raise exceptions.InferenceError( + "Inference failed to find values for all positional " + "arguments to {func!r}: {unpacked_args!r} doesn't " + "correspond to {positional_arguments!r}.", + positional_arguments=self.positional_arguments, + unpacked_args=self._unpacked_args, + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + args = nodes.Tuple( + lineno=funcnode.args.lineno, + col_offset=funcnode.args.col_offset, + parent=funcnode.args, + ) + args.postinit(vararg) + return iter((args,)) + + # Check if it's a default parameter. + try: + return funcnode.args.default_value(name).infer(context) + except exceptions.NoDefault: + pass + raise exceptions.InferenceError( + "No value found for argument {name} to " "{func!r}", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) diff --git a/venv/lib/python3.7/site-packages/astroid/as_string.py b/venv/lib/python3.7/site-packages/astroid/as_string.py new file mode 100644 index 0000000..7042272 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/as_string.py @@ -0,0 +1,630 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2013-2016, 2018 Claudiu Popa +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 brendanator +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module renders Astroid nodes as string: + +* :func:`to_code` function return equivalent (hopefully valid) python string + +* :func:`dump` function return an internal representation of nodes found + in the tree, useful for debugging or understanding the tree structure +""" +import sys + + +# pylint: disable=unused-argument + +DOC_NEWLINE = "\0" + + +class AsStringVisitor: + """Visitor to render an Astroid node as a valid python code string""" + + def __init__(self, indent): + self.indent = indent + + def __call__(self, node): + """Makes this visitor behave as a simple function""" + return node.accept(self).replace(DOC_NEWLINE, "\n") + + def _docs_dedent(self, doc): + """Stop newlines in docs being indented by self._stmt_list""" + return '\n%s"""%s"""' % (self.indent, doc.replace("\n", DOC_NEWLINE)) + + def _stmt_list(self, stmts, indent=True): + """return a list of nodes to string""" + stmts = "\n".join(nstr for nstr in [n.accept(self) for n in stmts] if nstr) + if indent: + return self.indent + stmts.replace("\n", "\n" + self.indent) + + return stmts + + def _precedence_parens(self, node, child, is_left=True): + """Wrap child in parens only if required to keep same semantics""" + if self._should_wrap(node, child, is_left): + return "(%s)" % child.accept(self) + + return child.accept(self) + + def _should_wrap(self, node, child, is_left): + """Wrap child if: + - it has lower precedence + - same precedence with position opposite to associativity direction + """ + node_precedence = node.op_precedence() + child_precedence = child.op_precedence() + + if node_precedence > child_precedence: + # 3 * (4 + 5) + return True + + if ( + node_precedence == child_precedence + and is_left != node.op_left_associative() + ): + # 3 - (4 - 5) + # (2**3)**4 + return True + + return False + + ## visit_ methods ########################################### + + def visit_arguments(self, node): + """return an astroid.Function node as string""" + return node.format_args() + + def visit_assignattr(self, node): + """return an astroid.AssAttr node as string""" + return self.visit_attribute(node) + + def visit_assert(self, node): + """return an astroid.Assert node as string""" + if node.fail: + return "assert %s, %s" % (node.test.accept(self), node.fail.accept(self)) + return "assert %s" % node.test.accept(self) + + def visit_assignname(self, node): + """return an astroid.AssName node as string""" + return node.name + + def visit_assign(self, node): + """return an astroid.Assign node as string""" + lhs = " = ".join(n.accept(self) for n in node.targets) + return "%s = %s" % (lhs, node.value.accept(self)) + + def visit_augassign(self, node): + """return an astroid.AugAssign node as string""" + return "%s %s %s" % (node.target.accept(self), node.op, node.value.accept(self)) + + def visit_annassign(self, node): + """Return an astroid.AugAssign node as string""" + + target = node.target.accept(self) + annotation = node.annotation.accept(self) + if node.value is None: + return "%s: %s" % (target, annotation) + return "%s: %s = %s" % (target, annotation, node.value.accept(self)) + + def visit_repr(self, node): + """return an astroid.Repr node as string""" + return "`%s`" % node.value.accept(self) + + def visit_binop(self, node): + """return an astroid.BinOp node as string""" + left = self._precedence_parens(node, node.left) + right = self._precedence_parens(node, node.right, is_left=False) + if node.op == "**": + return "%s%s%s" % (left, node.op, right) + + return "%s %s %s" % (left, node.op, right) + + def visit_boolop(self, node): + """return an astroid.BoolOp node as string""" + values = ["%s" % self._precedence_parens(node, n) for n in node.values] + return (" %s " % node.op).join(values) + + def visit_break(self, node): + """return an astroid.Break node as string""" + return "break" + + def visit_call(self, node): + """return an astroid.Call node as string""" + expr_str = self._precedence_parens(node, node.func) + args = [arg.accept(self) for arg in node.args] + if node.keywords: + keywords = [kwarg.accept(self) for kwarg in node.keywords] + else: + keywords = [] + + args.extend(keywords) + return "%s(%s)" % (expr_str, ", ".join(args)) + + def visit_classdef(self, node): + """return an astroid.ClassDef node as string""" + decorate = node.decorators.accept(self) if node.decorators else "" + bases = ", ".join(n.accept(self) for n in node.bases) + metaclass = node.metaclass() + if metaclass and not node.has_metaclass_hack(): + if bases: + bases = "(%s, metaclass=%s)" % (bases, metaclass.name) + else: + bases = "(metaclass=%s)" % metaclass.name + else: + bases = "(%s)" % bases if bases else "" + docs = self._docs_dedent(node.doc) if node.doc else "" + return "\n\n%sclass %s%s:%s\n%s\n" % ( + decorate, + node.name, + bases, + docs, + self._stmt_list(node.body), + ) + + def visit_compare(self, node): + """return an astroid.Compare node as string""" + rhs_str = " ".join( + [ + "%s %s" % (op, self._precedence_parens(node, expr, is_left=False)) + for op, expr in node.ops + ] + ) + return "%s %s" % (self._precedence_parens(node, node.left), rhs_str) + + def visit_comprehension(self, node): + """return an astroid.Comprehension node as string""" + ifs = "".join(" if %s" % n.accept(self) for n in node.ifs) + return "for %s in %s%s" % ( + node.target.accept(self), + node.iter.accept(self), + ifs, + ) + + def visit_const(self, node): + """return an astroid.Const node as string""" + if node.value is Ellipsis: + return "..." + return repr(node.value) + + def visit_continue(self, node): + """return an astroid.Continue node as string""" + return "continue" + + def visit_delete(self, node): # XXX check if correct + """return an astroid.Delete node as string""" + return "del %s" % ", ".join(child.accept(self) for child in node.targets) + + def visit_delattr(self, node): + """return an astroid.DelAttr node as string""" + return self.visit_attribute(node) + + def visit_delname(self, node): + """return an astroid.DelName node as string""" + return node.name + + def visit_decorators(self, node): + """return an astroid.Decorators node as string""" + return "@%s\n" % "\n@".join(item.accept(self) for item in node.nodes) + + def visit_dict(self, node): + """return an astroid.Dict node as string""" + return "{%s}" % ", ".join(self._visit_dict(node)) + + def _visit_dict(self, node): + for key, value in node.items: + key = key.accept(self) + value = value.accept(self) + if key == "**": + # It can only be a DictUnpack node. + yield key + value + else: + yield "%s: %s" % (key, value) + + def visit_dictunpack(self, node): + return "**" + + def visit_dictcomp(self, node): + """return an astroid.DictComp node as string""" + return "{%s: %s %s}" % ( + node.key.accept(self), + node.value.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_expr(self, node): + """return an astroid.Discard node as string""" + return node.value.accept(self) + + def visit_emptynode(self, node): + """dummy method for visiting an Empty node""" + return "" + + def visit_excepthandler(self, node): + if node.type: + if node.name: + excs = "except %s, %s" % ( + node.type.accept(self), + node.name.accept(self), + ) + else: + excs = "except %s" % node.type.accept(self) + else: + excs = "except" + return "%s:\n%s" % (excs, self._stmt_list(node.body)) + + def visit_ellipsis(self, node): + """return an astroid.Ellipsis node as string""" + return "..." + + def visit_empty(self, node): + """return an Empty node as string""" + return "" + + def visit_exec(self, node): + """return an astroid.Exec node as string""" + if node.locals: + return "exec %s in %s, %s" % ( + node.expr.accept(self), + node.locals.accept(self), + node.globals.accept(self), + ) + if node.globals: + return "exec %s in %s" % (node.expr.accept(self), node.globals.accept(self)) + return "exec %s" % node.expr.accept(self) + + def visit_extslice(self, node): + """return an astroid.ExtSlice node as string""" + return ", ".join(dim.accept(self) for dim in node.dims) + + def visit_for(self, node): + """return an astroid.For node as string""" + fors = "for %s in %s:\n%s" % ( + node.target.accept(self), + node.iter.accept(self), + self._stmt_list(node.body), + ) + if node.orelse: + fors = "%s\nelse:\n%s" % (fors, self._stmt_list(node.orelse)) + return fors + + def visit_importfrom(self, node): + """return an astroid.ImportFrom node as string""" + return "from %s import %s" % ( + "." * (node.level or 0) + node.modname, + _import_string(node.names), + ) + + def visit_functiondef(self, node): + """return an astroid.Function node as string""" + decorate = node.decorators.accept(self) if node.decorators else "" + docs = self._docs_dedent(node.doc) if node.doc else "" + trailer = ":" + if node.returns: + return_annotation = "->" + node.returns.as_string() + trailer = return_annotation + ":" + def_format = "\n%sdef %s(%s)%s%s\n%s" + return def_format % ( + decorate, + node.name, + node.args.accept(self), + trailer, + docs, + self._stmt_list(node.body), + ) + + def visit_generatorexp(self, node): + """return an astroid.GeneratorExp node as string""" + return "(%s %s)" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_attribute(self, node): + """return an astroid.Getattr node as string""" + return "%s.%s" % (self._precedence_parens(node, node.expr), node.attrname) + + def visit_global(self, node): + """return an astroid.Global node as string""" + return "global %s" % ", ".join(node.names) + + def visit_if(self, node): + """return an astroid.If node as string""" + ifs = ["if %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body))] + if node.has_elif_block(): + ifs.append("el%s" % self._stmt_list(node.orelse, indent=False)) + elif node.orelse: + ifs.append("else:\n%s" % self._stmt_list(node.orelse)) + return "\n".join(ifs) + + def visit_ifexp(self, node): + """return an astroid.IfExp node as string""" + return "%s if %s else %s" % ( + self._precedence_parens(node, node.body, is_left=True), + self._precedence_parens(node, node.test, is_left=True), + self._precedence_parens(node, node.orelse, is_left=False), + ) + + def visit_import(self, node): + """return an astroid.Import node as string""" + return "import %s" % _import_string(node.names) + + def visit_keyword(self, node): + """return an astroid.Keyword node as string""" + if node.arg is None: + return "**%s" % node.value.accept(self) + return "%s=%s" % (node.arg, node.value.accept(self)) + + def visit_lambda(self, node): + """return an astroid.Lambda node as string""" + args = node.args.accept(self) + body = node.body.accept(self) + if args: + return "lambda %s: %s" % (args, body) + + return "lambda: %s" % body + + def visit_list(self, node): + """return an astroid.List node as string""" + return "[%s]" % ", ".join(child.accept(self) for child in node.elts) + + def visit_listcomp(self, node): + """return an astroid.ListComp node as string""" + return "[%s %s]" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_module(self, node): + """return an astroid.Module node as string""" + docs = '"""%s"""\n\n' % node.doc if node.doc else "" + return docs + "\n".join(n.accept(self) for n in node.body) + "\n\n" + + def visit_name(self, node): + """return an astroid.Name node as string""" + return node.name + + def visit_pass(self, node): + """return an astroid.Pass node as string""" + return "pass" + + def visit_print(self, node): + """return an astroid.Print node as string""" + nodes = ", ".join(n.accept(self) for n in node.values) + if not node.nl: + nodes = "%s," % nodes + if node.dest: + return "print >> %s, %s" % (node.dest.accept(self), nodes) + return "print %s" % nodes + + def visit_raise(self, node): + """return an astroid.Raise node as string""" + if node.exc: + if node.inst: + if node.tback: + return "raise %s, %s, %s" % ( + node.exc.accept(self), + node.inst.accept(self), + node.tback.accept(self), + ) + return "raise %s, %s" % (node.exc.accept(self), node.inst.accept(self)) + return "raise %s" % node.exc.accept(self) + return "raise" + + def visit_return(self, node): + """return an astroid.Return node as string""" + if node.is_tuple_return() and len(node.value.elts) > 1: + elts = [child.accept(self) for child in node.value.elts] + return "return %s" % ", ".join(elts) + + if node.value: + return "return %s" % node.value.accept(self) + + return "return" + + def visit_index(self, node): + """return an astroid.Index node as string""" + return node.value.accept(self) + + def visit_set(self, node): + """return an astroid.Set node as string""" + return "{%s}" % ", ".join(child.accept(self) for child in node.elts) + + def visit_setcomp(self, node): + """return an astroid.SetComp node as string""" + return "{%s %s}" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_slice(self, node): + """return an astroid.Slice node as string""" + lower = node.lower.accept(self) if node.lower else "" + upper = node.upper.accept(self) if node.upper else "" + step = node.step.accept(self) if node.step else "" + if step: + return "%s:%s:%s" % (lower, upper, step) + return "%s:%s" % (lower, upper) + + def visit_subscript(self, node): + """return an astroid.Subscript node as string""" + idx = node.slice + if idx.__class__.__name__.lower() == "index": + idx = idx.value + idxstr = idx.accept(self) + if idx.__class__.__name__.lower() == "tuple" and idx.elts: + # Remove parenthesis in tuple and extended slice. + # a[(::1, 1:)] is not valid syntax. + idxstr = idxstr[1:-1] + return "%s[%s]" % (self._precedence_parens(node, node.value), idxstr) + + def visit_tryexcept(self, node): + """return an astroid.TryExcept node as string""" + trys = ["try:\n%s" % self._stmt_list(node.body)] + for handler in node.handlers: + trys.append(handler.accept(self)) + if node.orelse: + trys.append("else:\n%s" % self._stmt_list(node.orelse)) + return "\n".join(trys) + + def visit_tryfinally(self, node): + """return an astroid.TryFinally node as string""" + return "try:\n%s\nfinally:\n%s" % ( + self._stmt_list(node.body), + self._stmt_list(node.finalbody), + ) + + def visit_tuple(self, node): + """return an astroid.Tuple node as string""" + if len(node.elts) == 1: + return "(%s, )" % node.elts[0].accept(self) + return "(%s)" % ", ".join(child.accept(self) for child in node.elts) + + def visit_unaryop(self, node): + """return an astroid.UnaryOp node as string""" + if node.op == "not": + operator = "not " + else: + operator = node.op + return "%s%s" % (operator, self._precedence_parens(node, node.operand)) + + def visit_while(self, node): + """return an astroid.While node as string""" + whiles = "while %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body)) + if node.orelse: + whiles = "%s\nelse:\n%s" % (whiles, self._stmt_list(node.orelse)) + return whiles + + def visit_with(self, node): # 'with' without 'as' is possible + """return an astroid.With node as string""" + items = ", ".join( + ("%s" % expr.accept(self)) + (vars and " as %s" % (vars.accept(self)) or "") + for expr, vars in node.items + ) + return "with %s:\n%s" % (items, self._stmt_list(node.body)) + + def visit_yield(self, node): + """yield an ast.Yield node as string""" + yi_val = (" " + node.value.accept(self)) if node.value else "" + expr = "yield" + yi_val + if node.parent.is_statement: + return expr + + return "(%s)" % (expr,) + + def visit_starred(self, node): + """return Starred node as string""" + return "*" + node.value.accept(self) + + # These aren't for real AST nodes, but for inference objects. + + def visit_frozenset(self, node): + return node.parent.accept(self) + + def visit_super(self, node): + return node.parent.accept(self) + + def visit_uninferable(self, node): + return str(node) + + +class AsStringVisitor3(AsStringVisitor): + """AsStringVisitor3 overwrites some AsStringVisitor methods""" + + def visit_excepthandler(self, node): + if node.type: + if node.name: + excs = "except %s as %s" % ( + node.type.accept(self), + node.name.accept(self), + ) + else: + excs = "except %s" % node.type.accept(self) + else: + excs = "except" + return "%s:\n%s" % (excs, self._stmt_list(node.body)) + + def visit_nonlocal(self, node): + """return an astroid.Nonlocal node as string""" + return "nonlocal %s" % ", ".join(node.names) + + def visit_raise(self, node): + """return an astroid.Raise node as string""" + if node.exc: + if node.cause: + return "raise %s from %s" % ( + node.exc.accept(self), + node.cause.accept(self), + ) + return "raise %s" % node.exc.accept(self) + return "raise" + + def visit_yieldfrom(self, node): + """ Return an astroid.YieldFrom node as string. """ + yi_val = (" " + node.value.accept(self)) if node.value else "" + expr = "yield from" + yi_val + if node.parent.is_statement: + return expr + + return "(%s)" % (expr,) + + def visit_asyncfunctiondef(self, node): + function = super(AsStringVisitor3, self).visit_functiondef(node) + return "async " + function.strip() + + def visit_await(self, node): + return "await %s" % node.value.accept(self) + + def visit_asyncwith(self, node): + return "async %s" % self.visit_with(node) + + def visit_asyncfor(self, node): + return "async %s" % self.visit_for(node) + + def visit_joinedstr(self, node): + # Special treatment for constants, + # as we want to join literals not reprs + string = "".join( + value.value if type(value).__name__ == "Const" else value.accept(self) + for value in node.values + ) + return "f'%s'" % string + + def visit_formattedvalue(self, node): + return "{%s}" % node.value.accept(self) + + def visit_comprehension(self, node): + """return an astroid.Comprehension node as string""" + return "%s%s" % ( + "async " if node.is_async else "", + super(AsStringVisitor3, self).visit_comprehension(node), + ) + + +def _import_string(names): + """return a list of (name, asname) formatted as a string""" + _names = [] + for name, asname in names: + if asname is not None: + _names.append("%s as %s" % (name, asname)) + else: + _names.append(name) + return ", ".join(_names) + + +if sys.version_info >= (3, 0): + AsStringVisitor = AsStringVisitor3 + +# This sets the default indent to 4 spaces. +to_code = AsStringVisitor(" ") diff --git a/venv/lib/python3.7/site-packages/astroid/bases.py b/venv/lib/python3.7/site-packages/astroid/bases.py new file mode 100644 index 0000000..8fbbebf --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/bases.py @@ -0,0 +1,547 @@ +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Daniel Colascione + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module contains base classes and functions for the nodes and some +inference utils. +""" + +import builtins +import collections +import sys + +from astroid import context as contextmod +from astroid import exceptions +from astroid import util + +objectmodel = util.lazy_import("interpreter.objectmodel") +helpers = util.lazy_import("helpers") +BUILTINS = builtins.__name__ +manager = util.lazy_import("manager") +MANAGER = manager.AstroidManager() + +if sys.version_info >= (3, 0): + # TODO: check if needs special treatment + BUILTINS = "builtins" + BOOL_SPECIAL_METHOD = "__bool__" +else: + BUILTINS = "__builtin__" + BOOL_SPECIAL_METHOD = "__nonzero__" +PROPERTIES = {BUILTINS + ".property", "abc.abstractproperty"} +# List of possible property names. We use this list in order +# to see if a method is a property or not. This should be +# pretty reliable and fast, the alternative being to check each +# decorator to see if its a real property-like descriptor, which +# can be too complicated. +# Also, these aren't qualified, because each project can +# define them, we shouldn't expect to know every possible +# property-like decorator! +POSSIBLE_PROPERTIES = { + "cached_property", + "cachedproperty", + "lazyproperty", + "lazy_property", + "reify", + "lazyattribute", + "lazy_attribute", + "LazyProperty", + "lazy", + "cache_readonly", +} + + +def _is_property(meth): + if PROPERTIES.intersection(meth.decoratornames()): + return True + stripped = { + name.split(".")[-1] + for name in meth.decoratornames() + if name is not util.Uninferable + } + if any(name in stripped for name in POSSIBLE_PROPERTIES): + return True + + # Lookup for subclasses of *property* + if not meth.decorators: + return False + for decorator in meth.decorators.nodes or (): + inferred = helpers.safe_infer(decorator) + if inferred is None or inferred is util.Uninferable: + continue + if inferred.__class__.__name__ == "ClassDef": + for base_class in inferred.bases: + if base_class.__class__.__name__ != "Name": + continue + module, _ = base_class.lookup(base_class.name) + if module.name == BUILTINS and base_class.name == "property": + return True + + return False + + +class Proxy: + """a simple proxy object + + Note: + + Subclasses of this object will need a custom __getattr__ + if new instance attributes are created. See the Const class + """ + + _proxied = None # proxied object may be set by class or by instance + + def __init__(self, proxied=None): + if proxied is not None: + self._proxied = proxied + + def __getattr__(self, name): + if name == "_proxied": + return getattr(self.__class__, "_proxied") + if name in self.__dict__: + return self.__dict__[name] + return getattr(self._proxied, name) + + def infer(self, context=None): + yield self + + +def _infer_stmts(stmts, context, frame=None): + """Return an iterator on statements inferred by each statement in *stmts*.""" + inferred = False + if context is not None: + name = context.lookupname + context = context.clone() + else: + name = None + context = contextmod.InferenceContext() + + for stmt in stmts: + if stmt is util.Uninferable: + yield stmt + inferred = True + continue + context.lookupname = stmt._infer_name(frame, name) + try: + for inferred in stmt.infer(context=context): + yield inferred + inferred = True + except exceptions.NameInferenceError: + continue + except exceptions.InferenceError: + yield util.Uninferable + inferred = True + if not inferred: + raise exceptions.InferenceError( + "Inference failed for all members of {stmts!r}.", + stmts=stmts, + frame=frame, + context=context, + ) + + +def _infer_method_result_truth(instance, method_name, context): + # Get the method from the instance and try to infer + # its return's truth value. + meth = next(instance.igetattr(method_name, context=context), None) + if meth and hasattr(meth, "infer_call_result"): + if not meth.callable(): + return util.Uninferable + try: + for value in meth.infer_call_result(instance, context=context): + if value is util.Uninferable: + return value + + inferred = next(value.infer(context=context)) + return inferred.bool_value() + except exceptions.InferenceError: + pass + return util.Uninferable + + +class BaseInstance(Proxy): + """An instance base class, which provides lookup methods for potential instances.""" + + special_attributes = None + + def display_type(self): + return "Instance of" + + def getattr(self, name, context=None, lookupclass=True): + try: + values = self._proxied.instance_attr(name, context) + except exceptions.AttributeInferenceError as exc: + if self.special_attributes and name in self.special_attributes: + return [self.special_attributes.lookup(name)] + + if lookupclass: + # Class attributes not available through the instance + # unless they are explicitly defined. + return self._proxied.getattr(name, context, class_context=False) + + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) from exc + # since we've no context information, return matching class members as + # well + if lookupclass: + try: + return values + self._proxied.getattr( + name, context, class_context=False + ) + except exceptions.AttributeInferenceError: + pass + return values + + def igetattr(self, name, context=None): + """inferred getattr""" + if not context: + context = contextmod.InferenceContext() + try: + # avoid recursively inferring the same attr on the same class + if context.push((self._proxied, name)): + return + + # XXX frame should be self._proxied, or not ? + get_attr = self.getattr(name, context, lookupclass=False) + yield from _infer_stmts( + self._wrap_attr(get_attr, context), context, frame=self + ) + except exceptions.AttributeInferenceError as error: + try: + # fallback to class.igetattr since it has some logic to handle + # descriptors + # But only if the _proxied is the Class. + if self._proxied.__class__.__name__ != "ClassDef": + raise exceptions.InferenceError(**vars(error)) from error + attrs = self._proxied.igetattr(name, context, class_context=False) + yield from self._wrap_attr(attrs, context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError(**vars(error)) from error + + def _wrap_attr(self, attrs, context=None): + """wrap bound methods of attrs in a InstanceMethod proxies""" + for attr in attrs: + if isinstance(attr, UnboundMethod): + if _is_property(attr): + yield from attr.infer_call_result(self, context) + else: + yield BoundMethod(attr, self) + elif hasattr(attr, "name") and attr.name == "": + # This is a lambda function defined at class level, + # since its scope is the underlying _proxied class. + # Unfortunately, we can't do an isinstance check here, + # because of the circular dependency between astroid.bases + # and astroid.scoped_nodes. + if attr.statement().scope() == self._proxied: + if attr.args.args and attr.args.args[0].name == "self": + yield BoundMethod(attr, self) + continue + yield attr + else: + yield attr + + def infer_call_result(self, caller, context=None): + """infer what a class instance is returning when called""" + context = contextmod.bind_context_to_node(context, self) + inferred = False + for node in self._proxied.igetattr("__call__", context): + if node is util.Uninferable or not node.callable(): + continue + for res in node.infer_call_result(caller, context): + inferred = True + yield res + if not inferred: + raise exceptions.InferenceError(node=self, caller=caller, context=context) + + +class Instance(BaseInstance): + """A special node representing a class instance.""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.InstanceModel()) + + def __repr__(self): + return "" % ( + self._proxied.root().name, + self._proxied.name, + id(self), + ) + + def __str__(self): + return "Instance of %s.%s" % (self._proxied.root().name, self._proxied.name) + + def callable(self): + try: + self._proxied.getattr("__call__", class_context=False) + return True + except exceptions.AttributeInferenceError: + return False + + def pytype(self): + return self._proxied.qname() + + def display_type(self): + return "Instance of" + + def bool_value(self): + """Infer the truth value for an Instance + + The truth value of an instance is determined by these conditions: + + * if it implements __bool__ on Python 3 or __nonzero__ + on Python 2, then its bool value will be determined by + calling this special method and checking its result. + * when this method is not defined, __len__() is called, if it + is defined, and the object is considered true if its result is + nonzero. If a class defines neither __len__() nor __bool__(), + all its instances are considered true. + """ + context = contextmod.InferenceContext() + context.callcontext = contextmod.CallContext(args=[]) + context.boundnode = self + + try: + result = _infer_method_result_truth(self, BOOL_SPECIAL_METHOD, context) + except (exceptions.InferenceError, exceptions.AttributeInferenceError): + # Fallback to __len__. + try: + result = _infer_method_result_truth(self, "__len__", context) + except (exceptions.AttributeInferenceError, exceptions.InferenceError): + return True + return result + + # This is set in inference.py. + def getitem(self, index, context=None): + pass + + +class UnboundMethod(Proxy): + """a special node representing a method not bound to an instance""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.UnboundMethodModel()) + + def __repr__(self): + frame = self._proxied.parent.frame() + return "<%s %s of %s at 0x%s" % ( + self.__class__.__name__, + self._proxied.name, + frame.qname(), + id(self), + ) + + def implicit_parameters(self): + return 0 + + def is_bound(self): + return False + + def getattr(self, name, context=None): + if name in self.special_attributes: + return [self.special_attributes.lookup(name)] + return self._proxied.getattr(name, context) + + def igetattr(self, name, context=None): + if name in self.special_attributes: + return iter((self.special_attributes.lookup(name),)) + return self._proxied.igetattr(name, context) + + def infer_call_result(self, caller, context): + """ + The boundnode of the regular context with a function called + on ``object.__new__`` will be of type ``object``, + which is incorrect for the argument in general. + If no context is given the ``object.__new__`` call argument will + correctly inferred except when inside a call that requires + the additional context (such as a classmethod) of the boundnode + to determine which class the method was called from + """ + + # If we're unbound method __new__ of builtin object, the result is an + # instance of the class given as first argument. + if ( + self._proxied.name == "__new__" + and self._proxied.parent.frame().qname() == "%s.object" % BUILTINS + ): + if caller.args: + node_context = context.extra_context.get(caller.args[0]) + infer = caller.args[0].infer(context=node_context) + else: + infer = [] + return (Instance(x) if x is not util.Uninferable else x for x in infer) + return self._proxied.infer_call_result(caller, context) + + def bool_value(self): + return True + + +class BoundMethod(UnboundMethod): + """a special node representing a method bound to an instance""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.BoundMethodModel()) + + def __init__(self, proxy, bound): + UnboundMethod.__init__(self, proxy) + self.bound = bound + + def implicit_parameters(self): + return 1 + + def is_bound(self): + return True + + def _infer_type_new_call(self, caller, context): + """Try to infer what type.__new__(mcs, name, bases, attrs) returns. + + In order for such call to be valid, the metaclass needs to be + a subtype of ``type``, the name needs to be a string, the bases + needs to be a tuple of classes + """ + from astroid import node_classes + + # Verify the metaclass + mcs = next(caller.args[0].infer(context=context)) + if mcs.__class__.__name__ != "ClassDef": + # Not a valid first argument. + return None + if not mcs.is_subtype_of("%s.type" % BUILTINS): + # Not a valid metaclass. + return None + + # Verify the name + name = next(caller.args[1].infer(context=context)) + if name.__class__.__name__ != "Const": + # Not a valid name, needs to be a const. + return None + if not isinstance(name.value, str): + # Needs to be a string. + return None + + # Verify the bases + bases = next(caller.args[2].infer(context=context)) + if bases.__class__.__name__ != "Tuple": + # Needs to be a tuple. + return None + inferred_bases = [next(elt.infer(context=context)) for elt in bases.elts] + if any(base.__class__.__name__ != "ClassDef" for base in inferred_bases): + # All the bases needs to be Classes + return None + + # Verify the attributes. + attrs = next(caller.args[3].infer(context=context)) + if attrs.__class__.__name__ != "Dict": + # Needs to be a dictionary. + return None + cls_locals = collections.defaultdict(list) + for key, value in attrs.items: + key = next(key.infer(context=context)) + value = next(value.infer(context=context)) + # Ignore non string keys + if key.__class__.__name__ == "Const" and isinstance(key.value, str): + cls_locals[key.value].append(value) + + # Build the class from now. + cls = mcs.__class__( + name=name.value, + lineno=caller.lineno, + col_offset=caller.col_offset, + parent=caller, + ) + empty = node_classes.Pass() + cls.postinit( + bases=bases.elts, + body=[empty], + decorators=[], + newstyle=True, + metaclass=mcs, + keywords=[], + ) + cls.locals = cls_locals + return cls + + def infer_call_result(self, caller, context=None): + context = contextmod.bind_context_to_node(context, self.bound) + if ( + self.bound.__class__.__name__ == "ClassDef" + and self.bound.name == "type" + and self.name == "__new__" + and len(caller.args) == 4 + ): + # Check if we have a ``type.__new__(mcs, name, bases, attrs)`` call. + new_cls = self._infer_type_new_call(caller, context) + if new_cls: + return iter((new_cls,)) + + return super(BoundMethod, self).infer_call_result(caller, context) + + def bool_value(self): + return True + + +class Generator(BaseInstance): + """a special node representing a generator. + + Proxied class is set once for all in raw_building. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.GeneratorModel()) + + # pylint: disable=super-init-not-called + def __init__(self, parent=None): + self.parent = parent + + def callable(self): + return False + + def pytype(self): + return "%s.generator" % BUILTINS + + def display_type(self): + return "Generator" + + def bool_value(self): + return True + + def __repr__(self): + return "" % ( + self._proxied.name, + self.lineno, + id(self), + ) + + def __str__(self): + return "Generator(%s)" % (self._proxied.name) + + +class AsyncGenerator(Generator): + """Special node representing an async generator""" + + def pytype(self): + return "%s.async_generator" % BUILTINS + + def display_type(self): + return "AsyncGenerator" + + def __repr__(self): + return "" % ( + self._proxied.name, + self.lineno, + id(self), + ) + + def __str__(self): + return "AsyncGenerator(%s)" % (self._proxied.name) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4dfb9c820c89ba05e54a1488081d323f1d719f5e GIT binary patch literal 1083 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_collections.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_collections.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40452990f4758a7e2f1ebcb1980b5f2900f46b65 GIT binary patch literal 2638 zcmbVO&u`l{6qaN=R_vtchM^sHnT`?Q)DE^RT`&*pe)Tl3*m9Y(f}lm(Q$mX>NgKA& zp0>mOjP|l&|B|jd<-XHSd!%H^a#SOj08teAy+`u<$oKf=;bF^y=l4JV`T3x2S%2%F z_0xdL7x2nwP!NmQ%o?U&duUVZ$|25mV^}k_8r15fP8z>i!v@(SP5AB+m+Zs0N$uAz zwXgO`i#FcWZ1D7><+pFZt2OYQn;Lv?>QMNOaCBV{9Kf4Dy7Mb|wSpCuR;0YL((j#C1I5MC>w5zp(amlTp=l^( z7)=m5l9Y`*-ZfqN=Uxo1w}2C>LPe)rKta_^MB78PjICc!npi5qLy|ONEF?|Zh|m`^ zil#icPToaa5Gp7^dg7+-FH7vh(oOO2q8p2Fjuq|BvFMID1F-DIy)L_Ytkmk$(@(DD zz<(T&6SIE}FHRzaxResB20TaK>n$LLSLS z@iKX^*?^S5ksNa|eMd{9HL~pbzJP61sAt2E*3_u?9#n|^3KSIgUs}XDvtC&*Ezqtu zz$>sf?5yPjI*$103P#_MZi*L-Mxa=4ONB5BRW1SOA@GRNzSgzlrAFpw!{qzFdGY8NVC6bl2W@)7V^v}vAgqw;F$LKRb4Pr1rl z3f!2{E^y4_^|Z24OYB_s%6tGkcMN0S#YE64pVN$-Ic76jHEBWTu$@y_;W%qe1;{1y zOA-mL;80}#qy9-@tyfZlBBZIvHq1`kdf-ZIK9S4w^W&2;K?rR}hA<*j@0?1mOy{-- zxfNRssN=nrI|N~b!ODtgv>vk}aE&-;w^pSa4TJg8${ZsU@n}T_{~wkCj}(L!nVEJx zUXa1PFe)F%Exq8_-x?CycF#57@$#0HiL_gG_yPh|X+&*mK*b!Z3`;hKY-7~%799`b ztWf=4$Ai<_?-hQ^rx^&LB0uvTF9cwPT9}Z6H}wk@)v)l6xan-IJ;<=b-5qh_Z8+af z>d$`q=+w7|_eWULEYF!BU!*jlFCn4{#fR`pb0ztpZr5$c-Lp-5ejT`LLRnoHY0_-+ zeVR|duD%RFw%>WmHxBpev?REWXGn2Wgk!iSbUe6#sQ$N@$#sCsSoj!NcxYHCCHP7* zTp;3UPDb63VFMYuJ!x;`Wxtiwt* CRp-C} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_curses.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_curses.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9f0f69e910fef83fe1d5df7ccaf22d9b9be6747 GIT binary patch literal 3388 zcmZu!y>Ht_6sIgZG16w}*3m;34~gsstrMUrdOV&i!bcu^kMxI7K#(KGP%6s`sRT)v zEFJnsbV#P6|B}}ZMfXmf`i`>Adv_vWn(ue--uHWV3Lidv5a9FMAOHUJ_vbClX`Of|g7|J+3vS}qFi;UvLqT=*8 z2Aj^AjJXA*N+(QOK&DkLxUEo&V}UkUJdm?AQiaV_q><2Qnaws(Iv%PNRa$$c=-d0G zICXunwGlNUVoFABf}2%J3M>C+ znM=WF9E55^XE=nS@}W-GVp`kBHL^wGP&>k+m?g@JqET=tek|;B z8=(QcEFdD8negr4FdL<>Qu?x_CkM|>p<7_)R&gUBrBQ3dx15kjOS`)v&2D82C;Rb zuDH&Gv~Q^9TE4q+eScgptE=hcdTTMR>hjN^+Qe&o^ZKvuEvo6;@v`i_9ap`VSF=f3 zA-30>y?VM_{_^abZ-1^Y4)z!Cmj|y$lj{8G9zGZIUfx?w7mud%dO4oW9-Y_Yi~4eJ z+Pl$o_y4>aPv^bnJ$ms5mDi6K@2|hO`5rB+@w|R{RbAdQKQ7EG=xlxnb}REaytmr1 zyIE}@xx&7z%8O~eEUVGw)#S~r9F^~uHYo6u0wn3DuQWhylTpv8me2F+d9f#1$bXZUCkTDazHp;9g>fXQ!pNmVrN` zOo)FeD-$~t6VJ(|Jj>7T{q+3v`|!#3_7*|;_T$gT2QDGMtTTv*#!KAVDn?SmD051h zQas(#sod19ywsx>_e#GSr6aU`Hu_4^fP36!0S~TR#GLme4%hc*+JF))`lQrKM@t0} z%MEXgD1YM%WF9+h@OCzzy?Onvy$8Gy+HlA!#hQ|5{EOj|afoSqdqZ^6h!T-gdwCEa zjaRt!T~vk`dPT1t<6e7=e#eE0IPLQ0i$4|Q}mI}COK;BSIY+aUMFYZEOA8a$hL6we?RmdV+*zDWTU||=K z*X@XL#-;g5Ah5Ak{cVyO#5s~B=Q$)xWy{q`Jx$89V`J7&9z9;^;^<+0X^uW;3>L>z zltLySl3LV5l-g|4O|$@>A^oD0Z>OgfznqnOl}?VZ8N4CGSdq^ey^M~_eu z8dA@PTWGC!hPX-BGl;`B$TFr*vkdGY(qQvqS2^GZBk9ftnsoJZ=sRQS{@2}GA!2R# Vte^i2>uLL0JtuT_>DUd&{{ZQyzUu%0 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0ad4863dc775426f84a70ea72dbbf2771379458 GIT binary patch literal 1585 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_gi.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_gi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82fb5f082fae6e664b00b5c7335c0ffcd6c2a54c GIT binary patch literal 4027 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb9ec3f5ac9c2fdb6bc64fc1d701329a0b471575 GIT binary patch literal 1944 zcmd57%WfMtkmNqJR&A$AogjT27DfVj3&pbJN8G?NlA@1Oji4n3*jL2 zr`}vF3y7!i6NdmOqBug09ODMg_M|}=>KT+ATMd&M)I38Ci;=0#NUuOGX3Y!?dfy<= zJ_j4<$RpZ=r2gqu)~DRWG}6_E@vPggKp0D7ByN)I=n_+ z-?(6VkkUZ1xgXh6uHN5er#HG#D$NZ(O?i?sE{6*j=pbC<$~;2+2JL2)w2pldj;^y& zy+Jv5`oFc6(Wkr06y2bzY=E`ePL6l?GQ7Q??{}-U(H{`5px!K%%I?Qycj1Qm-cH#) zX2YB(f=K3+E{Mei@exU!^V&h23}n3uhFB`Qnuu7?&OEMfmEAa@%um{F!KB{)du8lg z6S!d#^g1o3DkUM66wYGmj z)^_(iq6*Cj&TGvJLMYUNKFyY%C3>!G!%vg}jL{DdUcl^_kk>E~BoNgex z?Lpk)ci~PCD@U?^8bKTWhTh6b%EJ?&D<=W3w3CQJy;RbzO4Qqza`egW-m&OBuBJoz z_@z&IbAJm~C$4;3NyGF}7z-Ih(W9maI-v zbXd$zQ+~LwV?h9z_UPe-h%b2%i*~~Mn+MR4P*8`Pml~d5+2HKU-+*8K^@NrV&nEagIABl!qIBX zUitqRQH5*>Gr>R1V$44P#6JR{?p%GT|8pxX)Q96cReLpU^?Xe0C~X49RU2 jzIt}_?90!;&OBWJnX}G8E`F%%ROr89hv=_pI6Hp>c>f|3 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_http.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_http.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ce43fc4efb64c9240002c6722b610eaec644b6a GIT binary patch literal 3495 zcmai1&2rl|5GG~WQk}TDb$aC0hgfcB+N3i{rZfpj7*hm8g8tET29ZtLrmMe@blUjZ z9{K=%0O!={E9u%(?>+U@#gbA)NJ{AuN$-B&Vt27vfJb|KyBb`-{qfHazwc?!SmOlwCjR~0-;&PQamm|z40pW8=6|erSRkMo;YWw1pI!j>AsX;aBww+r^4Dj~t~*p)KqI zQipJyMO^U^D7A2zZ;Dq=_$DYCEAuZn?GY9#^Pnh^0NtVOP_;1TQiODvt3)9ssB(zg z;oS}1DoP}HP=w62sqAH{7~3u%bp%i4|SgmxwQ*H9L0jfAzNkj0P!e$G!{u zXF&WDut;dBBUrP@x`A&}}Y=0UM@ScK{%R8$C-A(AsVgV`!}SyMm>KV|;$rWRk# zkNasb8rL#~?_?*WyB+*k{c={yG0C9ZY9CQ5?nN{7)@y z01uMs8_*rXu*c#qG&-455zWMgY?E2YP)A#waw<1a}o*%+> zJ#O*VG?_k4##ufX4xe6RgX?T`n6ye?7Ek=%XyIMRbN|8g{p<<8i98*QGx!D>!H18Q z?Z8dbclG+q^fP$7e}w4EVFC{CH)jnYqRFKYsr=$dx8T-)QjT?iVa6$D1Ihg_)A%~c t@;DX6$Bcjs#AApotxNhM`r@q#vRU&*0evMM$>djAU2oQ!`s1yp{U05N;B5c^ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_io.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_io.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d84d46e9d3c5078eb937e966357e9fc7c3100e2 GIT binary patch literal 1325 zcmb7DPfrvv6mO@qvjZ%+AZRomCSD9g7&K8ZAw)nh9$XW|kW5S_ooRRJGJn>#fRN?p z!HeGkPR1|c2brrU&wBFY>kP01s1CXggJrDNKj*S=6*nd!-m)}%yl-x8Zf&YcZW`f0Y|vY zM%ma0bV@K9*sZf`=ex{$ji#GN4_B0yxnN!-smQz?k!j_%bLpu(R!9eC1=}GXf7}0O->oeqg(vFe(`Es(q0clXG0|X#jBVYZ5YO3 zvtEN=-3QR9i%%?uPw_G7lfHEe9ov2Tgq)(|TEEu8eblx4cnOun$x&-d(o6x1py~p)3u^btAG^smn*H6 z=j)rnB`-=V5d*f6MQQ-fU?tNoFHOJ1U(Q{+UOA<}%fOiQx2H@35E(J3Ql3#2| zinPocOVbgh(-m9;vABIfA=FSrhSWh-Mz`Ty8C6u16M+9ihDdsF8585f6-=%VFsWSO z>@HldC}27HF9k!btZ3sGR4meX*MV5z*4fL2yZUBhV|{b|*%eQ^O9@RQMwjn_g&*)E zc>~}tM=yKDwDX@=qzx*UKTujT{U&dkJB^|qhAfZ6P}a@nlmVkHO<2k-RrxZ}F8!6J zB7zCYJ3>LR^6qleU?q$7Etd8GOSuz%h@4seIQvI0-(GN?aR<%ofjnOes@fg1gq||(PZ@W$@A3>gqbiF zFt0RkB;@ekg5rP)T^)>!MJ@Qa5z--3&%F|t8+q)OIdIAnOE2lCfYZ;^y%J28KcZ+V znKAJg^*aN2tcwen+T>moJK<2qx(0P@K$e5JK{<#yv+Th{D;UI9RG=HX_O=YqLa+_0 z*x&gpO0M)=7-9cYG^wXd=B1FZ4d_k9D)>h#Q4*q`3tg|&GN$c>?^^xKk@3< zJgrg8nT2%DFfFxjsY&Z$Dlg8hUEaNY=Z%@2-K-b(>}}4mI3GHhsq|%9i~2+;W0{mE zg<&&O4MoZ}v)SzhGNID7&MTO{W=bsKv|g;P@4Vb1Q>N5d^<6^7CrxPY8g|{D?d`5j wl1|p$hF=$je%RUJ7CK#*2DmBObN>{%u{sW0_3m#z)WbdJ84n%N{jhiR8w7011ONa4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9d848dce0e0a7f7d1866ad6198e9860c24e64f3 GIT binary patch literal 2601 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%0D+w{I=J7A#(SbK%C_cW%G25L~}@ zXMt|-fFEd<%2o(whJ4UP{1~;lE ztkj7FwkgrqD6mtlJ?ZBbO`PdQGLw&ojLk>Q_bqsFZ z-gc9`$iX$5=ox}Lbl`4}z}*(%Xk+DQh23$KD^48wNj#k7@O)0>w@13Jp27gUqafVR zH8He3!mhoDFu;jNX>``_#$)j~-ZLSF;Z$>pn-s*zm)11VHv+~WzN>X2Yn|BDI+?XjUeY$tBnWBlo#+(%b0tO9pA^~6pMOt_4<+U*R07*S z)xPjO-2AJsKdcdHj?)`hVwM9^;Y`un&sFNJri{JiW~~--un_%Z@Mf;R@u>|{1;M)6 zHfDE+3j6ps0r^&$X6D}@*Cn&G2;r2SqWf~(^%T^+M^5DhwEZ)# zu8%vTY!g!#@ahIahOU=uzfYFo0S)SSm%Wy3!brwjGqrMkNtC@PtgT$+^8E)$G{Vh` zqH}N7gDbdv?pm!ve65IsMd_5AOIg`N~($HjnHs*Mpa9aJMbniC`Xjm%n*-CY6{|| z4C4(6^aZVRK|mvdfSToVI%e83ML+B<68JP7N;m4QNh6MrYK``qf z$GnW|$@idt_v4CkCNOi&OyMk+klj;~7?q+Y=OUW>lm)9{jM-^$5FD^drc(8}8H)nE z8ng2}$iZlbQd==Eb$k01rNu#NRC1TkSeoVnVoT}--QXgRlncpSgwTTmQ2D1ct0kMw zn4P7})aM`k150L)WewT`OP{7H7OOhNWi#-(N4%Im_8Gl0i{~mqO zMHHGbfyiV6amN^bk0B0m4GS^Ilwlz*arF_y88r+8eFkEdX~Zz}&(%*DQsC*HN|QR1 zT_Xabzd%8e37m@_>kr|%H}A&)bI5(%`v8g#mli9KM@uYnDab89jIC|JHamI*(1w5; zVII}C?H!HoxAP+FNeF+b!qJ)2u$YMnXJKqR^c?bnBQXDkL>Yg3u}2(*Otd2rU6i}S z-b@pav90ZBttqlLYrCvXst1hORibhYrYy6xslL3Qo&7D%O0TfA_7A^XV)ik-Eb%hL z6m2s&D-fy@x+52;_>c!!zZVwf%HcT3QusZ{}R>i zd2Bw=b-wp{>d71d(cPb2S!e226q0H`XpdZ%jBj5dd6%H~gN5U2H*)H6koJ)Nh?68b zdp)S?Rb@u&KBD#Q^RnRm0Ta`zR1VmEYxYL9sy@6`n%+_^!X175C#Ke9%gtGh(x+4dL zW*DArOzEv{azfB`IF%pr; zjv9R*(F)>~*cR|;-J>T&EAOtqvZ~?830OO#lswYyTnx-TE>vCM5MNTg3Pc>JYN1+0 z%dfik+rt=Zt$#)L9jh^wJvD+c)Hb@RcPx=ZlHZ^0_dMGeW*Wz+->JLmSUiEd|Bff| z)L3;4-q&9Ly{ZHAcd52Lg?HJYGr##OinH$h4Y2Y)v%k>g&7=??$;P>l^_PLJ$4BF1NcoQ^1w4W0;oDvOo=Du_#HI&Mo+O^#n<4-J z*t-jSW~hqz4Cs4}(D&_AiM##O4&J9z8{i2b@^r##T+-HGc~85ot-EL=9BZik)V?tS zka)5R(VQo*VuO1-4s*cKCkJ>ZaDxDEY7mqyY6s%RzI!c-Dyxk}$^sP}&uHcztHdef z1qf3&)XOkG4LW*j@osSQjccz3*KXXn zb@$d=i@}=RU< zB;>vo#r4=f#GVqQBT4P^%^xD5pu55i8t$;PK~m&0Zc|&mb&rUrV|~Y)d2Nz+0$Ma< z%yf_fjvy600$AEWl1QhS6Z#lV_6fA6`w{wQxcGu;q!keF_~z)H;+i6BN;F;Gz; zkvOQwU2gLf%#p+9Xrf~$Hq243T1ad%N9%urBoXFuB})_AXKzus;g!8;V@WAxbH#%= z?*8m#m#raUDZOU!ijRPf3|borLaJu>?2NgLbnHAHP>4lLHQE;?+REtog>s`&W>d6h zU-;0BBCX!3Py0o+Q;Nz#Se+LzV2OIif$eu#{|F2j1T4J_&?G@qUv==X{_PB#Cc1xG zc4oZ?3VT6axo=6Id%$d-q1D`_`jGqu)%%LU5C&<7iV_)w5p>(8g0*%DHGCLzof;^% z^v8R=h%&S%wU+7I7YZW%DMBm>Y!OOK)q%_}>FGV8CCs<5J z=;Y-u(Y{MWDGp^3#kXzR)`U8HA=sWoGy~gBfbGv^r`o-9Zy*$iClF(p@)Dhfj<=pQjc z;V~(f7Ed6@=PzPPZu?AEd7e<1nYp>Sl1HG`+&*7%ea-T5798aiqMe(0(3vfg0Rk?MNU3rWe=o^r}8v527ICfNLurE;$ zo8V2Vk;!9&u0)ok72?@TU=#qy$cl;6YbE@Qw(JqV!v~1pLlQi)2bu-&4Hl6O{w#xz z2an*g&^Ez`f|h=SS^?1UmsE!QD?HOPMVO_3Oh$4{Fbuw&qRr)#8a@Rv4*R1kyI2|mGK3V?o{ zYJ3iu$9Xl9;F>=@aBetYuKlsWb_yl^lY=c!*mnk98H?jYSZ>j)$d|IUV(IWFWVi~! z29|_xD;p6V7Wo!|Y4RsDurH!qV}RJXRBwunT6l$wb3|s`f?J1Uhd7d(Cv>=IIvEa3 tSg>t5!_Kt(Q>Wk**zKF{MQ7Z7*)p94_mF$mLSQfj!6mURT6AaW{|oWl$=m<{ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_nose.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_nose.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b34da063bf18de12547cf702b6f44904f3cc9d35 GIT binary patch literal 2067 zcmaJ?L2uhO6ecBER%AO#v#e1~+HRc#73|V{TG{^Vtf>RbFQewtPl#l^HLIw=&uIE=`BB z*-J$;NhNQ_QAdR0wDlJRN%kkz8*jF6`G;QDKph&67W7@{auq~QXZj{*Bqww9Y3_F^ ztYgE`g#Hq`TnE8uPG)2dAHPawbWS$F1P2Nl2;A!#h20nFIFm&sPTz6i(SnZtAOf-b z_o$tT=r~loeH@B*FO3-&vYp*-$AkMyO}_r>?ojsc-N{bXy`zAM&i&ia`bqm$JBzYg zQ6g0s$G18%?90*Zs2xfr(ugfaxObGawG0r7R(4uATX8t*u<#)U|2K3p*$6V8-EVEh zX*Z1JLzt91AXHP1J8%Un2}j(wx?v`D;H9X-;i94se+E;j0i~i2^DcDV5Llp%UXU}G zC_qUWGoZvAep7O~uB^O7uQDg^>6E@E$z_Wudr%#^;sFK7;c3m6Z+tgQc0vtT`1qtDrWlid@xj27b)kRQ9Z%8#$dDJ>v)Pf)-{E4e^*&FWQbCzt&&z zoXO26Ts6a_87VG81vE-~O$0!~B5QWiF~|{DZ&M~)lb_rsv}ly2LN&)pq!gFR)r;LY zl(P8>^cx=xE!1{H$-M`93!cqjmsY~&H|1_ms|5}B3mc4FD1q4ewNlwT8i%ppD3ySt zCcQ@C1Uuh9efDVYMNtPHL`gsBjH8$pj^Zckod~nSW}NXv!E?fjUx|_)7e)1)HU9Eb z)Oph7dqSjOIKQK)!M6(+xF(c*7pb@Uh5gzN0`Xkq;8}$|O4&HpB#|66ygZ51~8Y-%-on$ zV62$~Ya#N@*HDa@b(IXPsimNZ0;}n?l3RHtfSy}HHOHG(CO3D-Ql+EjA~szK)myHs zVM_zvEFY^isRsd6kRSl&y*c#FbQnO9J_?HJ`MT$b6$n{iS=7J-A+wAptgy2XxS|A> z5#M?iNmW#i!+6X++qa||cYv+n8Mj1SimT`V@$_9>2JS}vq@1Un0q?4dIDhdeKfuRv z6vn~gPItkRF2BTZsbj1HH|mxP(uSY-60DOoUGemFTj%E&tij5R8MTXU@c#`M0+oD- z#opMTxF3&tRMQ`;c5)#^fpzT}bg_g2HSZE4$I@;P6o%m95*jo@E9Y6((m9D~cRul# zx67)%gUQN;Uwyv4zx`zIg$BN;cGFQ7#a!o{egVxceMSF@;C%p|i=ceZ0MZ)X2Ar%d vEDOjA`?=20Pi}$K6uOE#TcwAGcnh6?mf--f*q6;U%h_})&YDH*hE4wihJFl( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_numpy.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_numpy.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60b2d51d9451571860d78557a17a4f7bba1e2810 GIT binary patch literal 20290 zcmeHP-ESnvao<@kc|1xw>GWZp92=M*25u>=`K3GF9U%&lWh(*f(20HU17Ty(JJY*6 z$N5tC440&N@Ph={hT%UTZ_-N)|116zn8&~mc@Og7C;zH@W_Fglv+P;r5G4=+?#^~s zS65Y6S9Moc&-Y$=Wut|^-~8dfe*V3GZnge{eiVPV@$mQfmw&>C*E()_me&rfV@rLv zkK5jg*ZHhI0dk_md%EIJ)>p#J1>&T_g;%@~HAK_n;pwiao z;Qk8>SlUPIcPQGh@#pb@-RCLmvYy@V+0wt@hevV5HxF#V(@aEm7WvVD3)T<#q=g^F zq0fSD)Uy-wR_7^~-GE2KbhH@1JM!fx856wg4UEydqu6&jF;a5T0~1NWTz>deWE`{_ z@aFl#cSiwFyDUgXRcwoC=4T1y7NsN>>9T+y?r!Z=Xj$BP08TNGJ=+_298xV=Sln#L z!jN_4h$Y~zd9Onrhdc$pUGq^K^3;(jOL_MO(z3A6gKiMJhdW9Tjb$=APq>(n7!Bjt z>)BDC(Whi#5)jj78XGXB2VaJqARhWMg{-~=OTZDuB7};BoJF}{{9(u%DGRVjE__TT z^I;3KAg#{YQx-^L>8Zx2O!ydfr@}zbcH>iHED;~F)Ia4;ze%PmxP%fs2;QT1X)EW2ekv|+MLtGg&7`_zK{qTNp|7J{)X_s;6pjSTR0)D5i>zn%n z8f|X6hSo-~^MHfPB^-g|-0RYZfvb|GDOLt~F(Y!64F&ZoBac-6jN2u&GZL-9Gt7OqI3z)z%W{~#mF!tbs1cn+v47T z6jD0?H6NNR7Ea?R^d-!HnDy)vmL%q@lralD<$FLbIb>t1$K3B{LD0Z9T=>br5PY+J zb&KhR?bRymqU3*Ui4In+>fJWS~AWM?~g_Bc&1o;=(?k;6y3 z$$9$d6UP(%$2<5NM%z!f6F>Q`A7QYA;JbavhBDmoxAUIL@4jGuw5>iJy_inUufDCG z95P&({vq5>;yY4Bd9Wi=7lvO2qB4d3O;+rp1k{HvAsH}K$D&-LoN{j7c2@>YJY zSK*zbiyy^Vnj6CLh>K#C>ViN&8Xn$<(c#XCA9?qCb}Yd3;r$=tQCmt{rDOE6ete=< zw=4otYK8uH_D3=C9HmnI=JuhzxAkcE@!n(lfAH|h&Vz@#CJVT5)U*T4&ep?6kM?#S z?(aW%va|c}y}c(JIliOVhK;ueS>%%U(P(MwfW;seBJMw{Sq$dwe;n}|1TbMa0{u1L zhSj05$9_7p-mff?S{Y!v2RCges&+nnw3+Xna#*L&8pWLt` zv}xWEhP81=Xw$GGw=dFW-MDe|ta*zJD?+%WCW6C|He|-*!#%;gX5FBX;4ra`XoK_H zYuqB-ZPsMK`VGk%2oTn+6JHMe$Zt9}K2&sWk=#%D{lcH`t+>tJK5J^$4A;K&*`%ng-u z>M|WG&$^s-DE#tL^SfxgoOOWC`(YL?!7|i-$(9j6OW9yKEymKtS=PENYgYshv6aR~ zbqOh{Aj;Cy0Q+EU&fR5Z5IiDZ&K7Q3$Lqz;a&twrvDp`N=ytV6F#?vN-pi>% zIpODHY~^V)nuUmF%So6+P}Jb+n>y~`#)3N;aEvBFhaaF`uH&QC?yPkFrDF;DQ3f8U zf_hhhhuI^)f9#gw0nZ=cL=U~&6myky2&g!R*gUDro6FVF(WH>@BK?sa$ww@x)K!JCk5<_sDLC40p z-M}}-8;6M?Pj4m-6^tsG!5iq2 z2L?^i0@QT$2EOq`Ro2ar1i+fkCIU^l=}bisc;IuKE0~QPnN?Fz7}*A(2qrgyhV?cC zH#c!~tZ$0c*c574Vu%(8t)?=I_?VoOI$AKr9!D2k#D>rfrhk%}PNgI>9c95zk%3~S zmE>}bK@)5(je%8mjybfsR*E=7h{cRO$#JqVB8RGumrWJ{m`zQlHG$Jw%akC>Su%w+ zmq~*q12W7wH#Pw>H5RpAf|>GW?DJ?D!p?9cVK(9^J291S8mqOcDdHFo${cloq$y*} zw0uRN)sRDM_>AeGliS36ZH9wpLn=;vK3)K-k5Kg%N*&x9ZJ@Bp>e(znc>C~UBx>QH zmx7b}dEUNCfzp1mcGs|Qe^q*c+UD+viP}nRINbVLWkkvy32iZoKN{vOWi)D0kC@aO z&RPgxD(1Nd-O1c~0r;|?`IG~<08^y$)9L|k+Vjy_eQj%GTC#;3*$Bt|wXLbLUWnMX z*S1vtr@l6=A2|e7l*-mNuI{|2wwg053uJ8av6Ck;{B%K%7wHCVRviZiV|hSf{)V+W zvnXW=NmoX5E6tCT1T3h|-bfLD+Kyy*V%jTso=YZ)57 zH2(h`3+QLkW9O8DPkR@mjmwzxlaR@i!~47Rx3hy>@KGH2z$5e9B2zmSwY@F?YFEew z)&fAG(D4df7di8B@3Whq{bHe-;3&8P(U0T6sjtSiw2x$fvUy3KUNhgc!y{$LBPU4Z zN&S%TKbRoXv{ZM2r??o~Er_mc$8>K~C)DcBQqO+(U7a&t0j5rs2^V1!F>|9JM$UV*4gf+|3j zQluN4QMN`w!z`7U{m3Rr1tMPsSJy}l5#Ur8GStEld4@gvJl~XG?sxDTthI%hA2HZvI_Ny((Z98H2hw zKgMKM(GCi*=JKD1)ffhIv4HK_>gn15nagd8D{u_d*O)6PotT82C4gRIZWa_6clU9V zts>W1AjQFx{gS6y2%vd<6P64>@9o`8J;6P`8O)&wn}>XyE`7|Bl(WA3WbbAvkp1*{ zkTQtu23cq(ZU7<{Al4fPN(mM+DU_w2i@nF!xuCeW(%jib3LW~dM+^GuSXGWl2mO?Y zVZ=fn#^Ri!`MMIG?JuKX=`2!tXGjw*A#ID^APVKFj$8rW52&M6P# zXgJg8$)3hWmDd{;TI3*ZG-4jhpRVdfXCtc+H>B9peT|enz%Ac>5 z$`Q5zn!udvQj)5loO4|`LwDXG+ynJS?n?MZ zkVf2gGojKrBN|u;8!2LV35kbghN>DDUml}@b=Y;~{|Ymy6^DrhQ@P{S$?ElW+P zGmERrM+M)URwZ6Nv}&SE!Lu5OpS z9p9ZH3($~oW&Y>{V2ApVPT-&5T^ni|6*BuX=@V&9>yDrs$S!`XKPsciM_MKC;p4LP zto7TL*ZFm8fHxm`E1%tdZe7y5e^%LBg+6^~j|J|IbAgMplt}_jz!@0s{Re>qMZ)_+ z;1knP?14j6gY#Uii0Z8xO`$q_Ji;4v=AeUV$pWC`HZlmHZd_ZFh00V67%Q(IK_hWW zr7{JgmDg!;0sCi@hP`|guDuZ zwx4EL+Ls8l6{OZv+Ci!%>Hjl<3jgKy`?TXfOT-7aAyQ=lJ67Ae_}R2N zBWL`Y!fm~e_o*P?;e)N2DkoRg2}s$A>V9+Oc#TG$i>q5me@$_7;`m!xR4CePUz^s| zJv~yhb($eH9p9;?q)oih)&JJ&MtjY=_~?ItJG`6g2!!38=@cIK4tf&gDm1^Ac#EDD zk=mj=g*wkN^xtGT6s;R;?K>|EvJs`aliJh2@bEx6WXeUcpH@kC2!*S z+Q46J!f>efEL}5Pvjp8O6r*KrSmGVvI$jT;YPf01FYYNxZqe#ttK^BoF;}bVnE&GS z3IOh>BCSAPyjCew7bh;>&?Wj64qN&a4i|4%!0=dJb~s*D6{PmBUfpsWFLoVA+wT-x z0jU=}BtmuTLakPmOIMayi$}3>>z_V6`tToq@RQ@$1*aEA!K9Y2jW~Yk5l4$6zLAl`_eR#cM@HQ4L#Yp4%s!6f(b(P^(+>nrQ~>px$orPTZD8|!!1 Y|7K%#&7x`7v0m=zr`J~S+%EqA3PKy-F#rGn literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47855af32e33d3950eaafeae311160ef1c5c9df7 GIT binary patch literal 2209 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_re.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_re.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3bab01e71f313fc3d9b2b73261293ee723fd7c4 GIT binary patch literal 1086 zcmZ`&OK;jh5MDoc2!&e@IdbKYn5rsCtG0>(2U#*E0#mhCCCg+NYT{RST@-rmp+6%z zRsBo8_QbuXo;o(LL{N{kGwbjBW<9go>D22r1oq?SpHH7s#KCPZ1f zRGCFSCX^|0OYs+%N%HO0%k~|cUp$Xj$;B53)9GakY#u6>5_|EP7qZ0l{j(`^=PYP> z%Jxq@PO0mKO70y>&f`^Dhv+2K4cRQB!AUkHFs29z@-te6n2MA%E2+d*jAlf7vV@Af zD0IAV7TNO6#~1BfXrEFt_gF%x6GZr{PaJZekPzy(D+AS3``T#V=Vn*Q&a1xJ$lqmC Qnonp|sERdFmaC`#08{)C>;M1& literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_six.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..153a2c4dd0c01514304071cccbcf8d5ecfff14a2 GIT binary patch literal 5541 zcmbtYOK%*<5uTZyeQ@~@NzsyJ!}b79EUhCgR2ZAD`6$FJ9bpn zYf-&Z*ZpePh!#2vQM1#G7CVa?Rs;T0X9@j!XPI4N3#|Fn?5wcG&K0)AmY*7(Rkp&e z;JwCH*&5#KY@J=j`zo(;n{Dvb^NMNc{!2yQzS!VvmnNY0#Y=qY;2OWm*Dry^8oNg8 z`sr(1Qi&vBPCrQo(&;6_k-@POC2Sb-_CK*Pqh)3_#u<-Q%gXAHwsy8YfB04Qvf%rH zR9v_@uFH=Vj~N$0Unz)wIt)UBRI-g}ND%Ko6e1DX%68o2g2z73$Je)%5LLnn#D6OeYW8&E4) zX`-6YQ6HL_qIHX=TAJdX81nWDIK_#YaMMHrIaI;)bqLH_dVf3DMGe2@{SKx>L0x=JiB;g z1I@^|FfK7{nLBi?e8^D@l)&4L{d@qzAqm$$KG*3U;92wiYcw`&R@vUdp z1&r>}d|>?Yl`|ON$T&BJ^UNF>*Nxa389&3K!=L9{A4Ku>8T&A49Beg!D{OpQjvY*?$dxDJT-_qt&;gD6dea@-(k`nx#e zcz^p#=OY@o%VDz@gfJOE^G>rTlE{Hg36&%vJS!)WPxf#EycxvlP+@_7=lJquj2XmO z8#f~_1q#}x@Zx=rzJ3?vqqHO}c$j$1@uZXYia3_z^@g!OBLfKwh7{nAuqs_b68^;`YHABqs7 zv_;ZQ)I_~G)SZHs_&oB0upI>vZ%4RF0<6*M)^L~L?il`pHMn2K({u(?%ciGZu#&>w z+zJA{0JDp;oWmqgiCOGeZaO6N)2W()LQ)D|3}0}0o}Pz%UB-v8>r|F`*% z^Bzj*sP?%}2>>P93OUcYd0{F`RhV^dU7BZxvQ-tZ+6d|O8ET=C>DEV-XxlrdALJ<| zrSHz8^AxNC8hRP-Klukji zhP(af@t0ri?Ftf8P>z-@Nu7qcbQ7}7j=hMZoUwhB6}Im^D+pj`29>MgC(@s;kxWH*`i+hg6bP%6%z0JVQE25OHf{ z%3F#?*6+>VX!Sv5P#kb9W{xbkHZsLuRefX~)XvSb$_VuetNhlwVO%treQ91SP%U$5 zo!KYrBkQ6$0*uve7-!Y5jreujP>X}6_@jxW(=;Z0evVZ18$&IPs%rUQ<=g^?%EgsY z^W7HX@UzFu}uouqt%2uTVGf!Tm9ZeJ%9?@HB@U`)u>e4)wym>^&ISZ`DTyvCa#98gXSA|a7jF>m z64B8Wwwv_CYXn-<(&?Q3I9nLccNX)c#U)6#Acx&tAM;MKLN%02ns(_E!YN2f2aU0^ z4)17c|FEs5`HE?o>lm#9x?$QC@dMzDeTICPiWluOpP(}`4h-332pGqAsefRir25_& zd}L%Q^PqBW$+r$SM&^NiQN1)&ZD5HF25UXsKygK3rn2+dUaOup8TS+6sYFPvEpZdX zGy6WQE3+xf$Cjl_3Xk`*wcYJ++^q)>+(!@hw(ftiwYy6pf(|`f7}J?oz-{E(_;i9Q zY{1swVJyo0slPhD5uQKf@32&oXB)U7ibJ+? z>uoy)IGZ_ygn%vYlVm?@j=~qYoz6v%2fD#CP4SLFwR;@KSyK zb?QaX(s!L8^XXhEKy7{FK>>6ZcGgQMKlXX5i_knKk$QB1$u&tD(wAu-o#=wo9;@wC zOW%2Q`~@(Nvu+VEC=7Jg$CG14bsG2S#(%(jQ_7s&wv7+-0P`^!zPyFTww5d%E~-lv ayV87YR~pNWHycZhYveUe1Qi>9%lt14f2!jE literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18b3cb6e59d941c582b95b5be50ed0527e7686fe GIT binary patch literal 3620 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 RamX`03m&^_>c{rNzW`MI`jh|w literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_threading.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_threading.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..734fa1123b857fbe5cb7e8fafa09c4aa4b7ba0ef GIT binary patch literal 706 zcmah{zi$&U6!zUEBvdLAV(EB8haO6BIzS6*QA>qbAOm!YkWRky%i+|yyFU9O%FMu@ z(M}cr(ydJFOf2y1q^0e`ll=Ui{eAD3{c3%Ejgfr2{Ppoq$k-3(TuGOV16pR2lw>l{ zY{FzHqpxfd06PzX%_7->;35j>_5(}0KMBdkxzkq?k#R)JxI~tn2Qs*D*l;Z3fU&ih zB-g^2SXcSUR+Y^lx5*2C?(QT^W09XW3SrBDo(|&70aaP-A7cZ9*s3{Hjolw^-(Wdr zO+jykLC_$~GR*(5X$qwUOjDoq4jREWSjH~@tpr5+tn7+2h#w0q%pIyP%9C7UZ(Ykb z5Uap`5{XA8VcQeNVx?r;tpytR&agwH^y>G5*Qgf40$&K^(@IM~!|M^(vt4VyJb(J^ z#1uQ*^_kr{O(kZ#Ba))z$GlecP?g3Ct%sQrg_(~OUuC-9GZd=iUZ?gGf{--#C-qtT zaOI{JMQNrL&fW7GR~QRA5AYuC?fq*?(n0!N%pXrS5DI17aOah5G|Rx-V*+@N1o5rkNS`P0w3bFv;Y7A literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_typing.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_typing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85ff1cf51af19a477e2c4bfa30b0ecd4f0565e9a GIT binary patch literal 2357 zcmZ`)OLG%P5Z>9Rw3g*31}aY2Bvj(1z;aR*AXGvjgG{-=DhCS!o20hZnvuNrN?K+| z1}Sz9m;)F7gPcQB`AbvWa^jv7m!x~OmNBl3z4Q3GXQrpSzt-~jxUE2Y_2)l7zk%7` zxHxJCOm4xK{0<#eJcSafM#Lj9YLVK~JgudBddu*Pmg$)-%d=WJFGm!rQ)5f@^3y-{@$g9Qi!hc3 zf{84Sc2zjsHJ=G2^25-WdUJ zCfNa}w=TGLX27pY`wJ~FA~olGG$+%J!92T8(5KK;_%!%#!QlaXeF<8#U8;_BTP&`3U^qB;=sTHzr+1Ddxonoz`UdYokC1fAa?rkX;|0M zzu1tPNZi!VuVB)f6X9VdW}7=%N#}sZ%wmk*iGSK7gFQ?KdL2AO6H(bRF%w; zNpemt5FH|{tFxp?xC4?AkMQ~U!Zf}sFu~{wh%Rtt4*abNJ!Q}kH2}Q~sCfdl09_V2 z!1D*dsUffW_iDW7h>p_;n_bSFPFFZ#1A?{D-AwA>8Q~yPoJ*~+xg{<+n+#;|WN_UT z&LW@-g+iLCuDCYOgK;S>`8dvs(8*%v*R{&pa^=AW$4up8D9Mkmk@Nm(E{sl=#%>UG znM;N-K*Aoontu+@a_ma*;d>#a5ctd>)lPMv;-kQ7Byfy+lrr`2;mi z`czJxNM9_g_dqK_Elk+yG+~R7tn-AsfVrfK|7WG;`?OQ{eQ6FK;8|HI(C3 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9393ff7b6105dfef1e0cbcc76a437a10e8058ede GIT binary patch literal 649 zcmY*Xy>HV%6u%EUc2F`vHzteCL+c;`EmBkwQiK@D0CcgCtc&mBI63>AyGx};9Xqh_ zKeQ9#U-HVt3=`0Q zh|bU7oJE!5TPcpd0}6_98@!#&Ca+(;1Jkb+7beFp0_3y@JOwrnL0GiH9A6<$K9d6U zif}rHRsqtRX_pQ~dJWT}wk<7d8&gf;HT9>eHn#0al{0A|$#Y0wkq#mHYm+p(ykJ%& z7fdG$CArWhX-0`$omjhj{`A?}6vvO7OMAS@xSpSkfQmZ#kThj;SVCnc<>B10!c?O& zVf)el>bYiRopdtWZcBdDT( +# Copyright (c) 2014-2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Rene Zhang +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for various builtins.""" + +from functools import partial +from textwrap import dedent + +import six +from astroid import ( + MANAGER, + Instance, + UseInferenceDefault, + AttributeInferenceError, + inference_tip, + InferenceError, + NameInferenceError, + AstroidTypeError, + MroError, +) +from astroid import arguments +from astroid.builder import AstroidBuilder +from astroid import helpers +from astroid import nodes +from astroid import objects +from astroid import scoped_nodes +from astroid import util + + +OBJECT_DUNDER_NEW = "object.__new__" + + +def _extend_str(class_node, rvalue): + """function to extend builtin str/unicode class""" + code = dedent( + """ + class whatever(object): + def join(self, iterable): + return {rvalue} + def replace(self, old, new, count=None): + return {rvalue} + def format(self, *args, **kwargs): + return {rvalue} + def encode(self, encoding='ascii', errors=None): + return '' + def decode(self, encoding='ascii', errors=None): + return u'' + def capitalize(self): + return {rvalue} + def title(self): + return {rvalue} + def lower(self): + return {rvalue} + def upper(self): + return {rvalue} + def swapcase(self): + return {rvalue} + def index(self, sub, start=None, end=None): + return 0 + def find(self, sub, start=None, end=None): + return 0 + def count(self, sub, start=None, end=None): + return 0 + def strip(self, chars=None): + return {rvalue} + def lstrip(self, chars=None): + return {rvalue} + def rstrip(self, chars=None): + return {rvalue} + def rjust(self, width, fillchar=None): + return {rvalue} + def center(self, width, fillchar=None): + return {rvalue} + def ljust(self, width, fillchar=None): + return {rvalue} + """ + ) + code = code.format(rvalue=rvalue) + fake = AstroidBuilder(MANAGER).string_build(code)["whatever"] + for method in fake.mymethods(): + method.parent = class_node + method.lineno = None + method.col_offset = None + if "__class__" in method.locals: + method.locals["__class__"] = [class_node] + class_node.locals[method.name] = [method] + method.parent = class_node + + +def _extend_builtins(class_transforms): + builtin_ast = MANAGER.builtins_module + for class_name, transform in class_transforms.items(): + transform(builtin_ast[class_name]) + + +_extend_builtins( + { + "bytes": partial(_extend_str, rvalue="b''"), + "str": partial(_extend_str, rvalue="''"), + } +) + + +def _builtin_filter_predicate(node, builtin_name): + if isinstance(node.func, nodes.Name) and node.func.name == builtin_name: + return True + if isinstance(node.func, nodes.Attribute): + return ( + node.func.attrname == "fromkeys" + and isinstance(node.func.expr, nodes.Name) + and node.func.expr.name == "dict" + ) + return False + + +def register_builtin_transform(transform, builtin_name): + """Register a new transform function for the given *builtin_name*. + + The transform function must accept two parameters, a node and + an optional context. + """ + + def _transform_wrapper(node, context=None): + result = transform(node, context=context) + if result: + if not result.parent: + # Let the transformation function determine + # the parent for its result. Otherwise, + # we set it to be the node we transformed from. + result.parent = node + + if result.lineno is None: + result.lineno = node.lineno + if result.col_offset is None: + result.col_offset = node.col_offset + return iter([result]) + + MANAGER.register_transform( + nodes.Call, + inference_tip(_transform_wrapper), + partial(_builtin_filter_predicate, builtin_name=builtin_name), + ) + + +def _generic_inference(node, context, node_type, transform): + args = node.args + if not args: + return node_type() + if len(node.args) > 1: + raise UseInferenceDefault() + + arg, = args + transformed = transform(arg) + if not transformed: + try: + inferred = next(arg.infer(context=context)) + except (InferenceError, StopIteration): + raise UseInferenceDefault() + if inferred is util.Uninferable: + raise UseInferenceDefault() + transformed = transform(inferred) + if not transformed or transformed is util.Uninferable: + raise UseInferenceDefault() + return transformed + + +def _generic_transform(arg, klass, iterables, build_elts): + if isinstance(arg, klass): + return arg + elif isinstance(arg, iterables): + if not all(isinstance(elt, nodes.Const) for elt in arg.elts): + raise UseInferenceDefault() + elts = [elt.value for elt in arg.elts] + elif isinstance(arg, nodes.Dict): + if not all(isinstance(elt[0], nodes.Const) for elt in arg.items): + raise UseInferenceDefault() + elts = [item[0].value for item in arg.items] + elif isinstance(arg, nodes.Const) and isinstance( + arg.value, (six.string_types, six.binary_type) + ): + elts = arg.value + else: + return + return klass.from_constants(elts=build_elts(elts)) + + +def _infer_builtin(node, context, klass=None, iterables=None, build_elts=None): + transform_func = partial( + _generic_transform, klass=klass, iterables=iterables, build_elts=build_elts + ) + + return _generic_inference(node, context, klass, transform_func) + + +# pylint: disable=invalid-name +infer_tuple = partial( + _infer_builtin, + klass=nodes.Tuple, + iterables=( + nodes.List, + nodes.Set, + objects.FrozenSet, + objects.DictItems, + objects.DictKeys, + objects.DictValues, + ), + build_elts=tuple, +) + +infer_list = partial( + _infer_builtin, + klass=nodes.List, + iterables=( + nodes.Tuple, + nodes.Set, + objects.FrozenSet, + objects.DictItems, + objects.DictKeys, + objects.DictValues, + ), + build_elts=list, +) + +infer_set = partial( + _infer_builtin, + klass=nodes.Set, + iterables=(nodes.List, nodes.Tuple, objects.FrozenSet, objects.DictKeys), + build_elts=set, +) + +infer_frozenset = partial( + _infer_builtin, + klass=objects.FrozenSet, + iterables=(nodes.List, nodes.Tuple, nodes.Set, objects.FrozenSet, objects.DictKeys), + build_elts=frozenset, +) + + +def _get_elts(arg, context): + is_iterable = lambda n: isinstance(n, (nodes.List, nodes.Tuple, nodes.Set)) + try: + inferred = next(arg.infer(context)) + except (InferenceError, NameInferenceError): + raise UseInferenceDefault() + if isinstance(inferred, nodes.Dict): + items = inferred.items + elif is_iterable(inferred): + items = [] + for elt in inferred.elts: + # If an item is not a pair of two items, + # then fallback to the default inference. + # Also, take in consideration only hashable items, + # tuples and consts. We are choosing Names as well. + if not is_iterable(elt): + raise UseInferenceDefault() + if len(elt.elts) != 2: + raise UseInferenceDefault() + if not isinstance(elt.elts[0], (nodes.Tuple, nodes.Const, nodes.Name)): + raise UseInferenceDefault() + items.append(tuple(elt.elts)) + else: + raise UseInferenceDefault() + return items + + +def infer_dict(node, context=None): + """Try to infer a dict call to a Dict node. + + The function treats the following cases: + + * dict() + * dict(mapping) + * dict(iterable) + * dict(iterable, **kwargs) + * dict(mapping, **kwargs) + * dict(**kwargs) + + If a case can't be inferred, we'll fallback to default inference. + """ + call = arguments.CallSite.from_call(node) + if call.has_invalid_arguments() or call.has_invalid_keywords(): + raise UseInferenceDefault + + args = call.positional_arguments + kwargs = list(call.keyword_arguments.items()) + + if not args and not kwargs: + # dict() + return nodes.Dict() + elif kwargs and not args: + # dict(a=1, b=2, c=4) + items = [(nodes.Const(key), value) for key, value in kwargs] + elif len(args) == 1 and kwargs: + # dict(some_iterable, b=2, c=4) + elts = _get_elts(args[0], context) + keys = [(nodes.Const(key), value) for key, value in kwargs] + items = elts + keys + elif len(args) == 1: + items = _get_elts(args[0], context) + else: + raise UseInferenceDefault() + + value = nodes.Dict( + col_offset=node.col_offset, lineno=node.lineno, parent=node.parent + ) + value.postinit(items) + return value + + +def infer_super(node, context=None): + """Understand super calls. + + There are some restrictions for what can be understood: + + * unbounded super (one argument form) is not understood. + + * if the super call is not inside a function (classmethod or method), + then the default inference will be used. + + * if the super arguments can't be inferred, the default inference + will be used. + """ + if len(node.args) == 1: + # Ignore unbounded super. + raise UseInferenceDefault + + scope = node.scope() + if not isinstance(scope, nodes.FunctionDef): + # Ignore non-method uses of super. + raise UseInferenceDefault + if scope.type not in ("classmethod", "method"): + # Not interested in staticmethods. + raise UseInferenceDefault + + cls = scoped_nodes.get_wrapping_class(scope) + if not len(node.args): + mro_pointer = cls + # In we are in a classmethod, the interpreter will fill + # automatically the class as the second argument, not an instance. + if scope.type == "classmethod": + mro_type = cls + else: + mro_type = cls.instantiate_class() + else: + try: + mro_pointer = next(node.args[0].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + try: + mro_type = next(node.args[1].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + if mro_pointer is util.Uninferable or mro_type is util.Uninferable: + # No way we could understand this. + raise UseInferenceDefault + + super_obj = objects.Super( + mro_pointer=mro_pointer, mro_type=mro_type, self_class=cls, scope=scope + ) + super_obj.parent = node + return super_obj + + +def _infer_getattr_args(node, context): + if len(node.args) not in (2, 3): + # Not a valid getattr call. + raise UseInferenceDefault + + try: + obj = next(node.args[0].infer(context=context)) + attr = next(node.args[1].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + if obj is util.Uninferable or attr is util.Uninferable: + # If one of the arguments is something we can't infer, + # then also make the result of the getattr call something + # which is unknown. + return util.Uninferable, util.Uninferable + + is_string = isinstance(attr, nodes.Const) and isinstance( + attr.value, six.string_types + ) + if not is_string: + raise UseInferenceDefault + + return obj, attr.value + + +def infer_getattr(node, context=None): + """Understand getattr calls + + If one of the arguments is an Uninferable object, then the + result will be an Uninferable object. Otherwise, the normal attribute + lookup will be done. + """ + obj, attr = _infer_getattr_args(node, context) + if ( + obj is util.Uninferable + or attr is util.Uninferable + or not hasattr(obj, "igetattr") + ): + return util.Uninferable + + try: + return next(obj.igetattr(attr, context=context)) + except (StopIteration, InferenceError, AttributeInferenceError): + if len(node.args) == 3: + # Try to infer the default and return it instead. + try: + return next(node.args[2].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + raise UseInferenceDefault + + +def infer_hasattr(node, context=None): + """Understand hasattr calls + + This always guarantees three possible outcomes for calling + hasattr: Const(False) when we are sure that the object + doesn't have the intended attribute, Const(True) when + we know that the object has the attribute and Uninferable + when we are unsure of the outcome of the function call. + """ + try: + obj, attr = _infer_getattr_args(node, context) + if ( + obj is util.Uninferable + or attr is util.Uninferable + or not hasattr(obj, "getattr") + ): + return util.Uninferable + obj.getattr(attr, context=context) + except UseInferenceDefault: + # Can't infer something from this function call. + return util.Uninferable + except AttributeInferenceError: + # Doesn't have it. + return nodes.Const(False) + return nodes.Const(True) + + +def infer_callable(node, context=None): + """Understand callable calls + + This follows Python's semantics, where an object + is callable if it provides an attribute __call__, + even though that attribute is something which can't be + called. + """ + if len(node.args) != 1: + # Invalid callable call. + raise UseInferenceDefault + + argument = node.args[0] + try: + inferred = next(argument.infer(context=context)) + except InferenceError: + return util.Uninferable + if inferred is util.Uninferable: + return util.Uninferable + return nodes.Const(inferred.callable()) + + +def infer_bool(node, context=None): + """Understand bool calls.""" + if len(node.args) > 1: + # Invalid bool call. + raise UseInferenceDefault + + if not node.args: + return nodes.Const(False) + + argument = node.args[0] + try: + inferred = next(argument.infer(context=context)) + except InferenceError: + return util.Uninferable + if inferred is util.Uninferable: + return util.Uninferable + + bool_value = inferred.bool_value() + if bool_value is util.Uninferable: + return util.Uninferable + return nodes.Const(bool_value) + + +def infer_type(node, context=None): + """Understand the one-argument form of *type*.""" + if len(node.args) != 1: + raise UseInferenceDefault + + return helpers.object_type(node.args[0], context) + + +def infer_slice(node, context=None): + """Understand `slice` calls.""" + args = node.args + if not 0 < len(args) <= 3: + raise UseInferenceDefault + + infer_func = partial(helpers.safe_infer, context=context) + args = [infer_func(arg) for arg in args] + for arg in args: + if not arg or arg is util.Uninferable: + raise UseInferenceDefault + if not isinstance(arg, nodes.Const): + raise UseInferenceDefault + if not isinstance(arg.value, (type(None), int)): + raise UseInferenceDefault + + if len(args) < 3: + # Make sure we have 3 arguments. + args.extend([None] * (3 - len(args))) + + slice_node = nodes.Slice( + lineno=node.lineno, col_offset=node.col_offset, parent=node.parent + ) + slice_node.postinit(*args) + return slice_node + + +def _infer_object__new__decorator(node, context=None): + # Instantiate class immediately + # since that's what @object.__new__ does + return iter((node.instantiate_class(),)) + + +def _infer_object__new__decorator_check(node): + """Predicate before inference_tip + + Check if the given ClassDef has an @object.__new__ decorator + """ + if not node.decorators: + return False + + for decorator in node.decorators.nodes: + if isinstance(decorator, nodes.Attribute): + if decorator.as_string() == OBJECT_DUNDER_NEW: + return True + return False + + +def infer_issubclass(callnode, context=None): + """Infer issubclass() calls + + :param nodes.Call callnode: an `issubclass` call + :param InferenceContext: the context for the inference + :rtype nodes.Const: Boolean Const value of the `issubclass` call + :raises UseInferenceDefault: If the node cannot be inferred + """ + call = arguments.CallSite.from_call(callnode) + if call.keyword_arguments: + # issubclass doesn't support keyword arguments + raise UseInferenceDefault("TypeError: issubclass() takes no keyword arguments") + if len(call.positional_arguments) != 2: + raise UseInferenceDefault( + "Expected two arguments, got {count}".format( + count=len(call.positional_arguments) + ) + ) + # The left hand argument is the obj to be checked + obj_node, class_or_tuple_node = call.positional_arguments + + try: + obj_type = next(obj_node.infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault from exc + if not isinstance(obj_type, nodes.ClassDef): + raise UseInferenceDefault("TypeError: arg 1 must be class") + + # The right hand argument is the class(es) that the given + # object is to be checked against. + try: + class_container = _class_or_tuple_to_container( + class_or_tuple_node, context=context + ) + except InferenceError as exc: + raise UseInferenceDefault from exc + try: + issubclass_bool = helpers.object_issubclass(obj_type, class_container, context) + except AstroidTypeError as exc: + raise UseInferenceDefault("TypeError: " + str(exc)) from exc + except MroError as exc: + raise UseInferenceDefault from exc + return nodes.Const(issubclass_bool) + + +def infer_isinstance(callnode, context=None): + """Infer isinstance calls + + :param nodes.Call callnode: an isinstance call + :param InferenceContext: context for call + (currently unused but is a common interface for inference) + :rtype nodes.Const: Boolean Const value of isinstance call + + :raises UseInferenceDefault: If the node cannot be inferred + """ + call = arguments.CallSite.from_call(callnode) + if call.keyword_arguments: + # isinstance doesn't support keyword arguments + raise UseInferenceDefault("TypeError: isinstance() takes no keyword arguments") + if len(call.positional_arguments) != 2: + raise UseInferenceDefault( + "Expected two arguments, got {count}".format( + count=len(call.positional_arguments) + ) + ) + # The left hand argument is the obj to be checked + obj_node, class_or_tuple_node = call.positional_arguments + # The right hand argument is the class(es) that the given + # obj is to be check is an instance of + try: + class_container = _class_or_tuple_to_container( + class_or_tuple_node, context=context + ) + except InferenceError: + raise UseInferenceDefault + try: + isinstance_bool = helpers.object_isinstance(obj_node, class_container, context) + except AstroidTypeError as exc: + raise UseInferenceDefault("TypeError: " + str(exc)) + except MroError as exc: + raise UseInferenceDefault from exc + if isinstance_bool is util.Uninferable: + raise UseInferenceDefault + return nodes.Const(isinstance_bool) + + +def _class_or_tuple_to_container(node, context=None): + # Move inferences results into container + # to simplify later logic + # raises InferenceError if any of the inferences fall through + node_infer = next(node.infer(context=context)) + # arg2 MUST be a type or a TUPLE of types + # for isinstance + if isinstance(node_infer, nodes.Tuple): + class_container = [ + next(node.infer(context=context)) for node in node_infer.elts + ] + class_container = [ + klass_node for klass_node in class_container if klass_node is not None + ] + else: + class_container = [node_infer] + return class_container + + +def infer_len(node, context=None): + """Infer length calls + + :param nodes.Call node: len call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const node with the inferred length, if possible + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: len() must take no keyword arguments") + if len(call.positional_arguments) != 1: + raise UseInferenceDefault( + "TypeError: len() must take exactly one argument " + "({len}) given".format(len=len(call.positional_arguments)) + ) + [argument_node] = call.positional_arguments + try: + return nodes.Const(helpers.object_len(argument_node)) + except (AstroidTypeError, InferenceError) as exc: + raise UseInferenceDefault(str(exc)) from exc + + +def infer_str(node, context=None): + """Infer str() calls + + :param nodes.Call node: str() call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const containing an empty string + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: str() must take no keyword arguments") + try: + return nodes.Const("") + except (AstroidTypeError, InferenceError) as exc: + raise UseInferenceDefault(str(exc)) from exc + + +def infer_int(node, context=None): + """Infer int() calls + + :param nodes.Call node: int() call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const containing the integer value of the int() call + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: int() must take no keyword arguments") + + if call.positional_arguments: + try: + first_value = next(call.positional_arguments[0].infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault(str(exc)) from exc + + if first_value is util.Uninferable: + raise UseInferenceDefault + + if isinstance(first_value, nodes.Const) and isinstance( + first_value.value, (int, str) + ): + try: + actual_value = int(first_value.value) + except ValueError: + return nodes.Const(0) + return nodes.Const(actual_value) + + return nodes.Const(0) + + +def infer_dict_fromkeys(node, context=None): + """Infer dict.fromkeys + + :param nodes.Call node: dict.fromkeys() call to infer + :param context.InferenceContext: node context + :rtype nodes.Dict: + a Dictionary containing the values that astroid was able to infer. + In case the inference failed for any reason, an empty dictionary + will be inferred instead. + """ + + def _build_dict_with_elements(elements): + new_node = nodes.Dict( + col_offset=node.col_offset, lineno=node.lineno, parent=node.parent + ) + new_node.postinit(elements) + return new_node + + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: int() must take no keyword arguments") + if len(call.positional_arguments) not in {1, 2}: + raise UseInferenceDefault( + "TypeError: Needs between 1 and 2 positional arguments" + ) + + default = nodes.Const(None) + values = call.positional_arguments[0] + try: + inferred_values = next(values.infer(context=context)) + except InferenceError: + return _build_dict_with_elements([]) + if inferred_values is util.Uninferable: + return _build_dict_with_elements([]) + + # Limit to a couple of potential values, as this can become pretty complicated + accepted_iterable_elements = (nodes.Const,) + if isinstance(inferred_values, (nodes.List, nodes.Set, nodes.Tuple)): + elements = inferred_values.elts + for element in elements: + if not isinstance(element, accepted_iterable_elements): + # Fallback to an empty dict + return _build_dict_with_elements([]) + + elements_with_value = [(element, default) for element in elements] + return _build_dict_with_elements(elements_with_value) + + elif isinstance(inferred_values, nodes.Const) and isinstance( + inferred_values.value, (str, bytes) + ): + elements = [ + (nodes.Const(element), default) for element in inferred_values.value + ] + return _build_dict_with_elements(elements) + elif isinstance(inferred_values, nodes.Dict): + keys = inferred_values.itered() + for key in keys: + if not isinstance(key, accepted_iterable_elements): + # Fallback to an empty dict + return _build_dict_with_elements([]) + + elements_with_value = [(element, default) for element in keys] + return _build_dict_with_elements(elements_with_value) + + # Fallback to an empty dictionary + return _build_dict_with_elements([]) + + +# Builtins inference +register_builtin_transform(infer_bool, "bool") +register_builtin_transform(infer_super, "super") +register_builtin_transform(infer_callable, "callable") +register_builtin_transform(infer_getattr, "getattr") +register_builtin_transform(infer_hasattr, "hasattr") +register_builtin_transform(infer_tuple, "tuple") +register_builtin_transform(infer_set, "set") +register_builtin_transform(infer_list, "list") +register_builtin_transform(infer_dict, "dict") +register_builtin_transform(infer_frozenset, "frozenset") +register_builtin_transform(infer_type, "type") +register_builtin_transform(infer_slice, "slice") +register_builtin_transform(infer_isinstance, "isinstance") +register_builtin_transform(infer_issubclass, "issubclass") +register_builtin_transform(infer_len, "len") +register_builtin_transform(infer_str, "str") +register_builtin_transform(infer_int, "int") +register_builtin_transform(infer_dict_fromkeys, "dict.fromkeys") + + +# Infer object.__new__ calls +MANAGER.register_transform( + nodes.ClassDef, + inference_tip(_infer_object__new__decorator), + _infer_object__new__decorator_check, +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_collections.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_collections.py new file mode 100644 index 0000000..b9eb9b9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_collections.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2016-2017 Åukasz Rogalski +# Copyright (c) 2017 Derek Gustafson +# Copyright (c) 2018 Ioana Tagirta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys + +import astroid + +PY34 = sys.version_info >= (3, 4) +PY35 = sys.version_info >= (3, 5) + + +def _collections_transform(): + return astroid.parse( + """ + class defaultdict(dict): + default_factory = None + def __missing__(self, key): pass + def __getitem__(self, key): return default_factory + + """ + + _deque_mock() + + _ordered_dict_mock() + ) + + +def _deque_mock(): + base_deque_class = """ + class deque(object): + maxlen = 0 + def __init__(self, iterable=None, maxlen=None): + self.iterable = iterable or [] + def append(self, x): pass + def appendleft(self, x): pass + def clear(self): pass + def count(self, x): return 0 + def extend(self, iterable): pass + def extendleft(self, iterable): pass + def pop(self): return self.iterable[0] + def popleft(self): return self.iterable[0] + def remove(self, value): pass + def reverse(self): return reversed(self.iterable) + def rotate(self, n=1): return self + def __iter__(self): return self + def __reversed__(self): return self.iterable[::-1] + def __getitem__(self, index): return self.iterable[index] + def __setitem__(self, index, value): pass + def __delitem__(self, index): pass + def __bool__(self): return bool(self.iterable) + def __nonzero__(self): return bool(self.iterable) + def __contains__(self, o): return o in self.iterable + def __len__(self): return len(self.iterable) + def __copy__(self): return deque(self.iterable)""" + if PY35: + base_deque_class += """ + def copy(self): return deque(self.iterable) + def index(self, x, start=0, end=0): return 0 + def insert(self, x, i): pass + def __add__(self, other): pass + def __iadd__(self, other): pass + def __mul__(self, other): pass + def __imul__(self, other): pass + def __rmul__(self, other): pass""" + return base_deque_class + + +def _ordered_dict_mock(): + base_ordered_dict_class = """ + class OrderedDict(dict): + def __reversed__(self): return self[::-1] + """ + if PY34: + base_ordered_dict_class += """ + def move_to_end(self, key, last=False): pass""" + return base_ordered_dict_class + + +astroid.register_module_extender(astroid.MANAGER, "collections", _collections_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_curses.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_curses.py new file mode 100644 index 0000000..68e88b9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_curses.py @@ -0,0 +1,179 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import astroid + + +def _curses_transform(): + return astroid.parse( + """ + A_ALTCHARSET = 1 + A_BLINK = 1 + A_BOLD = 1 + A_DIM = 1 + A_INVIS = 1 + A_ITALIC = 1 + A_NORMAL = 1 + A_PROTECT = 1 + A_REVERSE = 1 + A_STANDOUT = 1 + A_UNDERLINE = 1 + A_HORIZONTAL = 1 + A_LEFT = 1 + A_LOW = 1 + A_RIGHT = 1 + A_TOP = 1 + A_VERTICAL = 1 + A_CHARTEXT = 1 + A_ATTRIBUTES = 1 + A_CHARTEXT = 1 + A_COLOR = 1 + KEY_MIN = 1 + KEY_BREAK = 1 + KEY_DOWN = 1 + KEY_UP = 1 + KEY_LEFT = 1 + KEY_RIGHT = 1 + KEY_HOME = 1 + KEY_BACKSPACE = 1 + KEY_F0 = 1 + KEY_Fn = 1 + KEY_DL = 1 + KEY_IL = 1 + KEY_DC = 1 + KEY_IC = 1 + KEY_EIC = 1 + KEY_CLEAR = 1 + KEY_EOS = 1 + KEY_EOL = 1 + KEY_SF = 1 + KEY_SR = 1 + KEY_NPAGE = 1 + KEY_PPAGE = 1 + KEY_STAB = 1 + KEY_CTAB = 1 + KEY_CATAB = 1 + KEY_ENTER = 1 + KEY_SRESET = 1 + KEY_RESET = 1 + KEY_PRINT = 1 + KEY_LL = 1 + KEY_A1 = 1 + KEY_A3 = 1 + KEY_B2 = 1 + KEY_C1 = 1 + KEY_C3 = 1 + KEY_BTAB = 1 + KEY_BEG = 1 + KEY_CANCEL = 1 + KEY_CLOSE = 1 + KEY_COMMAND = 1 + KEY_COPY = 1 + KEY_CREATE = 1 + KEY_END = 1 + KEY_EXIT = 1 + KEY_FIND = 1 + KEY_HELP = 1 + KEY_MARK = 1 + KEY_MESSAGE = 1 + KEY_MOVE = 1 + KEY_NEXT = 1 + KEY_OPEN = 1 + KEY_OPTIONS = 1 + KEY_PREVIOUS = 1 + KEY_REDO = 1 + KEY_REFERENCE = 1 + KEY_REFRESH = 1 + KEY_REPLACE = 1 + KEY_RESTART = 1 + KEY_RESUME = 1 + KEY_SAVE = 1 + KEY_SBEG = 1 + KEY_SCANCEL = 1 + KEY_SCOMMAND = 1 + KEY_SCOPY = 1 + KEY_SCREATE = 1 + KEY_SDC = 1 + KEY_SDL = 1 + KEY_SELECT = 1 + KEY_SEND = 1 + KEY_SEOL = 1 + KEY_SEXIT = 1 + KEY_SFIND = 1 + KEY_SHELP = 1 + KEY_SHOME = 1 + KEY_SIC = 1 + KEY_SLEFT = 1 + KEY_SMESSAGE = 1 + KEY_SMOVE = 1 + KEY_SNEXT = 1 + KEY_SOPTIONS = 1 + KEY_SPREVIOUS = 1 + KEY_SPRINT = 1 + KEY_SREDO = 1 + KEY_SREPLACE = 1 + KEY_SRIGHT = 1 + KEY_SRSUME = 1 + KEY_SSAVE = 1 + KEY_SSUSPEND = 1 + KEY_SUNDO = 1 + KEY_SUSPEND = 1 + KEY_UNDO = 1 + KEY_MOUSE = 1 + KEY_RESIZE = 1 + KEY_MAX = 1 + ACS_BBSS = 1 + ACS_BLOCK = 1 + ACS_BOARD = 1 + ACS_BSBS = 1 + ACS_BSSB = 1 + ACS_BSSS = 1 + ACS_BTEE = 1 + ACS_BULLET = 1 + ACS_CKBOARD = 1 + ACS_DARROW = 1 + ACS_DEGREE = 1 + ACS_DIAMOND = 1 + ACS_GEQUAL = 1 + ACS_HLINE = 1 + ACS_LANTERN = 1 + ACS_LARROW = 1 + ACS_LEQUAL = 1 + ACS_LLCORNER = 1 + ACS_LRCORNER = 1 + ACS_LTEE = 1 + ACS_NEQUAL = 1 + ACS_PI = 1 + ACS_PLMINUS = 1 + ACS_PLUS = 1 + ACS_RARROW = 1 + ACS_RTEE = 1 + ACS_S1 = 1 + ACS_S3 = 1 + ACS_S7 = 1 + ACS_S9 = 1 + ACS_SBBS = 1 + ACS_SBSB = 1 + ACS_SBSS = 1 + ACS_SSBB = 1 + ACS_SSBS = 1 + ACS_SSSB = 1 + ACS_SSSS = 1 + ACS_STERLING = 1 + ACS_TTEE = 1 + ACS_UARROW = 1 + ACS_ULCORNER = 1 + ACS_URCORNER = 1 + ACS_VLINE = 1 + COLOR_BLACK = 1 + COLOR_BLUE = 1 + COLOR_CYAN = 1 + COLOR_GREEN = 1 + COLOR_MAGENTA = 1 + COLOR_RED = 1 + COLOR_WHITE = 1 + COLOR_YELLOW = 1 + """ + ) + + +astroid.register_module_extender(astroid.MANAGER, "curses", _curses_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_dateutil.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_dateutil.py new file mode 100644 index 0000000..a1c270f --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_dateutil.py @@ -0,0 +1,28 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2015 raylu +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for dateutil""" + +import textwrap + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def dateutil_transform(): + return AstroidBuilder(MANAGER).string_build( + textwrap.dedent( + """ + import datetime + def parse(timestr, parserinfo=None, **kwargs): + return datetime.datetime() + """ + ) + ) + + +register_module_extender(MANAGER, "dateutil.parser", dateutil_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_fstrings.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_fstrings.py new file mode 100644 index 0000000..7d8c7b6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_fstrings.py @@ -0,0 +1,51 @@ +# Copyright (c) 2017 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import collections +import sys + +import astroid + + +def _clone_node_with_lineno(node, parent, lineno): + cls = node.__class__ + other_fields = node._other_fields + _astroid_fields = node._astroid_fields + init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent} + postinit_params = {param: getattr(node, param) for param in _astroid_fields} + if other_fields: + init_params.update({param: getattr(node, param) for param in other_fields}) + new_node = cls(**init_params) + if hasattr(node, "postinit") and _astroid_fields: + for param, child in postinit_params.items(): + if child and not isinstance(child, collections.Sequence): + cloned_child = _clone_node_with_lineno( + node=child, lineno=new_node.lineno, parent=new_node + ) + postinit_params[param] = cloned_child + new_node.postinit(**postinit_params) + return new_node + + +def _transform_formatted_value(node): + if node.value and node.value.lineno == 1: + if node.lineno != node.value.lineno: + new_node = astroid.FormattedValue( + lineno=node.lineno, col_offset=node.col_offset, parent=node.parent + ) + new_value = _clone_node_with_lineno( + node=node.value, lineno=node.lineno, parent=new_node + ) + new_node.postinit(value=new_value, format_spec=node.format_spec) + return new_node + + +if sys.version_info[:2] >= (3, 6): + # TODO: this fix tries to *patch* http://bugs.python.org/issue29051 + # The problem is that FormattedValue.value, which is a Name node, + # has wrong line numbers, usually 1. This creates problems for pylint, + # which expects correct line numbers for things such as message control. + astroid.MANAGER.register_transform( + astroid.FormattedValue, _transform_formatted_value + ) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_functools.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_functools.py new file mode 100644 index 0000000..726c82f --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_functools.py @@ -0,0 +1,157 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2018 Bryce Guinta + +"""Astroid hooks for understanding functools library module.""" +from functools import partial +from itertools import chain + +import astroid +from astroid import arguments +from astroid import BoundMethod +from astroid import extract_node +from astroid import helpers +from astroid.interpreter import objectmodel +from astroid import MANAGER +from astroid import objects + + +LRU_CACHE = "functools.lru_cache" + + +class LruWrappedModel(objectmodel.FunctionModel): + """Special attribute model for functions decorated with functools.lru_cache. + + The said decorators patches at decoration time some functions onto + the decorated function. + """ + + @property + def attr___wrapped__(self): + return self._instance + + @property + def attr_cache_info(self): + cache_info = extract_node( + """ + from functools import _CacheInfo + _CacheInfo(0, 0, 0, 0) + """ + ) + + class CacheInfoBoundMethod(BoundMethod): + def infer_call_result(self, caller, context=None): + yield helpers.safe_infer(cache_info) + + return CacheInfoBoundMethod(proxy=self._instance, bound=self._instance) + + @property + def attr_cache_clear(self): + node = extract_node("""def cache_clear(self): pass""") + return BoundMethod(proxy=node, bound=self._instance.parent.scope()) + + +def _transform_lru_cache(node, context=None): + # TODO: this is not ideal, since the node should be immutable, + # but due to https://github.com/PyCQA/astroid/issues/354, + # there's not much we can do now. + # Replacing the node would work partially, because, + # in pylint, the old node would still be available, leading + # to spurious false positives. + node.special_attributes = LruWrappedModel()(node) + return + + +def _functools_partial_inference(node, context=None): + call = arguments.CallSite.from_call(node) + number_of_positional = len(call.positional_arguments) + if number_of_positional < 1: + raise astroid.UseInferenceDefault( + "functools.partial takes at least one argument" + ) + if number_of_positional == 1 and not call.keyword_arguments: + raise astroid.UseInferenceDefault( + "functools.partial needs at least to have some filled arguments" + ) + + partial_function = call.positional_arguments[0] + try: + inferred_wrapped_function = next(partial_function.infer(context=context)) + except astroid.InferenceError as exc: + raise astroid.UseInferenceDefault from exc + if inferred_wrapped_function is astroid.Uninferable: + raise astroid.UseInferenceDefault("Cannot infer the wrapped function") + if not isinstance(inferred_wrapped_function, astroid.FunctionDef): + raise astroid.UseInferenceDefault("The wrapped function is not a function") + + # Determine if the passed keywords into the callsite are supported + # by the wrapped function. + function_parameters = chain( + inferred_wrapped_function.args.args or (), + inferred_wrapped_function.args.kwonlyargs or (), + ) + parameter_names = set( + param.name + for param in function_parameters + if isinstance(param, astroid.AssignName) + ) + if set(call.keyword_arguments) - parameter_names: + raise astroid.UseInferenceDefault( + "wrapped function received unknown parameters" + ) + + partial_function = objects.PartialFunction( + call, + name=inferred_wrapped_function.name, + doc=inferred_wrapped_function.doc, + lineno=inferred_wrapped_function.lineno, + col_offset=inferred_wrapped_function.col_offset, + parent=inferred_wrapped_function.parent, + ) + partial_function.postinit( + args=inferred_wrapped_function.args, + body=inferred_wrapped_function.body, + decorators=inferred_wrapped_function.decorators, + returns=inferred_wrapped_function.returns, + type_comment_returns=inferred_wrapped_function.type_comment_returns, + type_comment_args=inferred_wrapped_function.type_comment_args, + ) + return iter((partial_function,)) + + +def _looks_like_lru_cache(node): + """Check if the given function node is decorated with lru_cache.""" + if not node.decorators: + return False + for decorator in node.decorators.nodes: + if not isinstance(decorator, astroid.Call): + continue + if _looks_like_functools_member(decorator, "lru_cache"): + return True + return False + + +def _looks_like_functools_member(node, member): + """Check if the given Call node is a functools.partial call""" + if isinstance(node.func, astroid.Name): + return node.func.name == member + elif isinstance(node.func, astroid.Attribute): + return ( + node.func.attrname == member + and isinstance(node.func.expr, astroid.Name) + and node.func.expr.name == "functools" + ) + + +_looks_like_partial = partial(_looks_like_functools_member, member="partial") + + +MANAGER.register_transform( + astroid.FunctionDef, _transform_lru_cache, _looks_like_lru_cache +) + + +MANAGER.register_transform( + astroid.Call, + astroid.inference_tip(_functools_partial_inference), + _looks_like_partial, +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_gi.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_gi.py new file mode 100644 index 0000000..0970610 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_gi.py @@ -0,0 +1,220 @@ +# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Cole Robinson +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 David Shea +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Giuseppe Scrivano + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the Python 2 GObject introspection bindings. + +Helps with understanding everything imported from 'gi.repository' +""" + +import inspect +import itertools +import sys +import re +import warnings + +from astroid import MANAGER, AstroidBuildingError, nodes +from astroid.builder import AstroidBuilder + + +_inspected_modules = {} + +_identifier_re = r"^[A-Za-z_]\w*$" + + +def _gi_build_stub(parent): + """ + Inspect the passed module recursively and build stubs for functions, + classes, etc. + """ + classes = {} + functions = {} + constants = {} + methods = {} + for name in dir(parent): + if name.startswith("__"): + continue + + # Check if this is a valid name in python + if not re.match(_identifier_re, name): + continue + + try: + obj = getattr(parent, name) + except: + continue + + if inspect.isclass(obj): + classes[name] = obj + elif inspect.isfunction(obj) or inspect.isbuiltin(obj): + functions[name] = obj + elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): + methods[name] = obj + elif ( + str(obj).startswith(", ) + # Only accept function calls with two constant arguments + if len(node.args) != 2: + return False + + if not all(isinstance(arg, nodes.Const) for arg in node.args): + return False + + func = node.func + if isinstance(func, nodes.Attribute): + if func.attrname != "require_version": + return False + if isinstance(func.expr, nodes.Name) and func.expr.name == "gi": + return True + + return False + + if isinstance(func, nodes.Name): + return func.name == "require_version" + + return False + + +def _register_require_version(node): + # Load the gi.require_version locally + try: + import gi + + gi.require_version(node.args[0].value, node.args[1].value) + except Exception: + pass + + return node + + +MANAGER.register_failed_import_hook(_import_gi_module) +MANAGER.register_transform( + nodes.Call, _register_require_version, _looks_like_require_version +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_hashlib.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_hashlib.py new file mode 100644 index 0000000..98ae774 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_hashlib.py @@ -0,0 +1,67 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2018 Ioana Tagirta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys + +import six + +import astroid + +PY36 = sys.version_info >= (3, 6) + + +def _hashlib_transform(): + signature = "value=''" + template = """ + class %(name)s(object): + def __init__(self, %(signature)s): pass + def digest(self): + return %(digest)s + def copy(self): + return self + def update(self, value): pass + def hexdigest(self): + return '' + @property + def name(self): + return %(name)r + @property + def block_size(self): + return 1 + @property + def digest_size(self): + return 1 + """ + algorithms_with_signature = dict.fromkeys( + ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"], signature + ) + if PY36: + blake2b_signature = "data=b'', *, digest_size=64, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False" + blake2s_signature = "data=b'', *, digest_size=32, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False" + new_algorithms = dict.fromkeys( + ["sha3_224", "sha3_256", "sha3_384", "sha3_512", "shake_128", "shake_256"], + signature, + ) + algorithms_with_signature.update(new_algorithms) + algorithms_with_signature.update( + {"blake2b": blake2b_signature, "blake2s": blake2s_signature} + ) + classes = "".join( + template + % { + "name": hashfunc, + "digest": 'b""' if six.PY3 else '""', + "signature": signature, + } + for hashfunc, signature in algorithms_with_signature.items() + ) + return astroid.parse(classes) + + +astroid.register_module_extender(astroid.MANAGER, "hashlib", _hashlib_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_http.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_http.py new file mode 100644 index 0000000..45a9db2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_http.py @@ -0,0 +1,81 @@ +# Copyright (c) 2018 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid brain hints for some of the `http` module.""" +import textwrap + +import astroid +from astroid.builder import AstroidBuilder + + +def _http_transform(): + return AstroidBuilder(astroid.MANAGER).string_build( + textwrap.dedent( + """ + from http import HTTPStatus + + CONTINUE = HTTPStatus.CONTINUE + SWITCHING_PROTOCOLS = HTTPStatus.SWITCHING_PROTOCOLS + PROCESSING = HTTPStatus.PROCESSING + OK = HTTPStatus.OK + CREATED = HTTPStatus.CREATED + ACCEPTED = HTTPStatus.ACCEPTED + NON_AUTHORITATIVE_INFORMATION = HTTPStatus.NON_AUTHORITATIVE_INFORMATION + NO_CONTENT = HTTPStatus.NO_CONTENT + RESET_CONTENT = HTTPStatus.RESET_CONTENT + PARTIAL_CONTENT = HTTPStatus.PARTIAL_CONTENT + MULTI_STATUS = HTTPStatus.MULTI_STATUS + ALREADY_REPORTED = HTTPStatus.ALREADY_REPORTED + IM_USED = HTTPStatus.IM_USED + MULTIPLE_CHOICES = HTTPStatus.MULTIPLE_CHOICES + MOVED_PERMANENTLY = HTTPStatus.MOVED_PERMANENTLY + FOUND = HTTPStatus.FOUND + SEE_OTHER = HTTPStatus.SEE_OTHER + NOT_MODIFIED = HTTPStatus.NOT_MODIFIED + USE_PROXY = HTTPStatus.USE_PROXY + TEMPORARY_REDIRECT = HTTPStatus.TEMPORARY_REDIRECT + PERMANENT_REDIRECT = HTTPStatus.PERMANENT_REDIRECT + BAD_REQUEST = HTTPStatus.BAD_REQUEST + UNAUTHORIZED = HTTPStatus.UNAUTHORIZED + PAYMENT_REQUIRED = HTTPStatus.PAYMENT_REQUIRED + FORBIDDEN = HTTPStatus.FORBIDDEN + NOT_FOUND = HTTPStatus.NOT_FOUND + METHOD_NOT_ALLOWED = HTTPStatus.METHOD_NOT_ALLOWED + NOT_ACCEPTABLE = HTTPStatus.NOT_ACCEPTABLE + PROXY_AUTHENTICATION_REQUIRED = HTTPStatus.PROXY_AUTHENTICATION_REQUIRED + REQUEST_TIMEOUT = HTTPStatus.REQUEST_TIMEOUT + CONFLICT = HTTPStatus.CONFLICT + GONE = HTTPStatus.GONE + LENGTH_REQUIRED = HTTPStatus.LENGTH_REQUIRED + PRECONDITION_FAILED = HTTPStatus.PRECONDITION_FAILED + REQUEST_ENTITY_TOO_LARGE = HTTPStatus.REQUEST_ENTITY_TOO_LARGE + REQUEST_URI_TOO_LONG = HTTPStatus.REQUEST_URI_TOO_LONG + UNSUPPORTED_MEDIA_TYPE = HTTPStatus.UNSUPPORTED_MEDIA_TYPE + REQUESTED_RANGE_NOT_SATISFIABLE = HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE + EXPECTATION_FAILED = HTTPStatus.EXPECTATION_FAILED + UNPROCESSABLE_ENTITY = HTTPStatus.UNPROCESSABLE_ENTITY + LOCKED = HTTPStatus.LOCKED + FAILED_DEPENDENCY = HTTPStatus.FAILED_DEPENDENCY + UPGRADE_REQUIRED = HTTPStatus.UPGRADE_REQUIRED + PRECONDITION_REQUIRED = HTTPStatus.PRECONDITION_REQUIRED + TOO_MANY_REQUESTS = HTTPStatus.TOO_MANY_REQUESTS + REQUEST_HEADER_FIELDS_TOO_LARGE = HTTPStatus.REQUEST_HEADER_FIELDS_TOO_LARGE + INTERNAL_SERVER_ERROR = HTTPStatus.INTERNAL_SERVER_ERROR + NOT_IMPLEMENTED = HTTPStatus.NOT_IMPLEMENTED + BAD_GATEWAY = HTTPStatus.BAD_GATEWAY + SERVICE_UNAVAILABLE = HTTPStatus.SERVICE_UNAVAILABLE + GATEWAY_TIMEOUT = HTTPStatus.GATEWAY_TIMEOUT + HTTP_VERSION_NOT_SUPPORTED = HTTPStatus.HTTP_VERSION_NOT_SUPPORTED + VARIANT_ALSO_NEGOTIATES = HTTPStatus.VARIANT_ALSO_NEGOTIATES + INSUFFICIENT_STORAGE = HTTPStatus.INSUFFICIENT_STORAGE + LOOP_DETECTED = HTTPStatus.LOOP_DETECTED + NOT_EXTENDED = HTTPStatus.NOT_EXTENDED + NETWORK_AUTHENTICATION_REQUIRED = HTTPStatus.NETWORK_AUTHENTICATION_REQUIRED + """ + ) + ) + + +astroid.register_module_extender(astroid.MANAGER, "http.client", _http_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_io.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_io.py new file mode 100644 index 0000000..4c68922 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_io.py @@ -0,0 +1,45 @@ +# Copyright (c) 2016 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid brain hints for some of the _io C objects.""" + +import astroid + + +BUFFERED = {"BufferedWriter", "BufferedReader"} +TextIOWrapper = "TextIOWrapper" +FileIO = "FileIO" +BufferedWriter = "BufferedWriter" + + +def _generic_io_transform(node, name, cls): + """Transform the given name, by adding the given *class* as a member of the node.""" + + io_module = astroid.MANAGER.ast_from_module_name("_io") + attribute_object = io_module[cls] + instance = attribute_object.instantiate_class() + node.locals[name] = [instance] + + +def _transform_text_io_wrapper(node): + # This is not always correct, since it can vary with the type of the descriptor, + # being stdout, stderr or stdin. But we cannot get access to the name of the + # stream, which is why we are using the BufferedWriter class as a default + # value + return _generic_io_transform(node, name="buffer", cls=BufferedWriter) + + +def _transform_buffered(node): + return _generic_io_transform(node, name="raw", cls=FileIO) + + +astroid.MANAGER.register_transform( + astroid.ClassDef, _transform_buffered, lambda node: node.name in BUFFERED +) +astroid.MANAGER.register_transform( + astroid.ClassDef, + _transform_text_io_wrapper, + lambda node: node.name == TextIOWrapper, +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_mechanize.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_mechanize.py new file mode 100644 index 0000000..93f282e --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_mechanize.py @@ -0,0 +1,29 @@ +# Copyright (c) 2012-2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def mechanize_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +class Browser(object): + def open(self, url, data=None, timeout=None): + return None + def open_novisit(self, url, data=None, timeout=None): + return None + def open_local_file(self, filename): + return None + +""" + ) + + +register_module_extender(MANAGER, "mechanize", mechanize_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_multiprocessing.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_multiprocessing.py new file mode 100644 index 0000000..be575e9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_multiprocessing.py @@ -0,0 +1,112 @@ +# Copyright (c) 2016 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import sys + +import astroid +from astroid import exceptions + + +PY34 = sys.version_info >= (3, 4) + + +def _multiprocessing_transform(): + module = astroid.parse( + """ + from multiprocessing.managers import SyncManager + def Manager(): + return SyncManager() + """ + ) + if not PY34: + return module + + # On Python 3.4, multiprocessing uses a getattr lookup inside contexts, + # in order to get the attributes they need. Since it's extremely + # dynamic, we use this approach to fake it. + node = astroid.parse( + """ + from multiprocessing.context import DefaultContext, BaseContext + default = DefaultContext() + base = BaseContext() + """ + ) + try: + context = next(node["default"].infer()) + base = next(node["base"].infer()) + except exceptions.InferenceError: + return module + + for node in (context, base): + for key, value in node.locals.items(): + if key.startswith("_"): + continue + + value = value[0] + if isinstance(value, astroid.FunctionDef): + # We need to rebound this, since otherwise + # it will have an extra argument (self). + value = astroid.BoundMethod(value, node) + module[key] = value + return module + + +def _multiprocessing_managers_transform(): + return astroid.parse( + """ + import array + import threading + import multiprocessing.pool as pool + + import six + + class Namespace(object): + pass + + class Value(object): + def __init__(self, typecode, value, lock=True): + self._typecode = typecode + self._value = value + def get(self): + return self._value + def set(self, value): + self._value = value + def __repr__(self): + return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value) + value = property(get, set) + + def Array(typecode, sequence, lock=True): + return array.array(typecode, sequence) + + class SyncManager(object): + Queue = JoinableQueue = six.moves.queue.Queue + Event = threading.Event + RLock = threading.RLock + BoundedSemaphore = threading.BoundedSemaphore + Condition = threading.Condition + Barrier = threading.Barrier + Pool = pool.Pool + list = list + dict = dict + Value = Value + Array = Array + Namespace = Namespace + __enter__ = lambda self: self + __exit__ = lambda *args: args + + def start(self, initializer=None, initargs=None): + pass + def shutdown(self): + pass + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "multiprocessing.managers", _multiprocessing_managers_transform +) +astroid.register_module_extender( + astroid.MANAGER, "multiprocessing", _multiprocessing_transform +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_namedtuple_enum.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_namedtuple_enum.py new file mode 100644 index 0000000..c50ef04 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_namedtuple_enum.py @@ -0,0 +1,440 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2012-2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2015 David Shea +# Copyright (c) 2015 Philip Lorenz +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Mateusz Bysiek +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Åukasz Rogalski + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the Python standard library.""" + +import functools +import keyword +from textwrap import dedent + +from astroid import MANAGER, UseInferenceDefault, inference_tip, InferenceError +from astroid import arguments +from astroid import exceptions +from astroid import nodes +from astroid.builder import AstroidBuilder, extract_node +from astroid import util + + +TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"} +ENUM_BASE_NAMES = { + "Enum", + "IntEnum", + "enum.Enum", + "enum.IntEnum", + "IntFlag", + "enum.IntFlag", +} + + +def _infer_first(node, context): + if node is util.Uninferable: + raise UseInferenceDefault + try: + value = next(node.infer(context=context)) + if value is util.Uninferable: + raise UseInferenceDefault() + else: + return value + except StopIteration: + raise InferenceError() + + +def _find_func_form_arguments(node, context): + def _extract_namedtuple_arg_or_keyword(position, key_name=None): + + if len(args) > position: + return _infer_first(args[position], context) + if key_name and key_name in found_keywords: + return _infer_first(found_keywords[key_name], context) + + args = node.args + keywords = node.keywords + found_keywords = ( + {keyword.arg: keyword.value for keyword in keywords} if keywords else {} + ) + + name = _extract_namedtuple_arg_or_keyword(position=0, key_name="typename") + names = _extract_namedtuple_arg_or_keyword(position=1, key_name="field_names") + if name and names: + return name.value, names + + raise UseInferenceDefault() + + +def infer_func_form(node, base_type, context=None, enum=False): + """Specific inference function for namedtuple or Python 3 enum. """ + # node is a Call node, class name as first argument and generated class + # attributes as second argument + + # namedtuple or enums list of attributes can be a list of strings or a + # whitespace-separate string + try: + name, names = _find_func_form_arguments(node, context) + try: + attributes = names.value.replace(",", " ").split() + except AttributeError: + if not enum: + attributes = [ + _infer_first(const, context).value for const in names.elts + ] + else: + # Enums supports either iterator of (name, value) pairs + # or mappings. + if hasattr(names, "items") and isinstance(names.items, list): + attributes = [ + _infer_first(const[0], context).value + for const in names.items + if isinstance(const[0], nodes.Const) + ] + elif hasattr(names, "elts"): + # Enums can support either ["a", "b", "c"] + # or [("a", 1), ("b", 2), ...], but they can't + # be mixed. + if all(isinstance(const, nodes.Tuple) for const in names.elts): + attributes = [ + _infer_first(const.elts[0], context).value + for const in names.elts + if isinstance(const, nodes.Tuple) + ] + else: + attributes = [ + _infer_first(const, context).value for const in names.elts + ] + else: + raise AttributeError + if not attributes: + raise AttributeError + except (AttributeError, exceptions.InferenceError): + raise UseInferenceDefault() + + # If we can't infer the name of the class, don't crash, up to this point + # we know it is a namedtuple anyway. + name = name or "Uninferable" + # we want to return a Class node instance with proper attributes set + class_node = nodes.ClassDef(name, "docstring") + class_node.parent = node.parent + # set base class=tuple + class_node.bases.append(base_type) + # XXX add __init__(*attributes) method + for attr in attributes: + fake_node = nodes.EmptyNode() + fake_node.parent = class_node + fake_node.attrname = attr + class_node.instance_attrs[attr] = [fake_node] + return class_node, name, attributes + + +def _has_namedtuple_base(node): + """Predicate for class inference tip + + :type node: ClassDef + :rtype: bool + """ + return set(node.basenames) & TYPING_NAMEDTUPLE_BASENAMES + + +def _looks_like(node, name): + func = node.func + if isinstance(func, nodes.Attribute): + return func.attrname == name + if isinstance(func, nodes.Name): + return func.name == name + return False + + +_looks_like_namedtuple = functools.partial(_looks_like, name="namedtuple") +_looks_like_enum = functools.partial(_looks_like, name="Enum") +_looks_like_typing_namedtuple = functools.partial(_looks_like, name="NamedTuple") + + +def infer_named_tuple(node, context=None): + """Specific inference function for namedtuple Call node""" + tuple_base_name = nodes.Name(name="tuple", parent=node.root()) + class_node, name, attributes = infer_func_form( + node, tuple_base_name, context=context + ) + call_site = arguments.CallSite.from_call(node) + func = next(extract_node("import collections; collections.namedtuple").infer()) + try: + rename = next(call_site.infer_argument(func, "rename", context)).bool_value() + except InferenceError: + rename = False + + if rename: + attributes = _get_renamed_namedtuple_attributes(attributes) + + replace_args = ", ".join("{arg}=None".format(arg=arg) for arg in attributes) + field_def = ( + " {name} = property(lambda self: self[{index:d}], " + "doc='Alias for field number {index:d}')" + ) + field_defs = "\n".join( + field_def.format(name=name, index=index) + for index, name in enumerate(attributes) + ) + fake = AstroidBuilder(MANAGER).string_build( + """ +class %(name)s(tuple): + __slots__ = () + _fields = %(fields)r + def _asdict(self): + return self.__dict__ + @classmethod + def _make(cls, iterable, new=tuple.__new__, len=len): + return new(cls, iterable) + def _replace(self, %(replace_args)s): + return self + def __getnewargs__(self): + return tuple(self) +%(field_defs)s + """ + % { + "name": name, + "fields": attributes, + "field_defs": field_defs, + "replace_args": replace_args, + } + ) + class_node.locals["_asdict"] = fake.body[0].locals["_asdict"] + class_node.locals["_make"] = fake.body[0].locals["_make"] + class_node.locals["_replace"] = fake.body[0].locals["_replace"] + class_node.locals["_fields"] = fake.body[0].locals["_fields"] + for attr in attributes: + class_node.locals[attr] = fake.body[0].locals[attr] + # we use UseInferenceDefault, we can't be a generator so return an iterator + return iter([class_node]) + + +def _get_renamed_namedtuple_attributes(field_names): + names = list(field_names) + seen = set() + for i, name in enumerate(field_names): + if ( + not all(c.isalnum() or c == "_" for c in name) + or keyword.iskeyword(name) + or not name + or name[0].isdigit() + or name.startswith("_") + or name in seen + ): + names[i] = "_%d" % i + seen.add(name) + return tuple(names) + + +def infer_enum(node, context=None): + """ Specific inference function for enum Call node. """ + enum_meta = extract_node( + """ + class EnumMeta(object): + 'docstring' + def __call__(self, node): + class EnumAttribute(object): + name = '' + value = 0 + return EnumAttribute() + def __iter__(self): + class EnumAttribute(object): + name = '' + value = 0 + return [EnumAttribute()] + def __reversed__(self): + class EnumAttribute(object): + name = '' + value = 0 + return (EnumAttribute, ) + def __next__(self): + return next(iter(self)) + def __getitem__(self, attr): + class Value(object): + @property + def name(self): + return '' + @property + def value(self): + return attr + + return Value() + __members__ = [''] + """ + ) + class_node = infer_func_form(node, enum_meta, context=context, enum=True)[0] + return iter([class_node.instantiate_class()]) + + +INT_FLAG_ADDITION_METHODS = """ + def __or__(self, other): + return {name}(self.value | other.value) + def __and__(self, other): + return {name}(self.value & other.value) + def __xor__(self, other): + return {name}(self.value ^ other.value) + def __add__(self, other): + return {name}(self.value + other.value) + def __div__(self, other): + return {name}(self.value / other.value) + def __invert__(self): + return {name}(~self.value) + def __mul__(self, other): + return {name}(self.value * other.value) +""" + + +def infer_enum_class(node): + """ Specific inference for enums. """ + for basename in node.basenames: + # TODO: doesn't handle subclasses yet. This implementation + # is a hack to support enums. + if basename not in ENUM_BASE_NAMES: + continue + if node.root().name == "enum": + # Skip if the class is directly from enum module. + break + for local, values in node.locals.items(): + if any(not isinstance(value, nodes.AssignName) for value in values): + continue + + targets = [] + stmt = values[0].statement() + if isinstance(stmt, nodes.Assign): + if isinstance(stmt.targets[0], nodes.Tuple): + targets = stmt.targets[0].itered() + else: + targets = stmt.targets + elif isinstance(stmt, nodes.AnnAssign): + targets = [stmt.target] + + inferred_return_value = None + if isinstance(stmt, nodes.Assign): + if isinstance(stmt.value, nodes.Const): + if isinstance(stmt.value.value, str): + inferred_return_value = repr(stmt.value.value) + else: + inferred_return_value = stmt.value.value + else: + inferred_return_value = stmt.value.as_string() + + new_targets = [] + for target in targets: + # Replace all the assignments with our mocked class. + classdef = dedent( + """ + class {name}({types}): + @property + def value(self): + return {return_value} + @property + def name(self): + return "{name}" + """.format( + name=target.name, + types=", ".join(node.basenames), + return_value=inferred_return_value, + ) + ) + if "IntFlag" in basename: + # Alright, we need to add some additional methods. + # Unfortunately we still can't infer the resulting objects as + # Enum members, but once we'll be able to do that, the following + # should result in some nice symbolic execution + classdef += INT_FLAG_ADDITION_METHODS.format(name=target.name) + + fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name] + fake.parent = target.parent + for method in node.mymethods(): + fake.locals[method.name] = [method] + new_targets.append(fake.instantiate_class()) + node.locals[local] = new_targets + break + return node + + +def infer_typing_namedtuple_class(class_node, context=None): + """Infer a subclass of typing.NamedTuple""" + # Check if it has the corresponding bases + annassigns_fields = [ + annassign.target.name + for annassign in class_node.body + if isinstance(annassign, nodes.AnnAssign) + ] + code = dedent( + """ + from collections import namedtuple + namedtuple({typename!r}, {fields!r}) + """ + ).format(typename=class_node.name, fields=",".join(annassigns_fields)) + node = extract_node(code) + generated_class_node = next(infer_named_tuple(node, context)) + for method in class_node.mymethods(): + generated_class_node.locals[method.name] = [method] + return iter((generated_class_node,)) + + +def infer_typing_namedtuple(node, context=None): + """Infer a typing.NamedTuple(...) call.""" + # This is essentially a namedtuple with different arguments + # so we extract the args and infer a named tuple. + try: + func = next(node.func.infer()) + except InferenceError: + raise UseInferenceDefault + + if func.qname() != "typing.NamedTuple": + raise UseInferenceDefault + + if len(node.args) != 2: + raise UseInferenceDefault + + if not isinstance(node.args[1], (nodes.List, nodes.Tuple)): + raise UseInferenceDefault + + names = [] + for elt in node.args[1].elts: + if not isinstance(elt, (nodes.List, nodes.Tuple)): + raise UseInferenceDefault + if len(elt.elts) != 2: + raise UseInferenceDefault + names.append(elt.elts[0].as_string()) + + typename = node.args[0].as_string() + if names: + field_names = "({},)".format(",".join(names)) + else: + field_names = "''" + node = extract_node( + "namedtuple({typename}, {fields})".format(typename=typename, fields=field_names) + ) + return infer_named_tuple(node, context) + + +MANAGER.register_transform( + nodes.Call, inference_tip(infer_named_tuple), _looks_like_namedtuple +) +MANAGER.register_transform(nodes.Call, inference_tip(infer_enum), _looks_like_enum) +MANAGER.register_transform( + nodes.ClassDef, + infer_enum_class, + predicate=lambda cls: any( + basename for basename in cls.basenames if basename in ENUM_BASE_NAMES + ), +) +MANAGER.register_transform( + nodes.ClassDef, inference_tip(infer_typing_namedtuple_class), _has_namedtuple_base +) +MANAGER.register_transform( + nodes.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_nose.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_nose.py new file mode 100644 index 0000000..7b12d76 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_nose.py @@ -0,0 +1,77 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Hooks for nose library.""" + +import re +import textwrap + +import astroid +import astroid.builder + +_BUILDER = astroid.builder.AstroidBuilder(astroid.MANAGER) + + +def _pep8(name, caps=re.compile("([A-Z])")): + return caps.sub(lambda m: "_" + m.groups()[0].lower(), name) + + +def _nose_tools_functions(): + """Get an iterator of names and bound methods.""" + module = _BUILDER.string_build( + textwrap.dedent( + """ + import unittest + + class Test(unittest.TestCase): + pass + a = Test() + """ + ) + ) + try: + case = next(module["a"].infer()) + except astroid.InferenceError: + return + for method in case.methods(): + if method.name.startswith("assert") and "_" not in method.name: + pep8_name = _pep8(method.name) + yield pep8_name, astroid.BoundMethod(method, case) + if method.name == "assertEqual": + # nose also exports assert_equals. + yield "assert_equals", astroid.BoundMethod(method, case) + + +def _nose_tools_transform(node): + for method_name, method in _nose_tools_functions(): + node.locals[method_name] = [method] + + +def _nose_tools_trivial_transform(): + """Custom transform for the nose.tools module.""" + stub = _BUILDER.string_build("""__all__ = []""") + all_entries = ["ok_", "eq_"] + + for pep8_name, method in _nose_tools_functions(): + all_entries.append(pep8_name) + stub[pep8_name] = method + + # Update the __all__ variable, since nose.tools + # does this manually with .append. + all_assign = stub["__all__"].parent + all_object = astroid.List(all_entries) + all_object.parent = all_assign + all_assign.value = all_object + return stub + + +astroid.register_module_extender( + astroid.MANAGER, "nose.tools.trivial", _nose_tools_trivial_transform +) +astroid.MANAGER.register_transform( + astroid.Module, _nose_tools_transform, lambda n: n.name == "nose.tools" +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_numpy.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_numpy.py new file mode 100644 index 0000000..e6dfd8c --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_numpy.py @@ -0,0 +1,557 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2017-2018 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy.""" + +import functools +import astroid + + +def numpy_random_mtrand_transform(): + return astroid.parse( + """ + def beta(a, b, size=None): return uninferable + def binomial(n, p, size=None): return uninferable + def bytes(length): return uninferable + def chisquare(df, size=None): return uninferable + def choice(a, size=None, replace=True, p=None): return uninferable + def dirichlet(alpha, size=None): return uninferable + def exponential(scale=1.0, size=None): return uninferable + def f(dfnum, dfden, size=None): return uninferable + def gamma(shape, scale=1.0, size=None): return uninferable + def geometric(p, size=None): return uninferable + def get_state(): return uninferable + def gumbel(loc=0.0, scale=1.0, size=None): return uninferable + def hypergeometric(ngood, nbad, nsample, size=None): return uninferable + def laplace(loc=0.0, scale=1.0, size=None): return uninferable + def logistic(loc=0.0, scale=1.0, size=None): return uninferable + def lognormal(mean=0.0, sigma=1.0, size=None): return uninferable + def logseries(p, size=None): return uninferable + def multinomial(n, pvals, size=None): return uninferable + def multivariate_normal(mean, cov, size=None): return uninferable + def negative_binomial(n, p, size=None): return uninferable + def noncentral_chisquare(df, nonc, size=None): return uninferable + def noncentral_f(dfnum, dfden, nonc, size=None): return uninferable + def normal(loc=0.0, scale=1.0, size=None): return uninferable + def pareto(a, size=None): return uninferable + def permutation(x): return uninferable + def poisson(lam=1.0, size=None): return uninferable + def power(a, size=None): return uninferable + def rand(*args): return uninferable + def randint(low, high=None, size=None, dtype='l'): return uninferable + def randn(*args): return uninferable + def random_integers(low, high=None, size=None): return uninferable + def random_sample(size=None): return uninferable + def rayleigh(scale=1.0, size=None): return uninferable + def seed(seed=None): return uninferable + def set_state(state): return uninferable + def shuffle(x): return uninferable + def standard_cauchy(size=None): return uninferable + def standard_exponential(size=None): return uninferable + def standard_gamma(shape, size=None): return uninferable + def standard_normal(size=None): return uninferable + def standard_t(df, size=None): return uninferable + def triangular(left, mode, right, size=None): return uninferable + def uniform(low=0.0, high=1.0, size=None): return uninferable + def vonmises(mu, kappa, size=None): return uninferable + def wald(mean, scale, size=None): return uninferable + def weibull(a, size=None): return uninferable + def zipf(a, size=None): return uninferable + """ + ) + + +def numpy_core_umath_transform(): + ufunc_optional_keyword_arguments = ( + """out=None, where=True, casting='same_kind', order='K', """ + """dtype=None, subok=True""" + ) + return astroid.parse( + """ + # Constants + e = 2.718281828459045 + euler_gamma = 0.5772156649015329 + + # No arg functions + def geterrobj(): return uninferable + + # One arg functions + def seterrobj(errobj): return uninferable + + # One arg functions with optional kwargs + def arccos(x, {opt_args:s}): return uninferable + def arccosh(x, {opt_args:s}): return uninferable + def arcsin(x, {opt_args:s}): return uninferable + def arcsinh(x, {opt_args:s}): return uninferable + def arctan(x, {opt_args:s}): return uninferable + def arctanh(x, {opt_args:s}): return uninferable + def cbrt(x, {opt_args:s}): return uninferable + def conj(x, {opt_args:s}): return uninferable + def conjugate(x, {opt_args:s}): return uninferable + def cosh(x, {opt_args:s}): return uninferable + def deg2rad(x, {opt_args:s}): return uninferable + def degrees(x, {opt_args:s}): return uninferable + def exp2(x, {opt_args:s}): return uninferable + def expm1(x, {opt_args:s}): return uninferable + def fabs(x, {opt_args:s}): return uninferable + def frexp(x, {opt_args:s}): return uninferable + def isfinite(x, {opt_args:s}): return uninferable + def isinf(x, {opt_args:s}): return uninferable + def log(x, {opt_args:s}): return uninferable + def log1p(x, {opt_args:s}): return uninferable + def log2(x, {opt_args:s}): return uninferable + def logical_not(x, {opt_args:s}): return uninferable + def modf(x, {opt_args:s}): return uninferable + def negative(x, {opt_args:s}): return uninferable + def rad2deg(x, {opt_args:s}): return uninferable + def radians(x, {opt_args:s}): return uninferable + def reciprocal(x, {opt_args:s}): return uninferable + def rint(x, {opt_args:s}): return uninferable + def sign(x, {opt_args:s}): return uninferable + def signbit(x, {opt_args:s}): return uninferable + def sinh(x, {opt_args:s}): return uninferable + def spacing(x, {opt_args:s}): return uninferable + def square(x, {opt_args:s}): return uninferable + def tan(x, {opt_args:s}): return uninferable + def tanh(x, {opt_args:s}): return uninferable + def trunc(x, {opt_args:s}): return uninferable + + # Two args functions with optional kwargs + def bitwise_and(x1, x2, {opt_args:s}): return uninferable + def bitwise_or(x1, x2, {opt_args:s}): return uninferable + def bitwise_xor(x1, x2, {opt_args:s}): return uninferable + def copysign(x1, x2, {opt_args:s}): return uninferable + def divide(x1, x2, {opt_args:s}): return uninferable + def equal(x1, x2, {opt_args:s}): return uninferable + def float_power(x1, x2, {opt_args:s}): return uninferable + def floor_divide(x1, x2, {opt_args:s}): return uninferable + def fmax(x1, x2, {opt_args:s}): return uninferable + def fmin(x1, x2, {opt_args:s}): return uninferable + def fmod(x1, x2, {opt_args:s}): return uninferable + def greater(x1, x2, {opt_args:s}): return uninferable + def hypot(x1, x2, {opt_args:s}): return uninferable + def ldexp(x1, x2, {opt_args:s}): return uninferable + def left_shift(x1, x2, {opt_args:s}): return uninferable + def less(x1, x2, {opt_args:s}): return uninferable + def logaddexp(x1, x2, {opt_args:s}): return uninferable + def logaddexp2(x1, x2, {opt_args:s}): return uninferable + def logical_and(x1, x2, {opt_args:s}): return uninferable + def logical_or(x1, x2, {opt_args:s}): return uninferable + def logical_xor(x1, x2, {opt_args:s}): return uninferable + def maximum(x1, x2, {opt_args:s}): return uninferable + def minimum(x1, x2, {opt_args:s}): return uninferable + def nextafter(x1, x2, {opt_args:s}): return uninferable + def not_equal(x1, x2, {opt_args:s}): return uninferable + def power(x1, x2, {opt_args:s}): return uninferable + def remainder(x1, x2, {opt_args:s}): return uninferable + def right_shift(x1, x2, {opt_args:s}): return uninferable + def subtract(x1, x2, {opt_args:s}): return uninferable + def true_divide(x1, x2, {opt_args:s}): return uninferable + """.format( + opt_args=ufunc_optional_keyword_arguments + ) + ) + + +def numpy_core_numerictypes_transform(): + return astroid.parse( + """ + # different types defined in numerictypes.py + class generic(object): + def __init__(self, value): + self.T = None + self.base = None + self.data = None + self.dtype = None + self.flags = None + self.flat = None + self.imag = None + self.itemsize = None + self.nbytes = None + self.ndim = None + self.real = None + self.size = None + self.strides = None + + def all(self): return uninferable + def any(self): return uninferable + def argmax(self): return uninferable + def argmin(self): return uninferable + def argsort(self): return uninferable + def astype(self): return uninferable + def base(self): return uninferable + def byteswap(self): return uninferable + def choose(self): return uninferable + def clip(self): return uninferable + def compress(self): return uninferable + def conj(self): return uninferable + def conjugate(self): return uninferable + def copy(self): return uninferable + def cumprod(self): return uninferable + def cumsum(self): return uninferable + def data(self): return uninferable + def diagonal(self): return uninferable + def dtype(self): return uninferable + def dump(self): return uninferable + def dumps(self): return uninferable + def fill(self): return uninferable + def flags(self): return uninferable + def flat(self): return uninferable + def flatten(self): return uninferable + def getfield(self): return uninferable + def imag(self): return uninferable + def item(self): return uninferable + def itemset(self): return uninferable + def itemsize(self): return uninferable + def max(self): return uninferable + def mean(self): return uninferable + def min(self): return uninferable + def nbytes(self): return uninferable + def ndim(self): return uninferable + def newbyteorder(self): return uninferable + def nonzero(self): return uninferable + def prod(self): return uninferable + def ptp(self): return uninferable + def put(self): return uninferable + def ravel(self): return uninferable + def real(self): return uninferable + def repeat(self): return uninferable + def reshape(self): return uninferable + def resize(self): return uninferable + def round(self): return uninferable + def searchsorted(self): return uninferable + def setfield(self): return uninferable + def setflags(self): return uninferable + def shape(self): return uninferable + def size(self): return uninferable + def sort(self): return uninferable + def squeeze(self): return uninferable + def std(self): return uninferable + def strides(self): return uninferable + def sum(self): return uninferable + def swapaxes(self): return uninferable + def take(self): return uninferable + def tobytes(self): return uninferable + def tofile(self): return uninferable + def tolist(self): return uninferable + def tostring(self): return uninferable + def trace(self): return uninferable + def transpose(self): return uninferable + def var(self): return uninferable + def view(self): return uninferable + + + class dtype(object): + def __init__(self, obj, align=False, copy=False): + self.alignment = None + self.base = None + self.byteorder = None + self.char = None + self.descr = None + self.fields = None + self.flags = None + self.hasobject = None + self.isalignedstruct = None + self.isbuiltin = None + self.isnative = None + self.itemsize = None + self.kind = None + self.metadata = None + self.name = None + self.names = None + self.num = None + self.shape = None + self.str = None + self.subdtype = None + self.type = None + + def newbyteorder(self, new_order='S'): return uninferable + def __neg__(self): return uninferable + + + class ndarray(object): + def __init__(self, shape, dtype=float, buffer=None, offset=0, + strides=None, order=None): + self.T = None + self.base = None + self.ctypes = None + self.data = None + self.dtype = None + self.flags = None + self.flat = None + self.imag = None + self.itemsize = None + self.nbytes = None + self.ndim = None + self.real = None + self.shape = None + self.size = None + self.strides = None + + def __neg__(self): return uninferable + def __inv__(self): return uninferable + def __invert__(self): return uninferable + def all(self): return uninferable + def any(self): return uninferable + def argmax(self): return uninferable + def argmin(self): return uninferable + def argpartition(self): return uninferable + def argsort(self): return uninferable + def astype(self): return uninferable + def byteswap(self): return uninferable + def choose(self): return uninferable + def clip(self): return uninferable + def compress(self): return uninferable + def conj(self): return uninferable + def conjugate(self): return uninferable + def copy(self): return uninferable + def cumprod(self): return uninferable + def cumsum(self): return uninferable + def diagonal(self): return uninferable + def dot(self): return uninferable + def dump(self): return uninferable + def dumps(self): return uninferable + def fill(self): return uninferable + def flatten(self): return uninferable + def getfield(self): return uninferable + def item(self): return uninferable + def itemset(self): return uninferable + def max(self): return uninferable + def mean(self): return uninferable + def min(self): return uninferable + def newbyteorder(self): return uninferable + def nonzero(self): return uninferable + def partition(self): return uninferable + def prod(self): return uninferable + def ptp(self): return uninferable + def put(self): return uninferable + def ravel(self): return uninferable + def repeat(self): return uninferable + def reshape(self): return uninferable + def resize(self): return uninferable + def round(self): return uninferable + def searchsorted(self): return uninferable + def setfield(self): return uninferable + def setflags(self): return uninferable + def sort(self): return uninferable + def squeeze(self): return uninferable + def std(self): return uninferable + def sum(self): return uninferable + def swapaxes(self): return uninferable + def take(self): return uninferable + def tobytes(self): return uninferable + def tofile(self): return uninferable + def tolist(self): return uninferable + def tostring(self): return uninferable + def trace(self): return uninferable + def transpose(self): return uninferable + def var(self): return uninferable + def view(self): return uninferable + + + class busdaycalendar(object): + def __init__(self, weekmask='1111100', holidays=None): + self.holidays = None + self.weekmask = None + + class flexible(generic): pass + class bool_(generic): pass + class number(generic): + def __neg__(self): return uninferable + class datetime64(generic): pass + + + class void(flexible): + def __init__(self, *args, **kwargs): + self.base = None + self.dtype = None + self.flags = None + def getfield(self): return uninferable + def setfield(self): return uninferable + + + class character(flexible): pass + + + class integer(number): + def __init__(self, value): + self.denominator = None + self.numerator = None + + + class inexact(number): pass + + + class str_(str, character): + def maketrans(self, x, y=None, z=None): return uninferable + + + class bytes_(bytes, character): + def fromhex(self, string): return uninferable + def maketrans(self, frm, to): return uninferable + + + class signedinteger(integer): pass + + + class unsignedinteger(integer): pass + + + class complexfloating(inexact): pass + + + class floating(inexact): pass + + + class float64(floating, float): + def fromhex(self, string): return uninferable + + + class uint64(unsignedinteger): pass + class complex64(complexfloating): pass + class int16(signedinteger): pass + class float96(floating): pass + class int8(signedinteger): pass + class uint32(unsignedinteger): pass + class uint8(unsignedinteger): pass + class _typedict(dict): pass + class complex192(complexfloating): pass + class timedelta64(signedinteger): pass + class int32(signedinteger): pass + class uint16(unsignedinteger): pass + class float32(floating): pass + class complex128(complexfloating, complex): pass + class float16(floating): pass + class int64(signedinteger): pass + + buffer_type = memoryview + bool8 = bool_ + byte = int8 + bytes0 = bytes_ + cdouble = complex128 + cfloat = complex128 + clongdouble = complex192 + clongfloat = complex192 + complex_ = complex128 + csingle = complex64 + double = float64 + float_ = float64 + half = float16 + int0 = int32 + int_ = int32 + intc = int32 + intp = int32 + long = int32 + longcomplex = complex192 + longdouble = float96 + longfloat = float96 + longlong = int64 + object0 = object_ + object_ = object_ + short = int16 + single = float32 + singlecomplex = complex64 + str0 = str_ + string_ = bytes_ + ubyte = uint8 + uint = uint32 + uint0 = uint32 + uintc = uint32 + uintp = uint32 + ulonglong = uint64 + unicode = str_ + unicode_ = str_ + ushort = uint16 + void0 = void + """ + ) + + +def numpy_funcs(): + return astroid.parse( + """ + import builtins + def sum(a, axis=None, dtype=None, out=None, keepdims=None): + return builtins.sum(a) + """ + ) + + +def _looks_like_numpy_function(func_name, numpy_module_name, node): + """ + Return True if the current node correspond to the function inside + the numpy module in parameters + + :param node: the current node + :type node: FunctionDef + :param func_name: name of the function + :type func_name: str + :param numpy_module_name: name of the numpy module + :type numpy_module_name: str + :return: True if the current node correspond to the function looked for + :rtype: bool + """ + return node.name == func_name and node.parent.name == numpy_module_name + + +def numpy_function_infer_call_result(node): + """ + A wrapper around infer_call_result method bounded to the node. + + :param node: the node which infer_call_result should be filtered + :type node: FunctionDef + :return: a function that filter the results of the call to node.infer_call_result + :rtype: function + """ + #  Put the origin infer_call_result method into the closure + origin_infer_call_result = node.infer_call_result + + def infer_call_result_wrapper(caller=None, context=None): + """ + Call the origin infer_call_result method bounded to the node instance and + filter the results to remove List and Tuple instances + """ + unfiltered_infer_call_result = origin_infer_call_result(caller, context) + return ( + x + for x in unfiltered_infer_call_result + if not isinstance(x, (astroid.List, astroid.Tuple)) + ) + + return infer_call_result_wrapper + + +def _replace_numpy_function_infer_call_result(node, context=None): + node.infer_call_result = numpy_function_infer_call_result(node) + return + + +astroid.MANAGER.register_transform( + astroid.FunctionDef, + _replace_numpy_function_infer_call_result, + functools.partial( + _looks_like_numpy_function, "linspace", "numpy.core.function_base" + ), +) + +astroid.MANAGER.register_transform( + astroid.FunctionDef, + _replace_numpy_function_infer_call_result, + functools.partial(_looks_like_numpy_function, "array", "numpy.core.records"), +) + +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.umath", numpy_core_umath_transform +) +astroid.register_module_extender( + astroid.MANAGER, "numpy.random.mtrand", numpy_random_mtrand_transform +) +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.numerictypes", numpy_core_numerictypes_transform +) +astroid.register_module_extender(astroid.MANAGER, "numpy", numpy_funcs) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_pkg_resources.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_pkg_resources.py new file mode 100644 index 0000000..25e7649 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_pkg_resources.py @@ -0,0 +1,75 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +import astroid +from astroid import parse +from astroid import inference_tip +from astroid import register_module_extender +from astroid import MANAGER + + +def pkg_resources_transform(): + return parse( + """ +def require(*requirements): + return pkg_resources.working_set.require(*requirements) + +def run_script(requires, script_name): + return pkg_resources.working_set.run_script(requires, script_name) + +def iter_entry_points(group, name=None): + return pkg_resources.working_set.iter_entry_points(group, name) + +def resource_exists(package_or_requirement, resource_name): + return get_provider(package_or_requirement).has_resource(resource_name) + +def resource_isdir(package_or_requirement, resource_name): + return get_provider(package_or_requirement).resource_isdir( + resource_name) + +def resource_filename(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name) + +def resource_stream(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name) + +def resource_string(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_string( + self, resource_name) + +def resource_listdir(package_or_requirement, resource_name): + return get_provider(package_or_requirement).resource_listdir( + resource_name) + +def extraction_error(): + pass + +def get_cache_path(archive_name, names=()): + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name+'-tmp', *names) + return target_path + +def postprocess(tempname, filename): + pass + +def set_extraction_path(path): + pass + +def cleanup_resources(force=False): + pass + +def get_distribution(dist): + return Distribution(dist) + +_namespace_packages = {} +""" + ) + + +register_module_extender(MANAGER, "pkg_resources", pkg_resources_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_pytest.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_pytest.py new file mode 100644 index 0000000..d7e3ac8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_pytest.py @@ -0,0 +1,88 @@ +# Copyright (c) 2014-2016 Claudiu Popa +# Copyright (c) 2014 Jeff Quast +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2016 Florian Bruhin +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for pytest.""" +from __future__ import absolute_import +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def pytest_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +try: + import _pytest.mark + import _pytest.recwarn + import _pytest.runner + import _pytest.python + import _pytest.skipping + import _pytest.assertion +except ImportError: + pass +else: + deprecated_call = _pytest.recwarn.deprecated_call + warns = _pytest.recwarn.warns + + exit = _pytest.runner.exit + fail = _pytest.runner.fail + skip = _pytest.runner.skip + importorskip = _pytest.runner.importorskip + + xfail = _pytest.skipping.xfail + mark = _pytest.mark.MarkGenerator() + raises = _pytest.python.raises + + # New in pytest 3.0 + try: + approx = _pytest.python.approx + register_assert_rewrite = _pytest.assertion.register_assert_rewrite + except AttributeError: + pass + + +# Moved in pytest 3.0 + +try: + import _pytest.freeze_support + freeze_includes = _pytest.freeze_support.freeze_includes +except ImportError: + try: + import _pytest.genscript + freeze_includes = _pytest.genscript.freeze_includes + except ImportError: + pass + +try: + import _pytest.debugging + set_trace = _pytest.debugging.pytestPDB().set_trace +except ImportError: + try: + import _pytest.pdb + set_trace = _pytest.pdb.pytestPDB().set_trace + except ImportError: + pass + +try: + import _pytest.fixtures + fixture = _pytest.fixtures.fixture + yield_fixture = _pytest.fixtures.yield_fixture +except ImportError: + try: + import _pytest.python + fixture = _pytest.python.fixture + yield_fixture = _pytest.python.yield_fixture + except ImportError: + pass +""" + ) + + +register_module_extender(MANAGER, "pytest", pytest_transform) +register_module_extender(MANAGER, "py.test", pytest_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_qt.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_qt.py new file mode 100644 index 0000000..d65f218 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_qt.py @@ -0,0 +1,82 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2017 Roy Wright +# Copyright (c) 2018 Ashley Whetter + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the PyQT library.""" + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid import nodes +from astroid import parse + + +def _looks_like_signal(node, signal_name="pyqtSignal"): + if "__class__" in node.instance_attrs: + try: + cls = node.instance_attrs["__class__"][0] + return cls.name == signal_name + except AttributeError: + # return False if the cls does not have a name attribute + pass + return False + + +def transform_pyqt_signal(node): + module = parse( + """ + class pyqtSignal(object): + def connect(self, slot, type=None, no_receiver_check=False): + pass + def disconnect(self, slot): + pass + def emit(self, *args): + pass + """ + ) + signal_cls = module["pyqtSignal"] + node.instance_attrs["emit"] = signal_cls["emit"] + node.instance_attrs["disconnect"] = signal_cls["disconnect"] + node.instance_attrs["connect"] = signal_cls["connect"] + + +def transform_pyside_signal(node): + module = parse( + """ + class NotPySideSignal(object): + def connect(self, receiver, type=None): + pass + def disconnect(self, receiver): + pass + def emit(self, *args): + pass + """ + ) + signal_cls = module["NotPySideSignal"] + node.instance_attrs["connect"] = signal_cls["connect"] + node.instance_attrs["disconnect"] = signal_cls["disconnect"] + node.instance_attrs["emit"] = signal_cls["emit"] + + +def pyqt4_qtcore_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +def SIGNAL(signal_name): pass + +class QObject(object): + def emit(self, signal): pass +""" + ) + + +register_module_extender(MANAGER, "PyQt4.QtCore", pyqt4_qtcore_transform) +MANAGER.register_transform(nodes.FunctionDef, transform_pyqt_signal, _looks_like_signal) +MANAGER.register_transform( + nodes.ClassDef, + transform_pyside_signal, + lambda node: node.qname() == "PySide.QtCore.Signal", +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_random.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_random.py new file mode 100644 index 0000000..5ec858a --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_random.py @@ -0,0 +1,75 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import random + +import astroid +from astroid import helpers +from astroid import MANAGER + + +ACCEPTED_ITERABLES_FOR_SAMPLE = (astroid.List, astroid.Set, astroid.Tuple) + + +def _clone_node_with_lineno(node, parent, lineno): + cls = node.__class__ + other_fields = node._other_fields + _astroid_fields = node._astroid_fields + init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent} + postinit_params = {param: getattr(node, param) for param in _astroid_fields} + if other_fields: + init_params.update({param: getattr(node, param) for param in other_fields}) + new_node = cls(**init_params) + if hasattr(node, "postinit") and _astroid_fields: + new_node.postinit(**postinit_params) + return new_node + + +def infer_random_sample(node, context=None): + if len(node.args) != 2: + raise astroid.UseInferenceDefault + + length = node.args[1] + if not isinstance(length, astroid.Const): + raise astroid.UseInferenceDefault + if not isinstance(length.value, int): + raise astroid.UseInferenceDefault + + inferred_sequence = helpers.safe_infer(node.args[0], context=context) + if not inferred_sequence: + raise astroid.UseInferenceDefault + + if not isinstance(inferred_sequence, ACCEPTED_ITERABLES_FOR_SAMPLE): + raise astroid.UseInferenceDefault + + if length.value > len(inferred_sequence.elts): + # In this case, this will raise a ValueError + raise astroid.UseInferenceDefault + + try: + elts = random.sample(inferred_sequence.elts, length.value) + except ValueError: + raise astroid.UseInferenceDefault + + new_node = astroid.List( + lineno=node.lineno, col_offset=node.col_offset, parent=node.scope() + ) + new_elts = [ + _clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno) + for elt in elts + ] + new_node.postinit(new_elts) + return iter((new_node,)) + + +def _looks_like_random_sample(node): + func = node.func + if isinstance(func, astroid.Attribute): + return func.attrname == "sample" + if isinstance(func, astroid.Name): + return func.name == "sample" + return False + + +MANAGER.register_transform( + astroid.Call, astroid.inference_tip(infer_random_sample), _looks_like_random_sample +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_re.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_re.py new file mode 100644 index 0000000..c7ee51a --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_re.py @@ -0,0 +1,36 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys +import astroid + +PY36 = sys.version_info >= (3, 6) + +if PY36: + # Since Python 3.6 there is the RegexFlag enum + # where every entry will be exposed via updating globals() + + def _re_transform(): + return astroid.parse( + """ + import sre_compile + ASCII = sre_compile.SRE_FLAG_ASCII + IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE + LOCALE = sre_compile.SRE_FLAG_LOCALE + UNICODE = sre_compile.SRE_FLAG_UNICODE + MULTILINE = sre_compile.SRE_FLAG_MULTILINE + DOTALL = sre_compile.SRE_FLAG_DOTALL + VERBOSE = sre_compile.SRE_FLAG_VERBOSE + A = ASCII + I = IGNORECASE + L = LOCALE + U = UNICODE + M = MULTILINE + S = DOTALL + X = VERBOSE + TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE + T = TEMPLATE + DEBUG = sre_compile.SRE_FLAG_DEBUG + """ + ) + + astroid.register_module_extender(astroid.MANAGER, "re", _re_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_six.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_six.py new file mode 100644 index 0000000..b342fbf --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_six.py @@ -0,0 +1,200 @@ +# Copyright (c) 2014-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for six module.""" + +from textwrap import dedent + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid.exceptions import ( + AstroidBuildingError, + InferenceError, + AttributeInferenceError, +) +from astroid import nodes + + +SIX_ADD_METACLASS = "six.add_metaclass" + + +def _indent(text, prefix, predicate=None): + """Adds 'prefix' to the beginning of selected lines in 'text'. + + If 'predicate' is provided, 'prefix' will only be added to the lines + where 'predicate(line)' is True. If 'predicate' is not provided, + it will default to adding 'prefix' to all non-empty lines that do not + consist solely of whitespace characters. + """ + if predicate is None: + predicate = lambda line: line.strip() + + def prefixed_lines(): + for line in text.splitlines(True): + yield prefix + line if predicate(line) else line + + return "".join(prefixed_lines()) + + +_IMPORTS = """ +import _io +cStringIO = _io.StringIO +filter = filter +from itertools import filterfalse +input = input +from sys import intern +map = map +range = range +from imp import reload as reload_module +from functools import reduce +from shlex import quote as shlex_quote +from io import StringIO +from collections import UserDict, UserList, UserString +xrange = range +zip = zip +from itertools import zip_longest +import builtins +import configparser +import copyreg +import _dummy_thread +import http.cookiejar as http_cookiejar +import http.cookies as http_cookies +import html.entities as html_entities +import html.parser as html_parser +import http.client as http_client +import http.server as http_server +BaseHTTPServer = CGIHTTPServer = SimpleHTTPServer = http.server +import pickle as cPickle +import queue +import reprlib +import socketserver +import _thread +import winreg +import xmlrpc.server as xmlrpc_server +import xmlrpc.client as xmlrpc_client +import urllib.robotparser as urllib_robotparser +import email.mime.multipart as email_mime_multipart +import email.mime.nonmultipart as email_mime_nonmultipart +import email.mime.text as email_mime_text +import email.mime.base as email_mime_base +import urllib.parse as urllib_parse +import urllib.error as urllib_error +import tkinter +import tkinter.dialog as tkinter_dialog +import tkinter.filedialog as tkinter_filedialog +import tkinter.scrolledtext as tkinter_scrolledtext +import tkinter.simpledialog as tkinder_simpledialog +import tkinter.tix as tkinter_tix +import tkinter.ttk as tkinter_ttk +import tkinter.constants as tkinter_constants +import tkinter.dnd as tkinter_dnd +import tkinter.colorchooser as tkinter_colorchooser +import tkinter.commondialog as tkinter_commondialog +import tkinter.filedialog as tkinter_tkfiledialog +import tkinter.font as tkinter_font +import tkinter.messagebox as tkinter_messagebox +import urllib +import urllib.request as urllib_request +import urllib.robotparser as urllib_robotparser +import urllib.parse as urllib_parse +import urllib.error as urllib_error +""" + + +def six_moves_transform(): + code = dedent( + """ + class Moves(object): + {} + moves = Moves() + """ + ).format(_indent(_IMPORTS, " ")) + module = AstroidBuilder(MANAGER).string_build(code) + module.name = "six.moves" + return module + + +def _six_fail_hook(modname): + """Fix six.moves imports due to the dynamic nature of this + class. + + Construct a pseudo-module which contains all the necessary imports + for six + + :param modname: Name of failed module + :type modname: str + + :return: An astroid module + :rtype: nodes.Module + """ + + attribute_of = modname != "six.moves" and modname.startswith("six.moves") + if modname != "six.moves" and not attribute_of: + raise AstroidBuildingError(modname=modname) + module = AstroidBuilder(MANAGER).string_build(_IMPORTS) + module.name = "six.moves" + if attribute_of: + # Facilitate import of submodules in Moves + start_index = len(module.name) + attribute = modname[start_index:].lstrip(".").replace(".", "_") + try: + import_attr = module.getattr(attribute)[0] + except AttributeInferenceError: + raise AstroidBuildingError(modname=modname) + if isinstance(import_attr, nodes.Import): + submodule = MANAGER.ast_from_module_name(import_attr.names[0][0]) + return submodule + # Let dummy submodule imports pass through + # This will cause an Uninferable result, which is okay + return module + + +def _looks_like_decorated_with_six_add_metaclass(node): + if not node.decorators: + return False + + for decorator in node.decorators.nodes: + if not isinstance(decorator, nodes.Call): + continue + if decorator.func.as_string() == SIX_ADD_METACLASS: + return True + return False + + +def transform_six_add_metaclass(node): + """Check if the given class node is decorated with *six.add_metaclass* + + If so, inject its argument as the metaclass of the underlying class. + """ + if not node.decorators: + return + + for decorator in node.decorators.nodes: + if not isinstance(decorator, nodes.Call): + continue + + try: + func = next(decorator.func.infer()) + except InferenceError: + continue + if func.qname() == SIX_ADD_METACLASS and decorator.args: + metaclass = decorator.args[0] + node._metaclass = metaclass + return node + + +register_module_extender(MANAGER, "six", six_moves_transform) +register_module_extender( + MANAGER, "requests.packages.urllib3.packages.six", six_moves_transform +) +MANAGER.register_failed_import_hook(_six_fail_hook) +MANAGER.register_transform( + nodes.ClassDef, + transform_six_add_metaclass, + _looks_like_decorated_with_six_add_metaclass, +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_ssl.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_ssl.py new file mode 100644 index 0000000..893d8a2 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_ssl.py @@ -0,0 +1,74 @@ +# Copyright (c) 2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the ssl library.""" + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid import nodes +from astroid import parse + + +def ssl_transform(): + return parse( + """ + from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION + from _ssl import _SSLContext, MemoryBIO + from _ssl import ( + SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, + SSLSyscallError, SSLEOFError, + ) + from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED + from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj + from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes + try: + from _ssl import RAND_egd + except ImportError: + # LibreSSL does not provide RAND_egd + pass + from _ssl import (OP_ALL, OP_CIPHER_SERVER_PREFERENCE, + OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3, + OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2, + OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE) + + from _ssl import (ALERT_DESCRIPTION_ACCESS_DENIED, ALERT_DESCRIPTION_BAD_CERTIFICATE, + ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE, + ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE, + ALERT_DESCRIPTION_BAD_RECORD_MAC, + ALERT_DESCRIPTION_CERTIFICATE_EXPIRED, + ALERT_DESCRIPTION_CERTIFICATE_REVOKED, + ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN, + ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE, + ALERT_DESCRIPTION_CLOSE_NOTIFY, ALERT_DESCRIPTION_DECODE_ERROR, + ALERT_DESCRIPTION_DECOMPRESSION_FAILURE, + ALERT_DESCRIPTION_DECRYPT_ERROR, + ALERT_DESCRIPTION_HANDSHAKE_FAILURE, + ALERT_DESCRIPTION_ILLEGAL_PARAMETER, + ALERT_DESCRIPTION_INSUFFICIENT_SECURITY, + ALERT_DESCRIPTION_INTERNAL_ERROR, + ALERT_DESCRIPTION_NO_RENEGOTIATION, + ALERT_DESCRIPTION_PROTOCOL_VERSION, + ALERT_DESCRIPTION_RECORD_OVERFLOW, + ALERT_DESCRIPTION_UNEXPECTED_MESSAGE, + ALERT_DESCRIPTION_UNKNOWN_CA, + ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY, + ALERT_DESCRIPTION_UNRECOGNIZED_NAME, + ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE, + ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION, + ALERT_DESCRIPTION_USER_CANCELLED) + from _ssl import (SSL_ERROR_EOF, SSL_ERROR_INVALID_ERROR_CODE, SSL_ERROR_SSL, + SSL_ERROR_SYSCALL, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_READ, + SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_X509_LOOKUP, SSL_ERROR_ZERO_RETURN) + from _ssl import VERIFY_CRL_CHECK_CHAIN, VERIFY_CRL_CHECK_LEAF, VERIFY_DEFAULT, VERIFY_X509_STRICT + from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN + from _ssl import _OPENSSL_API_VERSION + from _ssl import PROTOCOL_SSLv23, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2 + from _ssl import PROTOCOL_TLS, PROTOCOL_TLS_CLIENT, PROTOCOL_TLS_SERVER + """ + ) + + +register_module_extender(MANAGER, "ssl", ssl_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_subprocess.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_subprocess.py new file mode 100644 index 0000000..6c46c82 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_subprocess.py @@ -0,0 +1,119 @@ +# Copyright (c) 2016-2017 Claudiu Popa +# Copyright (c) 2017 Hugo +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import sys +import textwrap + +import six + +import astroid + + +PY37 = sys.version_info >= (3, 7) +PY36 = sys.version_info >= (3, 6) +PY34 = sys.version_info >= (3, 4) +PY33 = sys.version_info >= (3, 3) + + +def _subprocess_transform(): + if six.PY3: + communicate = (bytes("string", "ascii"), bytes("string", "ascii")) + communicate_signature = "def communicate(self, input=None, timeout=None)" + if PY37: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=(), *, + encoding=None, errors=None, text=None): + pass + """ + elif PY36: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=(), *, + encoding=None, errors=None): + pass + """ + else: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=()): + pass + """ + else: + communicate = ("string", "string") + communicate_signature = "def communicate(self, input=None)" + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0): + pass + """ + if PY34: + wait_signature = "def wait(self, timeout=None)" + else: + wait_signature = "def wait(self)" + if six.PY3: + ctx_manager = """ + def __enter__(self): return self + def __exit__(self, *args): pass + """ + else: + ctx_manager = "" + py3_args = "" + if PY33: + py3_args = "args = []" + code = textwrap.dedent( + """ + class Popen(object): + returncode = pid = 0 + stdin = stdout = stderr = file() + %(py3_args)s + + %(communicate_signature)s: + return %(communicate)r + %(wait_signature)s: + return self.returncode + def poll(self): + return self.returncode + def send_signal(self, signal): + pass + def terminate(self): + pass + def kill(self): + pass + %(ctx_manager)s + """ + % { + "communicate": communicate, + "communicate_signature": communicate_signature, + "wait_signature": wait_signature, + "ctx_manager": ctx_manager, + "py3_args": py3_args, + } + ) + + init_lines = textwrap.dedent(init).splitlines() + indented_init = "\n".join(" " * 4 + line for line in init_lines) + code += indented_init + return astroid.parse(code) + + +astroid.register_module_extender(astroid.MANAGER, "subprocess", _subprocess_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_threading.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_threading.py new file mode 100644 index 0000000..77f5bde --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_threading.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 Claudiu Popa +# Copyright (c) 2017 Åukasz Rogalski + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import astroid + + +def _thread_transform(): + return astroid.parse( + """ + class lock(object): + def acquire(self, blocking=True, timeout=-1): + pass + def release(self): + pass + def __enter__(self): + return True + def __exit__(self, *args): + pass + + def Lock(): + return lock() + """ + ) + + +astroid.register_module_extender(astroid.MANAGER, "threading", _thread_transform) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_typing.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_typing.py new file mode 100644 index 0000000..9ff7227 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_typing.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017-2018 Claudiu Popa +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2017 David Euresti +# Copyright (c) 2018 Bryce Guinta + +"""Astroid hooks for typing.py support.""" +import typing + +from astroid import ( + MANAGER, + UseInferenceDefault, + extract_node, + inference_tip, + nodes, + InferenceError, +) + + +TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"} +TYPING_TYPEVARS = {"TypeVar", "NewType"} +TYPING_TYPEVARS_QUALIFIED = {"typing.TypeVar", "typing.NewType"} +TYPING_TYPE_TEMPLATE = """ +class Meta(type): + def __getitem__(self, item): + return self + + @property + def __args__(self): + return () + +class {0}(metaclass=Meta): + pass +""" +TYPING_MEMBERS = set(typing.__all__) + + +def looks_like_typing_typevar_or_newtype(node): + func = node.func + if isinstance(func, nodes.Attribute): + return func.attrname in TYPING_TYPEVARS + if isinstance(func, nodes.Name): + return func.name in TYPING_TYPEVARS + return False + + +def infer_typing_typevar_or_newtype(node, context=None): + """Infer a typing.TypeVar(...) or typing.NewType(...) call""" + try: + func = next(node.func.infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault from exc + + if func.qname() not in TYPING_TYPEVARS_QUALIFIED: + raise UseInferenceDefault + if not node.args: + raise UseInferenceDefault + + typename = node.args[0].as_string().strip("'") + node = extract_node(TYPING_TYPE_TEMPLATE.format(typename)) + return node.infer(context=context) + + +def _looks_like_typing_subscript(node): + """Try to figure out if a Subscript node *might* be a typing-related subscript""" + if isinstance(node, nodes.Name): + return node.name in TYPING_MEMBERS + elif isinstance(node, nodes.Attribute): + return node.attrname in TYPING_MEMBERS + elif isinstance(node, nodes.Subscript): + return _looks_like_typing_subscript(node.value) + return False + + +def infer_typing_attr(node, context=None): + """Infer a typing.X[...] subscript""" + try: + value = next(node.value.infer()) + except InferenceError as exc: + raise UseInferenceDefault from exc + + if not value.qname().startswith("typing."): + raise UseInferenceDefault + + node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1])) + return node.infer(context=context) + + +MANAGER.register_transform( + nodes.Call, + inference_tip(infer_typing_typevar_or_newtype), + looks_like_typing_typevar_or_newtype, +) +MANAGER.register_transform( + nodes.Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript +) diff --git a/venv/lib/python3.7/site-packages/astroid/brain/brain_uuid.py b/venv/lib/python3.7/site-packages/astroid/brain/brain_uuid.py new file mode 100644 index 0000000..8bda631 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/brain/brain_uuid.py @@ -0,0 +1,20 @@ +# Copyright (c) 2017 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the UUID module.""" + + +from astroid import MANAGER +from astroid import nodes + + +def _patch_uuid_class(node): + # The .int member is patched using __dict__ + node.locals["int"] = [nodes.Const(0, parent=node)] + + +MANAGER.register_transform( + nodes.ClassDef, _patch_uuid_class, lambda node: node.qname() == "uuid.UUID" +) diff --git a/venv/lib/python3.7/site-packages/astroid/builder.py b/venv/lib/python3.7/site-packages/astroid/builder.py new file mode 100644 index 0000000..ac71093 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/builder.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013 Phil Schaf +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014-2015 Google, Inc. +# Copyright (c) 2014 Alexander Presnyakov +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""The AstroidBuilder makes astroid from living object and / or from _ast + +The builder is not thread safe and can't be used to parse different sources +at the same time. +""" + +import os +import textwrap +from tokenize import detect_encoding + +from astroid._ast import _parse +from astroid import bases +from astroid import exceptions +from astroid import manager +from astroid import modutils +from astroid import raw_building +from astroid import rebuilder +from astroid import nodes +from astroid import util + +# The name of the transient function that is used to +# wrap expressions to be extracted when calling +# extract_node. +_TRANSIENT_FUNCTION = "__" + +# The comment used to select a statement to be extracted +# when calling extract_node. +_STATEMENT_SELECTOR = "#@" + +MANAGER = manager.AstroidManager() + + +def open_source_file(filename): + with open(filename, "rb") as byte_stream: + encoding = detect_encoding(byte_stream.readline)[0] + stream = open(filename, "r", newline=None, encoding=encoding) + data = stream.read() + return stream, encoding, data + + +def _can_assign_attr(node, attrname): + try: + slots = node.slots() + except NotImplementedError: + pass + else: + if slots and attrname not in {slot.value for slot in slots}: + return False + return True + + +class AstroidBuilder(raw_building.InspectBuilder): + """Class for building an astroid tree from source code or from a live module. + + The param *manager* specifies the manager class which should be used. + If no manager is given, then the default one will be used. The + param *apply_transforms* determines if the transforms should be + applied after the tree was built from source or from a live object, + by default being True. + """ + + # pylint: disable=redefined-outer-name + def __init__(self, manager=None, apply_transforms=True): + super(AstroidBuilder, self).__init__() + self._manager = manager or MANAGER + self._apply_transforms = apply_transforms + + def module_build(self, module, modname=None): + """Build an astroid from a living module instance.""" + node = None + path = getattr(module, "__file__", None) + if path is not None: + path_, ext = os.path.splitext(modutils._path_from_filename(path)) + if ext in (".py", ".pyc", ".pyo") and os.path.exists(path_ + ".py"): + node = self.file_build(path_ + ".py", modname) + if node is None: + # this is a built-in module + # get a partial representation by introspection + node = self.inspect_build(module, modname=modname, path=path) + if self._apply_transforms: + # We have to handle transformation by ourselves since the + # rebuilder isn't called for builtin nodes + node = self._manager.visit_transforms(node) + return node + + def file_build(self, path, modname=None): + """Build astroid from a source code file (i.e. from an ast) + + *path* is expected to be a python source file + """ + try: + stream, encoding, data = open_source_file(path) + except IOError as exc: + raise exceptions.AstroidBuildingError( + "Unable to load file {path}:\n{error}", + modname=modname, + path=path, + error=exc, + ) from exc + except (SyntaxError, LookupError) as exc: + raise exceptions.AstroidSyntaxError( + "Python 3 encoding specification error or unknown encoding:\n" + "{error}", + modname=modname, + path=path, + error=exc, + ) from exc + except UnicodeError as exc: # wrong encoding + # detect_encoding returns utf-8 if no encoding specified + raise exceptions.AstroidBuildingError( + "Wrong or no encoding specified for {filename}.", filename=path + ) from exc + with stream: + # get module name if necessary + if modname is None: + try: + modname = ".".join(modutils.modpath_from_file(path)) + except ImportError: + modname = os.path.splitext(os.path.basename(path))[0] + # build astroid representation + module = self._data_build(data, modname, path) + return self._post_build(module, encoding) + + def string_build(self, data, modname="", path=None): + """Build astroid from source code string.""" + module = self._data_build(data, modname, path) + module.file_bytes = data.encode("utf-8") + return self._post_build(module, "utf-8") + + def _post_build(self, module, encoding): + """Handles encoding and delayed nodes after a module has been built""" + module.file_encoding = encoding + self._manager.cache_module(module) + # post tree building steps after we stored the module in the cache: + for from_node in module._import_from_nodes: + if from_node.modname == "__future__": + for symbol, _ in from_node.names: + module.future_imports.add(symbol) + self.add_from_names_to_locals(from_node) + # handle delayed assattr nodes + for delayed in module._delayed_assattr: + self.delayed_assattr(delayed) + + # Visit the transforms + if self._apply_transforms: + module = self._manager.visit_transforms(module) + return module + + def _data_build(self, data, modname, path): + """Build tree node from data and add some informations""" + try: + node = _parse(data + "\n") + except (TypeError, ValueError, SyntaxError) as exc: + raise exceptions.AstroidSyntaxError( + "Parsing Python code failed:\n{error}", + source=data, + modname=modname, + path=path, + error=exc, + ) from exc + if path is not None: + node_file = os.path.abspath(path) + else: + node_file = "" + if modname.endswith(".__init__"): + modname = modname[:-9] + package = True + else: + package = ( + path is not None + and os.path.splitext(os.path.basename(path))[0] == "__init__" + ) + builder = rebuilder.TreeRebuilder(self._manager) + module = builder.visit_module(node, modname, node_file, package) + module._import_from_nodes = builder._import_from_nodes + module._delayed_assattr = builder._delayed_assattr + return module + + def add_from_names_to_locals(self, node): + """Store imported names to the locals + + Resort the locals if coming from a delayed node + """ + _key_func = lambda node: node.fromlineno + + def sort_locals(my_list): + my_list.sort(key=_key_func) + + for (name, asname) in node.names: + if name == "*": + try: + imported = node.do_import_module() + except exceptions.AstroidBuildingError: + continue + for name in imported.public_names(): + node.parent.set_local(name, node) + sort_locals(node.parent.scope().locals[name]) + else: + node.parent.set_local(asname or name, node) + sort_locals(node.parent.scope().locals[asname or name]) + + def delayed_assattr(self, node): + """Visit a AssAttr node + + This adds name to locals and handle members definition. + """ + try: + frame = node.frame() + for inferred in node.expr.infer(): + if inferred is util.Uninferable: + continue + try: + if inferred.__class__ is bases.Instance: + inferred = inferred._proxied + iattrs = inferred.instance_attrs + if not _can_assign_attr(inferred, node.attrname): + continue + elif isinstance(inferred, bases.Instance): + # Const, Tuple, ... we may be wrong, may be not, but + # anyway we don't want to pollute builtin's namespace + continue + elif inferred.is_function: + iattrs = inferred.instance_attrs + else: + iattrs = inferred.locals + except AttributeError: + # XXX log error + continue + values = iattrs.setdefault(node.attrname, []) + if node in values: + continue + # get assign in __init__ first XXX useful ? + if ( + frame.name == "__init__" + and values + and values[0].frame().name != "__init__" + ): + values.insert(0, node) + else: + values.append(node) + except exceptions.InferenceError: + pass + + +def build_namespace_package_module(name, path): + return nodes.Module(name, doc="", path=path, package=True) + + +def parse(code, module_name="", path=None, apply_transforms=True): + """Parses a source string in order to obtain an astroid AST from it + + :param str code: The code for the module. + :param str module_name: The name for the module, if any + :param str path: The path for the module + :param bool apply_transforms: + Apply the transforms for the give code. Use it if you + don't want the default transforms to be applied. + """ + code = textwrap.dedent(code) + builder = AstroidBuilder(manager=MANAGER, apply_transforms=apply_transforms) + return builder.string_build(code, modname=module_name, path=path) + + +def _extract_expressions(node): + """Find expressions in a call to _TRANSIENT_FUNCTION and extract them. + + The function walks the AST recursively to search for expressions that + are wrapped into a call to _TRANSIENT_FUNCTION. If it finds such an + expression, it completely removes the function call node from the tree, + replacing it by the wrapped expression inside the parent. + + :param node: An astroid node. + :type node: astroid.bases.NodeNG + :yields: The sequence of wrapped expressions on the modified tree + expression can be found. + """ + if ( + isinstance(node, nodes.Call) + and isinstance(node.func, nodes.Name) + and node.func.name == _TRANSIENT_FUNCTION + ): + real_expr = node.args[0] + real_expr.parent = node.parent + # Search for node in all _astng_fields (the fields checked when + # get_children is called) of its parent. Some of those fields may + # be lists or tuples, in which case the elements need to be checked. + # When we find it, replace it by real_expr, so that the AST looks + # like no call to _TRANSIENT_FUNCTION ever took place. + for name in node.parent._astroid_fields: + child = getattr(node.parent, name) + if isinstance(child, (list, tuple)): + for idx, compound_child in enumerate(child): + if compound_child is node: + child[idx] = real_expr + elif child is node: + setattr(node.parent, name, real_expr) + yield real_expr + else: + for child in node.get_children(): + yield from _extract_expressions(child) + + +def _find_statement_by_line(node, line): + """Extracts the statement on a specific line from an AST. + + If the line number of node matches line, it will be returned; + otherwise its children are iterated and the function is called + recursively. + + :param node: An astroid node. + :type node: astroid.bases.NodeNG + :param line: The line number of the statement to extract. + :type line: int + :returns: The statement on the line, or None if no statement for the line + can be found. + :rtype: astroid.bases.NodeNG or None + """ + if isinstance(node, (nodes.ClassDef, nodes.FunctionDef)): + # This is an inaccuracy in the AST: the nodes that can be + # decorated do not carry explicit information on which line + # the actual definition (class/def), but .fromline seems to + # be close enough. + node_line = node.fromlineno + else: + node_line = node.lineno + + if node_line == line: + return node + + for child in node.get_children(): + result = _find_statement_by_line(child, line) + if result: + return result + + return None + + +def extract_node(code, module_name=""): + """Parses some Python code as a module and extracts a designated AST node. + + Statements: + To extract one or more statement nodes, append #@ to the end of the line + + Examples: + >>> def x(): + >>> def y(): + >>> return 1 #@ + + The return statement will be extracted. + + >>> class X(object): + >>> def meth(self): #@ + >>> pass + + The function object 'meth' will be extracted. + + Expressions: + To extract arbitrary expressions, surround them with the fake + function call __(...). After parsing, the surrounded expression + will be returned and the whole AST (accessible via the returned + node's parent attribute) will look like the function call was + never there in the first place. + + Examples: + >>> a = __(1) + + The const node will be extracted. + + >>> def x(d=__(foo.bar)): pass + + The node containing the default argument will be extracted. + + >>> def foo(a, b): + >>> return 0 < __(len(a)) < b + + The node containing the function call 'len' will be extracted. + + If no statements or expressions are selected, the last toplevel + statement will be returned. + + If the selected statement is a discard statement, (i.e. an expression + turned into a statement), the wrapped expression is returned instead. + + For convenience, singleton lists are unpacked. + + :param str code: A piece of Python code that is parsed as + a module. Will be passed through textwrap.dedent first. + :param str module_name: The name of the module. + :returns: The designated node from the parse tree, or a list of nodes. + :rtype: astroid.bases.NodeNG, or a list of nodes. + """ + + def _extract(node): + if isinstance(node, nodes.Expr): + return node.value + + return node + + requested_lines = [] + for idx, line in enumerate(code.splitlines()): + if line.strip().endswith(_STATEMENT_SELECTOR): + requested_lines.append(idx + 1) + + tree = parse(code, module_name=module_name) + if not tree.body: + raise ValueError("Empty tree, cannot extract from it") + + extracted = [] + if requested_lines: + extracted = [_find_statement_by_line(tree, line) for line in requested_lines] + + # Modifies the tree. + extracted.extend(_extract_expressions(tree)) + + if not extracted: + extracted.append(tree.body[-1]) + + extracted = [_extract(node) for node in extracted] + if len(extracted) == 1: + return extracted[0] + return extracted diff --git a/venv/lib/python3.7/site-packages/astroid/context.py b/venv/lib/python3.7/site-packages/astroid/context.py new file mode 100644 index 0000000..70a9208 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/context.py @@ -0,0 +1,179 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Various context related utilities, including inference and call contexts.""" +import contextlib +import pprint +from typing import Optional + + +class InferenceContext: + """Provide context for inference + + Store already inferred nodes to save time + Account for already visited nodes to infinite stop infinite recursion + """ + + __slots__ = ( + "path", + "lookupname", + "callcontext", + "boundnode", + "inferred", + "extra_context", + ) + + def __init__(self, path=None, inferred=None): + self.path = path or set() + """ + :type: set(tuple(NodeNG, optional(str))) + + Path of visited nodes and their lookupname + + Currently this key is ``(node, context.lookupname)`` + """ + self.lookupname = None + """ + :type: optional[str] + + The original name of the node + + e.g. + foo = 1 + The inference of 'foo' is nodes.Const(1) but the lookup name is 'foo' + """ + self.callcontext = None + """ + :type: optional[CallContext] + + The call arguments and keywords for the given context + """ + self.boundnode = None + """ + :type: optional[NodeNG] + + The bound node of the given context + + e.g. the bound node of object.__new__(cls) is the object node + """ + self.inferred = inferred or {} + """ + :type: dict(seq, seq) + + Inferred node contexts to their mapped results + Currently the key is ``(node, lookupname, callcontext, boundnode)`` + and the value is tuple of the inferred results + """ + self.extra_context = {} + """ + :type: dict(NodeNG, Context) + + Context that needs to be passed down through call stacks + for call arguments + """ + + def push(self, node): + """Push node into inference path + + :return: True if node is already in context path else False + :rtype: bool + + Allows one to see if the given node has already + been looked at for this inference context""" + name = self.lookupname + if (node, name) in self.path: + return True + + self.path.add((node, name)) + return False + + def clone(self): + """Clone inference path + + For example, each side of a binary operation (BinOp) + starts with the same context but diverge as each side is inferred + so the InferenceContext will need be cloned""" + # XXX copy lookupname/callcontext ? + clone = InferenceContext(self.path, inferred=self.inferred) + clone.callcontext = self.callcontext + clone.boundnode = self.boundnode + clone.extra_context = self.extra_context + return clone + + def cache_generator(self, key, generator): + """Cache result of generator into dictionary + + Used to cache inference results""" + results = [] + for result in generator: + results.append(result) + yield result + + self.inferred[key] = tuple(results) + + @contextlib.contextmanager + def restore_path(self): + path = set(self.path) + yield + self.path = path + + def __str__(self): + state = ( + "%s=%s" + % (field, pprint.pformat(getattr(self, field), width=80 - len(field))) + for field in self.__slots__ + ) + return "%s(%s)" % (type(self).__name__, ",\n ".join(state)) + + +class CallContext: + """Holds information for a call site.""" + + __slots__ = ("args", "keywords") + + def __init__(self, args, keywords=None): + """ + :param List[NodeNG] args: Call positional arguments + :param Union[List[nodes.Keyword], None] keywords: Call keywords + """ + self.args = args + if keywords: + keywords = [(arg.arg, arg.value) for arg in keywords] + else: + keywords = [] + self.keywords = keywords + + +def copy_context(context: Optional[InferenceContext]) -> InferenceContext: + """Clone a context if given, or return a fresh contexxt""" + if context is not None: + return context.clone() + + return InferenceContext() + + +def bind_context_to_node(context, node): + """Give a context a boundnode + to retrieve the correct function name or attribute value + with from further inference. + + Do not use an existing context since the boundnode could then + be incorrectly propagated higher up in the call stack. + + :param context: Context to use + :type context: Optional(context) + + :param node: Node to do name lookups from + :type node NodeNG: + + :returns: A new context + :rtype: InferenceContext + """ + context = copy_context(context) + context.boundnode = node + return context diff --git a/venv/lib/python3.7/site-packages/astroid/decorators.py b/venv/lib/python3.7/site-packages/astroid/decorators.py new file mode 100644 index 0000000..1448757 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/decorators.py @@ -0,0 +1,141 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 HoverHell +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +""" A few useful function/method decorators.""" + +import functools + +import wrapt + +from astroid import context as contextmod +from astroid import exceptions +from astroid import util + + +@wrapt.decorator +def cached(func, instance, args, kwargs): + """Simple decorator to cache result of method calls without args.""" + cache = getattr(instance, "__cache", None) + if cache is None: + instance.__cache = cache = {} + try: + return cache[func] + except KeyError: + cache[func] = result = func(*args, **kwargs) + return result + + +class cachedproperty: + """ Provides a cached property equivalent to the stacking of + @cached and @property, but more efficient. + + After first usage, the becomes part of the object's + __dict__. Doing: + + del obj. empties the cache. + + Idea taken from the pyramid_ framework and the mercurial_ project. + + .. _pyramid: http://pypi.python.org/pypi/pyramid + .. _mercurial: http://pypi.python.org/pypi/Mercurial + """ + + __slots__ = ("wrapped",) + + def __init__(self, wrapped): + try: + wrapped.__name__ + except AttributeError as exc: + raise TypeError("%s must have a __name__ attribute" % wrapped) from exc + self.wrapped = wrapped + + @property + def __doc__(self): + doc = getattr(self.wrapped, "__doc__", None) + return "%s" % ( + "\n%s" % doc if doc else "" + ) + + def __get__(self, inst, objtype=None): + if inst is None: + return self + val = self.wrapped(inst) + setattr(inst, self.wrapped.__name__, val) + return val + + +def path_wrapper(func): + """return the given infer function wrapped to handle the path + + Used to stop inference if the node has already been looked + at for a given `InferenceContext` to prevent infinite recursion + """ + + @functools.wraps(func) + def wrapped(node, context=None, _func=func, **kwargs): + """wrapper function handling context""" + if context is None: + context = contextmod.InferenceContext() + if context.push(node): + return None + + yielded = set() + generator = _func(node, context, **kwargs) + try: + while True: + res = next(generator) + # unproxy only true instance, not const, tuple, dict... + if res.__class__.__name__ == "Instance": + ares = res._proxied + else: + ares = res + if ares not in yielded: + yield res + yielded.add(ares) + except StopIteration as error: + if error.args: + return error.args[0] + return None + + return wrapped + + +@wrapt.decorator +def yes_if_nothing_inferred(func, instance, args, kwargs): + generator = func(*args, **kwargs) + + try: + yield next(generator) + except StopIteration: + # generator is empty + yield util.Uninferable + return + + yield from generator + + +@wrapt.decorator +def raise_if_nothing_inferred(func, instance, args, kwargs): + generator = func(*args, **kwargs) + + try: + yield next(generator) + except StopIteration as error: + # generator is empty + if error.args: + # pylint: disable=not-a-mapping + raise exceptions.InferenceError(**error.args[0]) + raise exceptions.InferenceError( + "StopIteration raised without any error information." + ) + + yield from generator diff --git a/venv/lib/python3.7/site-packages/astroid/exceptions.py b/venv/lib/python3.7/site-packages/astroid/exceptions.py new file mode 100644 index 0000000..7e9d655 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/exceptions.py @@ -0,0 +1,230 @@ +# Copyright (c) 2007, 2009-2010, 2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains exceptions used in the astroid library +""" +from astroid import util + + +class AstroidError(Exception): + """base exception class for all astroid related exceptions + + AstroidError and its subclasses are structured, intended to hold + objects representing state when the exception is thrown. Field + values are passed to the constructor as keyword-only arguments. + Each subclass has its own set of standard fields, but use your + best judgment to decide whether a specific exception instance + needs more or fewer fields for debugging. Field values may be + used to lazily generate the error message: self.message.format() + will be called with the field names and values supplied as keyword + arguments. + """ + + def __init__(self, message="", **kws): + super(AstroidError, self).__init__(message) + self.message = message + for key, value in kws.items(): + setattr(self, key, value) + + def __str__(self): + return self.message.format(**vars(self)) + + +class AstroidBuildingError(AstroidError): + """exception class when we are unable to build an astroid representation + + Standard attributes: + modname: Name of the module that AST construction failed for. + error: Exception raised during construction. + """ + + def __init__(self, message="Failed to import module {modname}.", **kws): + super(AstroidBuildingError, self).__init__(message, **kws) + + +class AstroidImportError(AstroidBuildingError): + """Exception class used when a module can't be imported by astroid.""" + + +class TooManyLevelsError(AstroidImportError): + """Exception class which is raised when a relative import was beyond the top-level. + + Standard attributes: + level: The level which was attempted. + name: the name of the module on which the relative import was attempted. + """ + + level = None + name = None + + def __init__( + self, + message="Relative import with too many levels " "({level}) for module {name!r}", + **kws + ): + super(TooManyLevelsError, self).__init__(message, **kws) + + +class AstroidSyntaxError(AstroidBuildingError): + """Exception class used when a module can't be parsed.""" + + +class NoDefault(AstroidError): + """raised by function's `default_value` method when an argument has + no default value + + Standard attributes: + func: Function node. + name: Name of argument without a default. + """ + + func = None + name = None + + def __init__(self, message="{func!r} has no default for {name!r}.", **kws): + super(NoDefault, self).__init__(message, **kws) + + +class ResolveError(AstroidError): + """Base class of astroid resolution/inference error. + + ResolveError is not intended to be raised. + + Standard attributes: + context: InferenceContext object. + """ + + context = None + + +class MroError(ResolveError): + """Error raised when there is a problem with method resolution of a class. + + Standard attributes: + mros: A sequence of sequences containing ClassDef nodes. + cls: ClassDef node whose MRO resolution failed. + context: InferenceContext object. + """ + + mros = () + cls = None + + def __str__(self): + mro_names = ", ".join( + "({})".format(", ".join(b.name for b in m)) for m in self.mros + ) + return self.message.format(mros=mro_names, cls=self.cls) + + +class DuplicateBasesError(MroError): + """Error raised when there are duplicate bases in the same class bases.""" + + +class InconsistentMroError(MroError): + """Error raised when a class's MRO is inconsistent.""" + + +class SuperError(ResolveError): + """Error raised when there is a problem with a *super* call. + + Standard attributes: + *super_*: The Super instance that raised the exception. + context: InferenceContext object. + """ + + super_ = None + + def __str__(self): + return self.message.format(**vars(self.super_)) + + +class InferenceError(ResolveError): + """raised when we are unable to infer a node + + Standard attributes: + node: The node inference was called on. + context: InferenceContext object. + """ + + node = None + context = None + + def __init__(self, message="Inference failed for {node!r}.", **kws): + super(InferenceError, self).__init__(message, **kws) + + +# Why does this inherit from InferenceError rather than ResolveError? +# Changing it causes some inference tests to fail. +class NameInferenceError(InferenceError): + """Raised when a name lookup fails, corresponds to NameError. + + Standard attributes: + name: The name for which lookup failed, as a string. + scope: The node representing the scope in which the lookup occurred. + context: InferenceContext object. + """ + + name = None + scope = None + + def __init__(self, message="{name!r} not found in {scope!r}.", **kws): + super(NameInferenceError, self).__init__(message, **kws) + + +class AttributeInferenceError(ResolveError): + """Raised when an attribute lookup fails, corresponds to AttributeError. + + Standard attributes: + target: The node for which lookup failed. + attribute: The attribute for which lookup failed, as a string. + context: InferenceContext object. + """ + + target = None + attribute = None + + def __init__(self, message="{attribute!r} not found on {target!r}.", **kws): + super(AttributeInferenceError, self).__init__(message, **kws) + + +class UseInferenceDefault(Exception): + """exception to be raised in custom inference function to indicate that it + should go back to the default behaviour + """ + + +class _NonDeducibleTypeHierarchy(Exception): + """Raised when is_subtype / is_supertype can't deduce the relation between two types.""" + + +class AstroidIndexError(AstroidError): + """Raised when an Indexable / Mapping does not have an index / key.""" + + +class AstroidTypeError(AstroidError): + """Raised when a TypeError would be expected in Python code.""" + + +class InferenceOverwriteError(AstroidError): + """Raised when an inference tip is overwritten + + Currently only used for debugging. + """ + + +# Backwards-compatibility aliases +OperationError = util.BadOperationMessage +UnaryOperationError = util.BadUnaryOperationMessage +BinaryOperationError = util.BadBinaryOperationMessage + +SuperArgumentTypeError = SuperError +UnresolvableName = NameInferenceError +NotFoundError = AttributeInferenceError +AstroidBuildingException = AstroidBuildingError diff --git a/venv/lib/python3.7/site-packages/astroid/helpers.py b/venv/lib/python3.7/site-packages/astroid/helpers.py new file mode 100644 index 0000000..edbb205 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/helpers.py @@ -0,0 +1,272 @@ +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +Various helper utilities. +""" + +import builtins as builtins_mod + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import manager +from astroid import nodes +from astroid import raw_building +from astroid import scoped_nodes +from astroid import util + + +BUILTINS = builtins_mod.__name__ + + +def _build_proxy_class(cls_name, builtins): + proxy = raw_building.build_class(cls_name) + proxy.parent = builtins + return proxy + + +def _function_type(function, builtins): + if isinstance(function, scoped_nodes.Lambda): + if function.root().name == BUILTINS: + cls_name = "builtin_function_or_method" + else: + cls_name = "function" + elif isinstance(function, bases.BoundMethod): + cls_name = "method" + elif isinstance(function, bases.UnboundMethod): + cls_name = "function" + return _build_proxy_class(cls_name, builtins) + + +def _object_type(node, context=None): + astroid_manager = manager.AstroidManager() + builtins = astroid_manager.builtins_module + context = context or contextmod.InferenceContext() + + for inferred in node.infer(context=context): + if isinstance(inferred, scoped_nodes.ClassDef): + if inferred.newstyle: + metaclass = inferred.metaclass() + if metaclass: + yield metaclass + continue + yield builtins.getattr("type")[0] + elif isinstance(inferred, (scoped_nodes.Lambda, bases.UnboundMethod)): + yield _function_type(inferred, builtins) + elif isinstance(inferred, scoped_nodes.Module): + yield _build_proxy_class("module", builtins) + else: + yield inferred._proxied + + +def object_type(node, context=None): + """Obtain the type of the given node + + This is used to implement the ``type`` builtin, which means that it's + used for inferring type calls, as well as used in a couple of other places + in the inference. + The node will be inferred first, so this function can support all + sorts of objects, as long as they support inference. + """ + + try: + types = set(_object_type(node, context)) + except exceptions.InferenceError: + return util.Uninferable + if len(types) > 1 or not types: + return util.Uninferable + return list(types)[0] + + +def _object_type_is_subclass(obj_type, class_or_seq, context=None): + if not isinstance(class_or_seq, (tuple, list)): + class_seq = (class_or_seq,) + else: + class_seq = class_or_seq + + if obj_type is util.Uninferable: + return util.Uninferable + + # Instances are not types + class_seq = [ + item if not isinstance(item, bases.Instance) else util.Uninferable + for item in class_seq + ] + # strict compatibility with issubclass + # issubclass(type, (object, 1)) evaluates to true + # issubclass(object, (1, type)) raises TypeError + for klass in class_seq: + if klass is util.Uninferable: + raise exceptions.AstroidTypeError("arg 2 must be a type or tuple of types") + + for obj_subclass in obj_type.mro(): + if obj_subclass == klass: + return True + return False + + +def object_isinstance(node, class_or_seq, context=None): + """Check if a node 'isinstance' any node in class_or_seq + + :param node: A given node + :param class_or_seq: Union[nodes.NodeNG, Sequence[nodes.NodeNG]] + :rtype: bool + + :raises AstroidTypeError: if the given ``classes_or_seq`` are not types + """ + obj_type = object_type(node, context) + if obj_type is util.Uninferable: + return util.Uninferable + return _object_type_is_subclass(obj_type, class_or_seq, context=context) + + +def object_issubclass(node, class_or_seq, context=None): + """Check if a type is a subclass of any node in class_or_seq + + :param node: A given node + :param class_or_seq: Union[Nodes.NodeNG, Sequence[nodes.NodeNG]] + :rtype: bool + + :raises AstroidTypeError: if the given ``classes_or_seq`` are not types + :raises AstroidError: if the type of the given node cannot be inferred + or its type's mro doesn't work + """ + if not isinstance(node, nodes.ClassDef): + raise TypeError("{node} needs to be a ClassDef node".format(node=node)) + return _object_type_is_subclass(node, class_or_seq, context=context) + + +def safe_infer(node, context=None): + """Return the inferred value for the given node. + + Return None if inference failed or if there is some ambiguity (more than + one node has been inferred). + """ + try: + inferit = node.infer(context=context) + value = next(inferit) + except exceptions.InferenceError: + return None + try: + next(inferit) + return None # None if there is ambiguity on the inferred node + except exceptions.InferenceError: + return None # there is some kind of ambiguity + except StopIteration: + return value + + +def has_known_bases(klass, context=None): + """Return true if all base classes of a class could be inferred.""" + try: + return klass._all_bases_known + except AttributeError: + pass + for base in klass.bases: + result = safe_infer(base, context=context) + # TODO: check for A->B->A->B pattern in class structure too? + if ( + not isinstance(result, scoped_nodes.ClassDef) + or result is klass + or not has_known_bases(result, context=context) + ): + klass._all_bases_known = False + return False + klass._all_bases_known = True + return True + + +def _type_check(type1, type2): + if not all(map(has_known_bases, (type1, type2))): + raise exceptions._NonDeducibleTypeHierarchy + + if not all([type1.newstyle, type2.newstyle]): + return False + try: + return type1 in type2.mro()[:-1] + except exceptions.MroError: + # The MRO is invalid. + raise exceptions._NonDeducibleTypeHierarchy + + +def is_subtype(type1, type2): + """Check if *type1* is a subtype of *typ2*.""" + return _type_check(type2, type1) + + +def is_supertype(type1, type2): + """Check if *type2* is a supertype of *type1*.""" + return _type_check(type1, type2) + + +def class_instance_as_index(node): + """Get the value as an index for the given instance. + + If an instance provides an __index__ method, then it can + be used in some scenarios where an integer is expected, + for instance when multiplying or subscripting a list. + """ + context = contextmod.InferenceContext() + context.callcontext = contextmod.CallContext(args=[node]) + + try: + for inferred in node.igetattr("__index__", context=context): + if not isinstance(inferred, bases.BoundMethod): + continue + + for result in inferred.infer_call_result(node, context=context): + if isinstance(result, nodes.Const) and isinstance(result.value, int): + return result + except exceptions.InferenceError: + pass + return None + + +def object_len(node, context=None): + """Infer length of given node object + + :param Union[nodes.ClassDef, nodes.Instance] node: + :param node: Node to infer length of + + :raises AstroidTypeError: If an invalid node is returned + from __len__ method or no __len__ method exists + :raises InferenceError: If the given node cannot be inferred + or if multiple nodes are inferred + :rtype int: Integer length of node + """ + from astroid.objects import FrozenSet + + inferred_node = safe_infer(node, context=context) + if inferred_node is None or inferred_node is util.Uninferable: + raise exceptions.InferenceError(node=node) + if isinstance(inferred_node, nodes.Const) and isinstance( + inferred_node.value, (bytes, str) + ): + return len(inferred_node.value) + if isinstance(inferred_node, (nodes.List, nodes.Set, nodes.Tuple, FrozenSet)): + return len(inferred_node.elts) + if isinstance(inferred_node, nodes.Dict): + return len(inferred_node.items) + try: + node_type = object_type(inferred_node, context=context) + len_call = next(node_type.igetattr("__len__", context=context)) + except exceptions.AttributeInferenceError: + raise exceptions.AstroidTypeError( + "object of type '{}' has no len()".format(len_call.pytype()) + ) + + result_of_len = next(len_call.infer_call_result(node, context)) + if ( + isinstance(result_of_len, nodes.Const) + and result_of_len.pytype() == "builtins.int" + ): + return result_of_len.value + raise exceptions.AstroidTypeError( + "'{}' object cannot be interpreted as an integer".format(result_of_len) + ) diff --git a/venv/lib/python3.7/site-packages/astroid/inference.py b/venv/lib/python3.7/site-packages/astroid/inference.py new file mode 100644 index 0000000..16346a7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/inference.py @@ -0,0 +1,899 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2017 MichaÅ‚ MasÅ‚owski +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to handle inference on astroid trees +""" + +import functools +import itertools +import operator + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators +from astroid import helpers +from astroid import manager +from astroid import nodes +from astroid.interpreter import dunder_lookup +from astroid import protocols +from astroid import util + + +MANAGER = manager.AstroidManager() + + +# .infer method ############################################################### + + +def infer_end(self, context=None): + """inference's end for node such as Module, ClassDef, FunctionDef, + Const... + + """ + yield self + + +nodes.Module._infer = infer_end +nodes.ClassDef._infer = infer_end +nodes.FunctionDef._infer = infer_end +nodes.Lambda._infer = infer_end +nodes.Const._infer = infer_end +nodes.Slice._infer = infer_end + + +def _infer_sequence_helper(node, context=None): + """Infer all values based on _BaseContainer.elts""" + values = [] + + for elt in node.elts: + if isinstance(elt, nodes.Starred): + starred = helpers.safe_infer(elt.value, context) + if not starred: + raise exceptions.InferenceError(node=node, context=context) + if not hasattr(starred, "elts"): + raise exceptions.InferenceError(node=node, context=context) + values.extend(_infer_sequence_helper(starred)) + else: + values.append(elt) + return values + + +@decorators.raise_if_nothing_inferred +def infer_sequence(self, context=None): + if not any(isinstance(e, nodes.Starred) for e in self.elts): + yield self + else: + values = _infer_sequence_helper(self, context) + new_seq = type(self)( + lineno=self.lineno, col_offset=self.col_offset, parent=self.parent + ) + new_seq.postinit(values) + + yield new_seq + + +nodes.List._infer = infer_sequence +nodes.Tuple._infer = infer_sequence +nodes.Set._infer = infer_sequence + + +def infer_map(self, context=None): + if not any(isinstance(k, nodes.DictUnpack) for k, _ in self.items): + yield self + else: + items = _infer_map(self, context) + new_seq = type(self)(self.lineno, self.col_offset, self.parent) + new_seq.postinit(list(items.items())) + yield new_seq + + +def _update_with_replacement(lhs_dict, rhs_dict): + """Delete nodes that equate to duplicate keys + + Since an astroid node doesn't 'equal' another node with the same value, + this function uses the as_string method to make sure duplicate keys + don't get through + + Note that both the key and the value are astroid nodes + + Fixes issue with DictUnpack causing duplicte keys + in inferred Dict items + + :param dict(nodes.NodeNG, nodes.NodeNG) lhs_dict: Dictionary to 'merge' nodes into + :param dict(nodes.NodeNG, nodes.NodeNG) rhs_dict: Dictionary with nodes to pull from + :return dict(nodes.NodeNG, nodes.NodeNG): merged dictionary of nodes + """ + combined_dict = itertools.chain(lhs_dict.items(), rhs_dict.items()) + # Overwrite keys which have the same string values + string_map = {key.as_string(): (key, value) for key, value in combined_dict} + # Return to dictionary + return dict(string_map.values()) + + +def _infer_map(node, context): + """Infer all values based on Dict.items""" + values = {} + for name, value in node.items: + if isinstance(name, nodes.DictUnpack): + double_starred = helpers.safe_infer(value, context) + if not double_starred: + raise exceptions.InferenceError + if not isinstance(double_starred, nodes.Dict): + raise exceptions.InferenceError(node=node, context=context) + unpack_items = _infer_map(double_starred, context) + values = _update_with_replacement(values, unpack_items) + else: + key = helpers.safe_infer(name, context=context) + value = helpers.safe_infer(value, context=context) + if any(not elem for elem in (key, value)): + raise exceptions.InferenceError(node=node, context=context) + values = _update_with_replacement(values, {key: value}) + return values + + +nodes.Dict._infer = infer_map + + +def _higher_function_scope(node): + """ Search for the first function which encloses the given + scope. This can be used for looking up in that function's + scope, in case looking up in a lower scope for a particular + name fails. + + :param node: A scope node. + :returns: + ``None``, if no parent function scope was found, + otherwise an instance of :class:`astroid.scoped_nodes.Function`, + which encloses the given node. + """ + current = node + while current.parent and not isinstance(current.parent, nodes.FunctionDef): + current = current.parent + if current and current.parent: + return current.parent + return None + + +def infer_name(self, context=None): + """infer a Name: use name lookup rules""" + frame, stmts = self.lookup(self.name) + if not stmts: + # Try to see if the name is enclosed in a nested function + # and use the higher (first function) scope for searching. + parent_function = _higher_function_scope(self.scope()) + if parent_function: + _, stmts = parent_function.lookup(self.name) + + if not stmts: + raise exceptions.NameInferenceError( + name=self.name, scope=self.scope(), context=context + ) + context = contextmod.copy_context(context) + context.lookupname = self.name + return bases._infer_stmts(stmts, context, frame) + + +# pylint: disable=no-value-for-parameter +nodes.Name._infer = decorators.raise_if_nothing_inferred( + decorators.path_wrapper(infer_name) +) +nodes.AssignName.infer_lhs = infer_name # won't work with a path wrapper + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_call(self, context=None): + """infer a Call node by trying to guess what the function returns""" + callcontext = contextmod.copy_context(context) + callcontext.callcontext = contextmod.CallContext( + args=self.args, keywords=self.keywords + ) + callcontext.boundnode = None + if context is not None: + callcontext.extra_context = _populate_context_lookup(self, context.clone()) + + for callee in self.func.infer(context): + if callee is util.Uninferable: + yield callee + continue + try: + if hasattr(callee, "infer_call_result"): + yield from callee.infer_call_result(caller=self, context=callcontext) + except exceptions.InferenceError: + continue + return dict(node=self, context=context) + + +nodes.Call._infer = infer_call + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_import(self, context=None, asname=True): + """infer an Import node: return the imported module/object""" + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + + try: + if asname: + yield self.do_import_module(self.real_name(name)) + else: + yield self.do_import_module(name) + except exceptions.AstroidBuildingError as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + +nodes.Import._infer = infer_import + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_import_from(self, context=None, asname=True): + """infer a ImportFrom node: return the imported module/object""" + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + if asname: + name = self.real_name(name) + + try: + module = self.do_import_module() + except exceptions.AstroidBuildingError as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + try: + context = contextmod.copy_context(context) + context.lookupname = name + stmts = module.getattr(name, ignore_locals=module is self.root()) + return bases._infer_stmts(stmts, context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + +nodes.ImportFrom._infer = infer_import_from + + +def infer_attribute(self, context=None): + """infer an Attribute node by using getattr on the associated object""" + for owner in self.expr.infer(context): + if owner is util.Uninferable: + yield owner + continue + + if context and context.boundnode: + # This handles the situation where the attribute is accessed through a subclass + # of a base class and the attribute is defined at the base class's level, + # by taking in consideration a redefinition in the subclass. + if isinstance(owner, bases.Instance) and isinstance( + context.boundnode, bases.Instance + ): + try: + if helpers.is_subtype( + helpers.object_type(context.boundnode), + helpers.object_type(owner), + ): + owner = context.boundnode + except exceptions._NonDeducibleTypeHierarchy: + # Can't determine anything useful. + pass + + try: + context.boundnode = owner + yield from owner.igetattr(self.attrname, context) + context.boundnode = None + except (exceptions.AttributeInferenceError, exceptions.InferenceError): + context.boundnode = None + except AttributeError: + # XXX method / function + context.boundnode = None + return dict(node=self, context=context) + + +nodes.Attribute._infer = decorators.raise_if_nothing_inferred( + decorators.path_wrapper(infer_attribute) +) +# won't work with a path wrapper +nodes.AssignAttr.infer_lhs = decorators.raise_if_nothing_inferred(infer_attribute) + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_global(self, context=None): + if context.lookupname is None: + raise exceptions.InferenceError(node=self, context=context) + try: + return bases._infer_stmts(self.root().getattr(context.lookupname), context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=context.lookupname, context=context + ) from error + + +nodes.Global._infer = infer_global + + +_SUBSCRIPT_SENTINEL = object() + + +@decorators.raise_if_nothing_inferred +def infer_subscript(self, context=None): + """Inference for subscripts + + We're understanding if the index is a Const + or a slice, passing the result of inference + to the value's `getitem` method, which should + handle each supported index type accordingly. + """ + + found_one = False + for value in self.value.infer(context): + if value is util.Uninferable: + yield util.Uninferable + return None + for index in self.slice.infer(context): + if index is util.Uninferable: + yield util.Uninferable + return None + + # Try to deduce the index value. + index_value = _SUBSCRIPT_SENTINEL + if value.__class__ == bases.Instance: + index_value = index + else: + if index.__class__ == bases.Instance: + instance_as_index = helpers.class_instance_as_index(index) + if instance_as_index: + index_value = instance_as_index + else: + index_value = index + if index_value is _SUBSCRIPT_SENTINEL: + raise exceptions.InferenceError(node=self, context=context) + + try: + assigned = value.getitem(index_value, context) + except ( + exceptions.AstroidTypeError, + exceptions.AstroidIndexError, + exceptions.AttributeInferenceError, + AttributeError, + ) as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + # Prevent inferring if the inferred subscript + # is the same as the original subscripted object. + if self is assigned or assigned is util.Uninferable: + yield util.Uninferable + return None + yield from assigned.infer(context) + found_one = True + + if found_one: + return dict(node=self, context=context) + return None + + +nodes.Subscript._infer = decorators.path_wrapper(infer_subscript) +nodes.Subscript.infer_lhs = infer_subscript + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def _infer_boolop(self, context=None): + """Infer a boolean operation (and / or / not). + + The function will calculate the boolean operation + for all pairs generated through inference for each component + node. + """ + values = self.values + if self.op == "or": + predicate = operator.truth + else: + predicate = operator.not_ + + try: + values = [value.infer(context=context) for value in values] + except exceptions.InferenceError: + yield util.Uninferable + return None + + for pair in itertools.product(*values): + if any(item is util.Uninferable for item in pair): + # Can't infer the final result, just yield Uninferable. + yield util.Uninferable + continue + + bool_values = [item.bool_value() for item in pair] + if any(item is util.Uninferable for item in bool_values): + # Can't infer the final result, just yield Uninferable. + yield util.Uninferable + continue + + # Since the boolean operations are short circuited operations, + # this code yields the first value for which the predicate is True + # and if no value respected the predicate, then the last value will + # be returned (or Uninferable if there was no last value). + # This is conforming to the semantics of `and` and `or`: + # 1 and 0 -> 1 + # 0 and 1 -> 0 + # 1 or 0 -> 1 + # 0 or 1 -> 1 + value = util.Uninferable + for value, bool_value in zip(pair, bool_values): + if predicate(bool_value): + yield value + break + else: + yield value + + return dict(node=self, context=context) + + +nodes.BoolOp._infer = _infer_boolop + + +# UnaryOp, BinOp and AugAssign inferences + + +def _filter_operation_errors(self, infer_callable, context, error): + for result in infer_callable(self, context): + if isinstance(result, error): + # For the sake of .infer(), we don't care about operation + # errors, which is the job of pylint. So return something + # which shows that we can't infer the result. + yield util.Uninferable + else: + yield result + + +def _infer_unaryop(self, context=None): + """Infer what an UnaryOp should return when evaluated.""" + for operand in self.operand.infer(context): + try: + yield operand.infer_unary_op(self.op) + except TypeError as exc: + # The operand doesn't support this operation. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + except AttributeError as exc: + meth = protocols.UNARY_OP_METHOD[self.op] + if meth is None: + # `not node`. Determine node's boolean + # value and negate its result, unless it is + # Uninferable, which will be returned as is. + bool_value = operand.bool_value() + if bool_value is not util.Uninferable: + yield nodes.const_factory(not bool_value) + else: + yield util.Uninferable + else: + if not isinstance(operand, (bases.Instance, nodes.ClassDef)): + # The operation was used on something which + # doesn't support it. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + continue + + try: + try: + methods = dunder_lookup.lookup(operand, meth) + except exceptions.AttributeInferenceError: + yield util.BadUnaryOperationMessage(operand, self.op, exc) + continue + + meth = methods[0] + inferred = next(meth.infer(context=context)) + if inferred is util.Uninferable or not inferred.callable(): + continue + + context = contextmod.copy_context(context) + context.callcontext = contextmod.CallContext(args=[operand]) + call_results = inferred.infer_call_result(self, context=context) + result = next(call_results, None) + if result is None: + # Failed to infer, return the same type. + yield operand + else: + yield result + except exceptions.AttributeInferenceError as exc: + # The unary operation special method was not found. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + except exceptions.InferenceError: + yield util.Uninferable + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_unaryop(self, context=None): + """Infer what an UnaryOp should return when evaluated.""" + yield from _filter_operation_errors( + self, _infer_unaryop, context, util.BadUnaryOperationMessage + ) + return dict(node=self, context=context) + + +nodes.UnaryOp._infer_unaryop = _infer_unaryop +nodes.UnaryOp._infer = infer_unaryop + + +def _is_not_implemented(const): + """Check if the given const node is NotImplemented.""" + return isinstance(const, nodes.Const) and const.value is NotImplemented + + +def _invoke_binop_inference(instance, opnode, op, other, context, method_name): + """Invoke binary operation inference on the given instance.""" + methods = dunder_lookup.lookup(instance, method_name) + context = contextmod.bind_context_to_node(context, instance) + method = methods[0] + inferred = next(method.infer(context=context)) + if inferred is util.Uninferable: + raise exceptions.InferenceError + return instance.infer_binary_op(opnode, op, other, context, inferred) + + +def _aug_op(instance, opnode, op, other, context, reverse=False): + """Get an inference callable for an augmented binary operation.""" + method_name = protocols.AUGMENTED_OP_METHOD[op] + return functools.partial( + _invoke_binop_inference, + instance=instance, + op=op, + opnode=opnode, + other=other, + context=context, + method_name=method_name, + ) + + +def _bin_op(instance, opnode, op, other, context, reverse=False): + """Get an inference callable for a normal binary operation. + + If *reverse* is True, then the reflected method will be used instead. + """ + if reverse: + method_name = protocols.REFLECTED_BIN_OP_METHOD[op] + else: + method_name = protocols.BIN_OP_METHOD[op] + return functools.partial( + _invoke_binop_inference, + instance=instance, + op=op, + opnode=opnode, + other=other, + context=context, + method_name=method_name, + ) + + +def _get_binop_contexts(context, left, right): + """Get contexts for binary operations. + + This will return two inference contexts, the first one + for x.__op__(y), the other one for y.__rop__(x), where + only the arguments are inversed. + """ + # The order is important, since the first one should be + # left.__op__(right). + for arg in (right, left): + new_context = context.clone() + new_context.callcontext = contextmod.CallContext(args=[arg]) + new_context.boundnode = None + yield new_context + + +def _same_type(type1, type2): + """Check if type1 is the same as type2.""" + return type1.qname() == type2.qname() + + +def _get_binop_flow( + left, left_type, binary_opnode, right, right_type, context, reverse_context +): + """Get the flow for binary operations. + + The rules are a bit messy: + + * if left and right have the same type, then only one + method will be called, left.__op__(right) + * if left and right are unrelated typewise, then first + left.__op__(right) is tried and if this does not exist + or returns NotImplemented, then right.__rop__(left) is tried. + * if left is a subtype of right, then only left.__op__(right) + is tried. + * if left is a supertype of right, then right.__rop__(left) + is first tried and then left.__op__(right) + """ + op = binary_opnode.op + if _same_type(left_type, right_type): + methods = [_bin_op(left, binary_opnode, op, right, context)] + elif helpers.is_subtype(left_type, right_type): + methods = [_bin_op(left, binary_opnode, op, right, context)] + elif helpers.is_supertype(left_type, right_type): + methods = [ + _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True), + _bin_op(left, binary_opnode, op, right, context), + ] + else: + methods = [ + _bin_op(left, binary_opnode, op, right, context), + _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True), + ] + return methods + + +def _get_aug_flow( + left, left_type, aug_opnode, right, right_type, context, reverse_context +): + """Get the flow for augmented binary operations. + + The rules are a bit messy: + + * if left and right have the same type, then left.__augop__(right) + is first tried and then left.__op__(right). + * if left and right are unrelated typewise, then + left.__augop__(right) is tried, then left.__op__(right) + is tried and then right.__rop__(left) is tried. + * if left is a subtype of right, then left.__augop__(right) + is tried and then left.__op__(right). + * if left is a supertype of right, then left.__augop__(right) + is tried, then right.__rop__(left) and then + left.__op__(right) + """ + bin_op = aug_opnode.op.strip("=") + aug_op = aug_opnode.op + if _same_type(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + elif helpers.is_subtype(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + elif helpers.is_supertype(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + else: + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True), + ] + return methods + + +def _infer_binary_operation(left, right, binary_opnode, context, flow_factory): + """Infer a binary operation between a left operand and a right operand + + This is used by both normal binary operations and augmented binary + operations, the only difference is the flow factory used. + """ + + context, reverse_context = _get_binop_contexts(context, left, right) + left_type = helpers.object_type(left) + right_type = helpers.object_type(right) + methods = flow_factory( + left, left_type, binary_opnode, right, right_type, context, reverse_context + ) + for method in methods: + try: + results = list(method()) + except AttributeError: + continue + except exceptions.AttributeInferenceError: + continue + except exceptions.InferenceError: + yield util.Uninferable + return + else: + if any(result is util.Uninferable for result in results): + yield util.Uninferable + return + + if all(map(_is_not_implemented, results)): + continue + not_implemented = sum( + 1 for result in results if _is_not_implemented(result) + ) + if not_implemented and not_implemented != len(results): + # Can't infer yet what this is. + yield util.Uninferable + return + + yield from results + return + # The operation doesn't seem to be supported so let the caller know about it + yield util.BadBinaryOperationMessage(left_type, binary_opnode.op, right_type) + + +def _infer_binop(self, context): + """Binary operation inference logic.""" + left = self.left + right = self.right + + # we use two separate contexts for evaluating lhs and rhs because + # 1. evaluating lhs may leave some undesired entries in context.path + # which may not let us infer right value of rhs + context = context or contextmod.InferenceContext() + lhs_context = contextmod.copy_context(context) + rhs_context = contextmod.copy_context(context) + lhs_iter = left.infer(context=lhs_context) + rhs_iter = right.infer(context=rhs_context) + for lhs, rhs in itertools.product(lhs_iter, rhs_iter): + if any(value is util.Uninferable for value in (rhs, lhs)): + # Don't know how to process this. + yield util.Uninferable + return + + try: + yield from _infer_binary_operation(lhs, rhs, self, context, _get_binop_flow) + except exceptions._NonDeducibleTypeHierarchy: + yield util.Uninferable + + +@decorators.yes_if_nothing_inferred +@decorators.path_wrapper +def infer_binop(self, context=None): + return _filter_operation_errors( + self, _infer_binop, context, util.BadBinaryOperationMessage + ) + + +nodes.BinOp._infer_binop = _infer_binop +nodes.BinOp._infer = infer_binop + + +def _infer_augassign(self, context=None): + """Inference logic for augmented binary operations.""" + if context is None: + context = contextmod.InferenceContext() + + rhs_context = context.clone() + + lhs_iter = self.target.infer_lhs(context=context) + rhs_iter = self.value.infer(context=rhs_context) + for lhs, rhs in itertools.product(lhs_iter, rhs_iter): + if any(value is util.Uninferable for value in (rhs, lhs)): + # Don't know how to process this. + yield util.Uninferable + return + + try: + yield from _infer_binary_operation( + left=lhs, + right=rhs, + binary_opnode=self, + context=context, + flow_factory=_get_aug_flow, + ) + except exceptions._NonDeducibleTypeHierarchy: + yield util.Uninferable + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_augassign(self, context=None): + return _filter_operation_errors( + self, _infer_augassign, context, util.BadBinaryOperationMessage + ) + + +nodes.AugAssign._infer_augassign = _infer_augassign +nodes.AugAssign._infer = infer_augassign + +# End of binary operation inference. + + +@decorators.raise_if_nothing_inferred +def infer_arguments(self, context=None): + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + return protocols._arguments_infer_argname(self, name, context) + + +nodes.Arguments._infer = infer_arguments + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_assign(self, context=None): + """infer a AssignName/AssignAttr: need to inspect the RHS part of the + assign node + """ + stmt = self.statement() + if isinstance(stmt, nodes.AugAssign): + return stmt.infer(context) + + stmts = list(self.assigned_stmts(context=context)) + return bases._infer_stmts(stmts, context) + + +nodes.AssignName._infer = infer_assign +nodes.AssignAttr._infer = infer_assign + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_empty_node(self, context=None): + if not self.has_underlying_object(): + yield util.Uninferable + else: + try: + yield from MANAGER.infer_ast_from_something(self.object, context=context) + except exceptions.AstroidError: + yield util.Uninferable + + +nodes.EmptyNode._infer = infer_empty_node + + +@decorators.raise_if_nothing_inferred +def infer_index(self, context=None): + return self.value.infer(context) + + +nodes.Index._infer = infer_index + +# TODO: move directly into bases.Instance when the dependency hell +# will be solved. +def instance_getitem(self, index, context=None): + # Rewrap index to Const for this case + new_context = contextmod.bind_context_to_node(context, self) + if not context: + context = new_context + + # Create a new callcontext for providing index as an argument. + new_context.callcontext = contextmod.CallContext(args=[index]) + + method = next(self.igetattr("__getitem__", context=context), None) + if not isinstance(method, bases.BoundMethod): + raise exceptions.InferenceError( + "Could not find __getitem__ for {node!r}.", node=self, context=context + ) + + return next(method.infer_call_result(self, new_context)) + + +bases.Instance.getitem = instance_getitem + + +def _populate_context_lookup(call, context): + # Allows context to be saved for later + # for inference inside a function + context_lookup = {} + if context is None: + return context_lookup + for arg in call.args: + if isinstance(arg, nodes.Starred): + context_lookup[arg.value] = context + else: + context_lookup[arg] = context + keywords = call.keywords if call.keywords is not None else [] + for keyword in keywords: + context_lookup[keyword.value] = context + return context_lookup diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/__init__.py b/venv/lib/python3.7/site-packages/astroid/interpreter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/interpreter/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25dcd72162748b46790e360082c1630f5eb02011 GIT binary patch literal 204 zcmZ?b<>g`kf{x{1VnFm`5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o5j>zo00yEU_e2 zzbvsxKP^8eCAFwnzra90C(ELwq{`CNEW0?}+_0ds#Jn&*r6|e500`3a^h5LuG7EGw z^NLFnb8>W(iWAd|a}6@}6N^iV@-tK5bY@;jYEeN^Dv;EVkI&4@EQycTE2zB1VUwGm PQks)$2XfA5AZ7pnC{;M* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a2e4a3985134045cf8a8d245fa9f4889bc0eee5 GIT binary patch literal 2157 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__init__.py b/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60f68abe81c94c4655d4e4ff1c891a24a8687fa9 GIT binary patch literal 212 zcmYL@Jqp4=5QR5jAwmvfp%V-LKtw!%jh4c)vTGRKB zdylDR9>*;axLjZBx*xT^L}AQAd?QGUrD#Wso1psq*ZT~PuvBcIR0P|?YC|4e0(LiI zK8^c>y-$ZdSMl&5HEl*oAkAR~4qXRx&&t})#;eq434-!W1?pd8&W0SBV33%(f*7R4 W99hb)tM1K7R_LQO)B3Gvi1+{)zdRKH literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d515bfcf40058b479321a112315d4b451d5f8ab9 GIT binary patch literal 9386 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-37.pyc b/venv/lib/python3.7/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd63ed85cd8ee48f3d522e74473bfecbefb95186 GIT binary patch literal 428 zcmYjOJxc>Y5S_h?=EFop8-IY!6>+1Wi6A11g-sd-H3-KgyB?eST4y(b6H5#KiTIbU zwX(Oe(b<3>Z<+UIn4M)Fd(!E&fbjhCar;I3=87LQC^@DuyF_JMfM6+%;0p518c3G3 zaEpOEf{ow?a_<_1C;TTEd4gR)PV#;l)|hNSrCvki?v6}rYu>e88!^O zs-u%QL}`i{PNb*j3nhM4jdES(R? +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Chris Philip +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 ioanatia +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Nick Drozd + +import abc +import collections +import enum +import imp +import os +import sys +import zipimport + +try: + import importlib.machinery + + _HAS_MACHINERY = True +except ImportError: + _HAS_MACHINERY = False + +try: + from functools import lru_cache +except ImportError: + from backports.functools_lru_cache import lru_cache + +from . import util + +ModuleType = enum.Enum( + "ModuleType", + "C_BUILTIN C_EXTENSION PKG_DIRECTORY " + "PY_CODERESOURCE PY_COMPILED PY_FROZEN PY_RESOURCE " + "PY_SOURCE PY_ZIPMODULE PY_NAMESPACE", +) +_ImpTypes = { + imp.C_BUILTIN: ModuleType.C_BUILTIN, + imp.C_EXTENSION: ModuleType.C_EXTENSION, + imp.PKG_DIRECTORY: ModuleType.PKG_DIRECTORY, + imp.PY_COMPILED: ModuleType.PY_COMPILED, + imp.PY_FROZEN: ModuleType.PY_FROZEN, + imp.PY_SOURCE: ModuleType.PY_SOURCE, +} +if hasattr(imp, "PY_RESOURCE"): + _ImpTypes[imp.PY_RESOURCE] = ModuleType.PY_RESOURCE +if hasattr(imp, "PY_CODERESOURCE"): + _ImpTypes[imp.PY_CODERESOURCE] = ModuleType.PY_CODERESOURCE + + +def _imp_type_to_module_type(imp_type): + return _ImpTypes[imp_type] + + +_ModuleSpec = collections.namedtuple( + "_ModuleSpec", "name type location " "origin submodule_search_locations" +) + + +class ModuleSpec(_ModuleSpec): + """Defines a class similar to PEP 420's ModuleSpec + + A module spec defines a name of a module, its type, location + and where submodules can be found, if the module is a package. + """ + + def __new__( + cls, + name, + module_type, + location=None, + origin=None, + submodule_search_locations=None, + ): + return _ModuleSpec.__new__( + cls, + name=name, + type=module_type, + location=location, + origin=origin, + submodule_search_locations=submodule_search_locations, + ) + + +class Finder: + """A finder is a class which knows how to find a particular module.""" + + def __init__(self, path=None): + self._path = path or sys.path + + @abc.abstractmethod + def find_module(self, modname, module_parts, processed, submodule_path): + """Find the given module + + Each finder is responsible for each protocol of finding, as long as + they all return a ModuleSpec. + + :param str modname: The module which needs to be searched. + :param list module_parts: It should be a list of strings, + where each part contributes to the module's + namespace. + :param list processed: What parts from the module parts were processed + so far. + :param list submodule_path: A list of paths where the module + can be looked into. + :returns: A ModuleSpec, describing how and where the module was found, + None, otherwise. + """ + + def contribute_to_path(self, spec, processed): + """Get a list of extra paths where this finder can search.""" + + +class ImpFinder(Finder): + """A finder based on the imp module.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + if submodule_path is not None: + submodule_path = list(submodule_path) + try: + stream, mp_filename, mp_desc = imp.find_module(modname, submodule_path) + except ImportError: + return None + + # Close resources. + if stream: + stream.close() + + return ModuleSpec( + name=modname, + location=mp_filename, + module_type=_imp_type_to_module_type(mp_desc[2]), + ) + + def contribute_to_path(self, spec, processed): + if spec.location is None: + # Builtin. + return None + + if _is_setuptools_namespace(spec.location): + # extend_path is called, search sys.path for module/packages + # of this name see pkgutil.extend_path documentation + path = [ + os.path.join(p, *processed) + for p in sys.path + if os.path.isdir(os.path.join(p, *processed)) + ] + else: + path = [spec.location] + return path + + +class ExplicitNamespacePackageFinder(ImpFinder): + """A finder for the explicit namespace packages, generated through pkg_resources.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + if processed: + modname = ".".join(processed + [modname]) + if util.is_namespace(modname) and modname in sys.modules: + submodule_path = sys.modules[modname].__path__ + return ModuleSpec( + name=modname, + location="", + origin="namespace", + module_type=ModuleType.PY_NAMESPACE, + submodule_search_locations=submodule_path, + ) + return None + + def contribute_to_path(self, spec, processed): + return spec.submodule_search_locations + + +class ZipFinder(Finder): + """Finder that knows how to find a module inside zip files.""" + + def __init__(self, path): + super(ZipFinder, self).__init__(path) + self._zipimporters = _precache_zipimporters(path) + + def find_module(self, modname, module_parts, processed, submodule_path): + try: + file_type, filename, path = _search_zip(module_parts, self._zipimporters) + except ImportError: + return None + + return ModuleSpec( + name=modname, + location=filename, + origin="egg", + module_type=file_type, + submodule_search_locations=path, + ) + + +class PathSpecFinder(Finder): + """Finder based on importlib.machinery.PathFinder.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + spec = importlib.machinery.PathFinder.find_spec(modname, path=submodule_path) + if spec: + # origin can be either a string on older Python versions + # or None in case it is a namespace package: + # https://github.com/python/cpython/pull/5481 + is_namespace_pkg = spec.origin in ("namespace", None) + location = spec.origin if not is_namespace_pkg else None + module_type = ModuleType.PY_NAMESPACE if is_namespace_pkg else None + spec = ModuleSpec( + name=spec.name, + location=location, + origin=spec.origin, + module_type=module_type, + submodule_search_locations=list(spec.submodule_search_locations or []), + ) + return spec + + def contribute_to_path(self, spec, processed): + if spec.type == ModuleType.PY_NAMESPACE: + return spec.submodule_search_locations + return None + + +_SPEC_FINDERS = (ImpFinder, ZipFinder) +if _HAS_MACHINERY and sys.version_info[:2] >= (3, 4): + _SPEC_FINDERS += (PathSpecFinder,) +_SPEC_FINDERS += (ExplicitNamespacePackageFinder,) + + +def _is_setuptools_namespace(location): + try: + with open(os.path.join(location, "__init__.py"), "rb") as stream: + data = stream.read(4096) + except IOError: + pass + else: + extend_path = b"pkgutil" in data and b"extend_path" in data + declare_namespace = ( + b"pkg_resources" in data and b"declare_namespace(__name__)" in data + ) + return extend_path or declare_namespace + + +@lru_cache() +def _cached_set_diff(left, right): + result = set(left) + result.difference_update(right) + return result + + +def _precache_zipimporters(path=None): + pic = sys.path_importer_cache + + # When measured, despite having the same complexity (O(n)), + # converting to tuples and then caching the conversion to sets + # and the set difference is faster than converting to sets + # and then only caching the set difference. + + req_paths = tuple(path or sys.path) + cached_paths = tuple(pic) + new_paths = _cached_set_diff(req_paths, cached_paths) + for entry_path in new_paths: + try: + pic[entry_path] = zipimport.zipimporter(entry_path) + except zipimport.ZipImportError: + continue + return pic + + +def _search_zip(modpath, pic): + for filepath, importer in list(pic.items()): + if importer is not None: + found = importer.find_module(modpath[0]) + if found: + if not importer.find_module(os.path.sep.join(modpath)): + raise ImportError( + "No module named %s in %s/%s" + % (".".join(modpath[1:]), filepath, modpath) + ) + # import code; code.interact(local=locals()) + return ( + ModuleType.PY_ZIPMODULE, + os.path.abspath(filepath) + os.path.sep + os.path.sep.join(modpath), + filepath, + ) + raise ImportError("No module named %s" % ".".join(modpath)) + + +def _find_spec_with_path(search_path, modname, module_parts, processed, submodule_path): + finders = [finder(search_path) for finder in _SPEC_FINDERS] + for finder in finders: + spec = finder.find_module(modname, module_parts, processed, submodule_path) + if spec is None: + continue + return finder, spec + + raise ImportError("No module named %s" % ".".join(module_parts)) + + +def find_spec(modpath, path=None): + """Find a spec for the given module. + + :type modpath: list or tuple + :param modpath: + split module's name (i.e name of a module or package split + on '.'), with leading empty strings for explicit relative import + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :rtype: ModuleSpec + :return: A module spec, which describes how the module was + found and where. + """ + _path = path or sys.path + + # Need a copy for not mutating the argument. + modpath = modpath[:] + + submodule_path = None + module_parts = modpath[:] + processed = [] + + while modpath: + modname = modpath.pop(0) + finder, spec = _find_spec_with_path( + _path, modname, module_parts, processed, submodule_path or path + ) + processed.append(modname) + if modpath: + submodule_path = finder.contribute_to_path(spec, processed) + + if spec.type == ModuleType.PKG_DIRECTORY: + spec = spec._replace(submodule_search_locations=submodule_path) + + return spec diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/_import/util.py b/venv/lib/python3.7/site-packages/astroid/interpreter/_import/util.py new file mode 100644 index 0000000..a917bd3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/interpreter/_import/util.py @@ -0,0 +1,10 @@ +# Copyright (c) 2016, 2018 Claudiu Popa + +try: + import pkg_resources +except ImportError: + pkg_resources = None + + +def is_namespace(modname): + return pkg_resources is not None and modname in pkg_resources._namespace_packages diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/dunder_lookup.py b/venv/lib/python3.7/site-packages/astroid/interpreter/dunder_lookup.py new file mode 100644 index 0000000..0ae9bc9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/interpreter/dunder_lookup.py @@ -0,0 +1,66 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Contains logic for retrieving special methods. + +This implementation does not rely on the dot attribute access +logic, found in ``.getattr()``. The difference between these two +is that the dunder methods are looked with the type slots +(you can find more about these here +http://lucumr.pocoo.org/2014/8/16/the-python-i-would-like-to-see/) +As such, the lookup for the special methods is actually simpler than +the dot attribute access. +""" +import itertools + +import astroid +from astroid import exceptions + + +def _lookup_in_mro(node, name): + attrs = node.locals.get(name, []) + + nodes = itertools.chain.from_iterable( + ancestor.locals.get(name, []) for ancestor in node.ancestors(recurs=True) + ) + values = list(itertools.chain(attrs, nodes)) + if not values: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return values + + +def lookup(node, name): + """Lookup the given special method name in the given *node* + + If the special method was found, then a list of attributes + will be returned. Otherwise, `astroid.AttributeInferenceError` + is going to be raised. + """ + if isinstance( + node, (astroid.List, astroid.Tuple, astroid.Const, astroid.Dict, astroid.Set) + ): + return _builtin_lookup(node, name) + if isinstance(node, astroid.Instance): + return _lookup_in_mro(node, name) + if isinstance(node, astroid.ClassDef): + return _class_lookup(node, name) + + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + +def _class_lookup(node, name): + metaclass = node.metaclass() + if metaclass is None: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return _lookup_in_mro(metaclass, name) + + +def _builtin_lookup(node, name): + values = node.locals.get(name, []) + if not values: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return values diff --git a/venv/lib/python3.7/site-packages/astroid/interpreter/objectmodel.py b/venv/lib/python3.7/site-packages/astroid/interpreter/objectmodel.py new file mode 100644 index 0000000..581930d --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/interpreter/objectmodel.py @@ -0,0 +1,728 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017-2018 Bryce Guinta +# Copyright (c) 2017 Ceridwen +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Nick Drozd +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +""" +Data object model, as per https://docs.python.org/3/reference/datamodel.html. + +This module describes, at least partially, a data object model for some +of astroid's nodes. The model contains special attributes that nodes such +as functions, classes, modules etc have, such as __doc__, __class__, +__module__ etc, being used when doing attribute lookups over nodes. + +For instance, inferring `obj.__class__` will first trigger an inference +of the `obj` variable. If it was successfully inferred, then an attribute +`__class__ will be looked for in the inferred object. This is the part +where the data model occurs. The model is attached to those nodes +and the lookup mechanism will try to see if attributes such as +`__class__` are defined by the model or not. If they are defined, +the model will be requested to return the corresponding value of that +attribute. Thus the model can be viewed as a special part of the lookup +mechanism. +""" + +import itertools +import pprint +import os +import types +from functools import lru_cache + +import astroid +from astroid import context as contextmod +from astroid import exceptions +from astroid import node_classes + + +IMPL_PREFIX = "attr_" + + +def _dunder_dict(instance, attributes): + obj = node_classes.Dict(parent=instance) + + # Convert the keys to node strings + keys = [ + node_classes.Const(value=value, parent=obj) for value in list(attributes.keys()) + ] + + # The original attribute has a list of elements for each key, + # but that is not useful for retrieving the special attribute's value. + # In this case, we're picking the last value from each list. + values = [elem[-1] for elem in attributes.values()] + + obj.postinit(list(zip(keys, values))) + return obj + + +class ObjectModel: + def __init__(self): + self._instance = None + + def __repr__(self): + result = [] + cname = type(self).__name__ + string = "%(cname)s(%(fields)s)" + alignment = len(cname) + 1 + for field in sorted(self.attributes()): + width = 80 - len(field) - alignment + lines = pprint.pformat(field, indent=2, width=width).splitlines(True) + + inner = [lines[0]] + for line in lines[1:]: + inner.append(" " * alignment + line) + result.append(field) + + return string % { + "cname": cname, + "fields": (",\n" + " " * alignment).join(result), + } + + def __call__(self, instance): + self._instance = instance + return self + + def __get__(self, instance, cls=None): + # ObjectModel needs to be a descriptor so that just doing + # `special_attributes = SomeObjectModel` should be enough in the body of a node. + # But at the same time, node.special_attributes should return an object + # which can be used for manipulating the special attributes. That's the reason + # we pass the instance through which it got accessed to ObjectModel.__call__, + # returning itself afterwards, so we can still have access to the + # underlying data model and to the instance for which it got accessed. + return self(instance) + + def __contains__(self, name): + return name in self.attributes() + + @lru_cache(maxsize=None) + def attributes(self): + """Get the attributes which are exported by this object model.""" + return [ + obj[len(IMPL_PREFIX) :] for obj in dir(self) if obj.startswith(IMPL_PREFIX) + ] + + def lookup(self, name): + """Look up the given *name* in the current model + + It should return an AST or an interpreter object, + but if the name is not found, then an AttributeInferenceError will be raised. + """ + + if name in self.attributes(): + return getattr(self, IMPL_PREFIX + name) + raise exceptions.AttributeInferenceError(target=self._instance, attribute=name) + + +class ModuleModel(ObjectModel): + def _builtins(self): + builtins_ast_module = astroid.MANAGER.builtins_module + return builtins_ast_module.special_attributes.lookup("__dict__") + + @property + def attr_builtins(self): + return self._builtins() + + @property + def attr___path__(self): + if not self._instance.package: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__path__" + ) + + path_objs = [ + node_classes.Const( + value=path + if not path.endswith("__init__.py") + else os.path.dirname(path), + parent=self._instance, + ) + for path in self._instance.path + ] + + container = node_classes.List(parent=self._instance) + container.postinit(path_objs) + + return container + + @property + def attr___name__(self): + return node_classes.Const(value=self._instance.name, parent=self._instance) + + @property + def attr___doc__(self): + return node_classes.Const(value=self._instance.doc, parent=self._instance) + + @property + def attr___file__(self): + return node_classes.Const(value=self._instance.file, parent=self._instance) + + @property + def attr___dict__(self): + return _dunder_dict(self._instance, self._instance.globals) + + @property + def attr___package__(self): + if not self._instance.package: + value = "" + else: + value = self._instance.name + + return node_classes.Const(value=value, parent=self._instance) + + # These are related to the Python 3 implementation of the + # import system, + # https://docs.python.org/3/reference/import.html#import-related-module-attributes + + @property + def attr___spec__(self): + # No handling for now. + return node_classes.Unknown() + + @property + def attr___loader__(self): + # No handling for now. + return node_classes.Unknown() + + @property + def attr___cached__(self): + # No handling for now. + return node_classes.Unknown() + + +class FunctionModel(ObjectModel): + @property + def attr___name__(self): + return node_classes.Const(value=self._instance.name, parent=self._instance) + + @property + def attr___doc__(self): + return node_classes.Const(value=self._instance.doc, parent=self._instance) + + @property + def attr___qualname__(self): + return node_classes.Const(value=self._instance.qname(), parent=self._instance) + + @property + def attr___defaults__(self): + func = self._instance + if not func.args.defaults: + return node_classes.Const(value=None, parent=func) + + defaults_obj = node_classes.Tuple(parent=func) + defaults_obj.postinit(func.args.defaults) + return defaults_obj + + @property + def attr___annotations__(self): + obj = node_classes.Dict(parent=self._instance) + + if not self._instance.returns: + returns = None + else: + returns = self._instance.returns + + args = self._instance.args + pair_annotations = itertools.chain( + zip(args.args or [], args.annotations), + zip(args.kwonlyargs, args.kwonlyargs_annotations), + ) + + annotations = { + arg.name: annotation for (arg, annotation) in pair_annotations if annotation + } + if args.varargannotation: + annotations[args.vararg] = args.varargannotation + if args.kwargannotation: + annotations[args.kwarg] = args.kwargannotation + if returns: + annotations["return"] = returns + + items = [ + (node_classes.Const(key, parent=obj), value) + for (key, value) in annotations.items() + ] + + obj.postinit(items) + return obj + + @property + def attr___dict__(self): + return node_classes.Dict(parent=self._instance) + + attr___globals__ = attr___dict__ + + @property + def attr___kwdefaults__(self): + def _default_args(args, parent): + for arg in args.kwonlyargs: + try: + default = args.default_value(arg.name) + except exceptions.NoDefault: + continue + + name = node_classes.Const(arg.name, parent=parent) + yield name, default + + args = self._instance.args + obj = node_classes.Dict(parent=self._instance) + defaults = dict(_default_args(args, obj)) + + obj.postinit(list(defaults.items())) + return obj + + @property + def attr___module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def attr___get__(self): + from astroid import bases + + func = self._instance + + class DescriptorBoundMethod(bases.BoundMethod): + """Bound method which knows how to understand calling descriptor binding.""" + + def implicit_parameters(self): + # Different than BoundMethod since the signature + # is different. + return 0 + + def infer_call_result(self, caller, context=None): + if len(caller.args) != 2: + raise exceptions.InferenceError( + "Invalid arguments for descriptor binding", + target=self, + context=context, + ) + + context = contextmod.copy_context(context) + cls = next(caller.args[0].infer(context=context)) + + if cls is astroid.Uninferable: + raise exceptions.InferenceError( + "Invalid class inferred", target=self, context=context + ) + + # For some reason func is a Node that the below + # code is not expecting + if isinstance(func, bases.BoundMethod): + yield func + return + + # Rebuild the original value, but with the parent set as the + # class where it will be bound. + new_func = func.__class__( + name=func.name, + doc=func.doc, + lineno=func.lineno, + col_offset=func.col_offset, + parent=cls, + ) + # pylint: disable=no-member + new_func.postinit(func.args, func.body, func.decorators, func.returns) + + # Build a proper bound method that points to our newly built function. + proxy = bases.UnboundMethod(new_func) + yield bases.BoundMethod(proxy=proxy, bound=cls) + + @property + def args(self): + """Overwrite the underlying args to match those of the underlying func + + Usually the underlying *func* is a function/method, as in: + + def test(self): + pass + + This has only the *self* parameter but when we access test.__get__ + we get a new object which has two parameters, *self* and *type*. + """ + nonlocal func + params = func.args.args.copy() + params.append(astroid.AssignName(name="type")) + arguments = astroid.Arguments(parent=func.args.parent) + arguments.postinit( + args=params, + defaults=[], + kwonlyargs=[], + kw_defaults=[], + annotations=[], + ) + return arguments + + return DescriptorBoundMethod(proxy=self._instance, bound=self._instance) + + # These are here just for completion. + @property + def attr___ne__(self): + return node_classes.Unknown() + + attr___subclasshook__ = attr___ne__ + attr___str__ = attr___ne__ + attr___sizeof__ = attr___ne__ + attr___setattr___ = attr___ne__ + attr___repr__ = attr___ne__ + attr___reduce__ = attr___ne__ + attr___reduce_ex__ = attr___ne__ + attr___new__ = attr___ne__ + attr___lt__ = attr___ne__ + attr___eq__ = attr___ne__ + attr___gt__ = attr___ne__ + attr___format__ = attr___ne__ + attr___delattr___ = attr___ne__ + attr___getattribute__ = attr___ne__ + attr___hash__ = attr___ne__ + attr___init__ = attr___ne__ + attr___dir__ = attr___ne__ + attr___call__ = attr___ne__ + attr___class__ = attr___ne__ + attr___closure__ = attr___ne__ + attr___code__ = attr___ne__ + + +class ClassModel(ObjectModel): + @property + def attr___module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def attr___name__(self): + return node_classes.Const(self._instance.name) + + @property + def attr___qualname__(self): + return node_classes.Const(self._instance.qname()) + + @property + def attr___doc__(self): + return node_classes.Const(self._instance.doc) + + @property + def attr___mro__(self): + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__mro__" + ) + + mro = self._instance.mro() + obj = node_classes.Tuple(parent=self._instance) + obj.postinit(mro) + return obj + + @property + def attr_mro(self): + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="mro" + ) + + from astroid import bases + + other_self = self + + # Cls.mro is a method and we need to return one in order to have a proper inference. + # The method we're returning is capable of inferring the underlying MRO though. + class MroBoundMethod(bases.BoundMethod): + def infer_call_result(self, caller, context=None): + yield other_self.attr___mro__ + + implicit_metaclass = self._instance.implicit_metaclass() + mro_method = implicit_metaclass.locals["mro"][0] + return MroBoundMethod(proxy=mro_method, bound=implicit_metaclass) + + @property + def attr___bases__(self): + obj = node_classes.Tuple() + context = contextmod.InferenceContext() + elts = list(self._instance._inferred_bases(context)) + obj.postinit(elts=elts) + return obj + + @property + def attr___class__(self): + from astroid import helpers + + return helpers.object_type(self._instance) + + @property + def attr___subclasses__(self): + """Get the subclasses of the underlying class + + This looks only in the current module for retrieving the subclasses, + thus it might miss a couple of them. + """ + from astroid import bases + from astroid import scoped_nodes + + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__subclasses__" + ) + + qname = self._instance.qname() + root = self._instance.root() + classes = [ + cls + for cls in root.nodes_of_class(scoped_nodes.ClassDef) + if cls != self._instance and cls.is_subtype_of(qname) + ] + + obj = node_classes.List(parent=self._instance) + obj.postinit(classes) + + class SubclassesBoundMethod(bases.BoundMethod): + def infer_call_result(self, caller, context=None): + yield obj + + implicit_metaclass = self._instance.implicit_metaclass() + subclasses_method = implicit_metaclass.locals["__subclasses__"][0] + return SubclassesBoundMethod(proxy=subclasses_method, bound=implicit_metaclass) + + @property + def attr___dict__(self): + return node_classes.Dict(parent=self._instance) + + +class SuperModel(ObjectModel): + @property + def attr___thisclass__(self): + return self._instance.mro_pointer + + @property + def attr___self_class__(self): + return self._instance._self_class + + @property + def attr___self__(self): + return self._instance.type + + @property + def attr___class__(self): + return self._instance._proxied + + +class UnboundMethodModel(ObjectModel): + @property + def attr___class__(self): + from astroid import helpers + + return helpers.object_type(self._instance) + + @property + def attr___func__(self): + return self._instance._proxied + + @property + def attr___self__(self): + return node_classes.Const(value=None, parent=self._instance) + + attr_im_func = attr___func__ + attr_im_class = attr___class__ + attr_im_self = attr___self__ + + +class BoundMethodModel(FunctionModel): + @property + def attr___func__(self): + return self._instance._proxied._proxied + + @property + def attr___self__(self): + return self._instance.bound + + +class GeneratorModel(FunctionModel): + def __new__(cls, *args, **kwargs): + # Append the values from the GeneratorType unto this object. + ret = super(GeneratorModel, cls).__new__(cls, *args, **kwargs) + generator = astroid.MANAGER.builtins_module["generator"] + for name, values in generator.locals.items(): + method = values[0] + patched = lambda cls, meth=method: meth + + setattr(type(ret), IMPL_PREFIX + name, property(patched)) + + return ret + + @property + def attr___name__(self): + return node_classes.Const( + value=self._instance.parent.name, parent=self._instance + ) + + @property + def attr___doc__(self): + return node_classes.Const( + value=self._instance.parent.doc, parent=self._instance + ) + + +class AsyncGeneratorModel(GeneratorModel): + def __new__(cls, *args, **kwargs): + # Append the values from the AGeneratorType unto this object. + ret = super().__new__(cls, *args, **kwargs) + astroid_builtins = astroid.MANAGER.builtins_module + generator = astroid_builtins.get("async_generator") + if generator is None: + # Make it backward compatible. + generator = astroid_builtins.get("generator") + + for name, values in generator.locals.items(): + method = values[0] + patched = lambda cls, meth=method: meth + + setattr(type(ret), IMPL_PREFIX + name, property(patched)) + + return ret + + +class InstanceModel(ObjectModel): + @property + def attr___class__(self): + return self._instance._proxied + + @property + def attr___module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def attr___doc__(self): + return node_classes.Const(self._instance.doc) + + @property + def attr___dict__(self): + return _dunder_dict(self._instance, self._instance.instance_attrs) + + +# Exception instances + + +class ExceptionInstanceModel(InstanceModel): + @property + def attr_args(self): + message = node_classes.Const("") + args = node_classes.Tuple(parent=self._instance) + args.postinit((message,)) + return args + + @property + def attr___traceback__(self): + builtins_ast_module = astroid.MANAGER.builtins_module + traceback_type = builtins_ast_module[types.TracebackType.__name__] + return traceback_type.instantiate_class() + + +class SyntaxErrorInstanceModel(ExceptionInstanceModel): + @property + def attr_text(self): + return node_classes.Const("") + + +class OSErrorInstanceModel(ExceptionInstanceModel): + @property + def attr_filename(self): + return node_classes.Const("") + + @property + def attr_errno(self): + return node_classes.Const(0) + + @property + def attr_strerror(self): + return node_classes.Const("") + + attr_filename2 = attr_filename + + +class ImportErrorInstanceModel(ExceptionInstanceModel): + @property + def attr_name(self): + return node_classes.Const("") + + @property + def attr_path(self): + return node_classes.Const("") + + +BUILTIN_EXCEPTIONS = { + "builtins.SyntaxError": SyntaxErrorInstanceModel, + "builtins.ImportError": ImportErrorInstanceModel, + # These are all similar to OSError in terms of attributes + "builtins.OSError": OSErrorInstanceModel, + "builtins.BlockingIOError": OSErrorInstanceModel, + "builtins.BrokenPipeError": OSErrorInstanceModel, + "builtins.ChildProcessError": OSErrorInstanceModel, + "builtins.ConnectionAbortedError": OSErrorInstanceModel, + "builtins.ConnectionError": OSErrorInstanceModel, + "builtins.ConnectionRefusedError": OSErrorInstanceModel, + "builtins.ConnectionResetError": OSErrorInstanceModel, + "builtins.FileExistsError": OSErrorInstanceModel, + "builtins.FileNotFoundError": OSErrorInstanceModel, + "builtins.InterruptedError": OSErrorInstanceModel, + "builtins.IsADirectoryError": OSErrorInstanceModel, + "builtins.NotADirectoryError": OSErrorInstanceModel, + "builtins.PermissionError": OSErrorInstanceModel, + "builtins.ProcessLookupError": OSErrorInstanceModel, + "builtins.TimeoutError": OSErrorInstanceModel, +} + + +class DictModel(ObjectModel): + @property + def attr___class__(self): + return self._instance._proxied + + def _generic_dict_attribute(self, obj, name): + """Generate a bound method that can infer the given *obj*.""" + + class DictMethodBoundMethod(astroid.BoundMethod): + def infer_call_result(self, caller, context=None): + yield obj + + meth = next(self._instance._proxied.igetattr(name)) + return DictMethodBoundMethod(proxy=meth, bound=self._instance) + + @property + def attr_items(self): + elems = [] + obj = node_classes.List(parent=self._instance) + for key, value in self._instance.items: + elem = node_classes.Tuple(parent=obj) + elem.postinit((key, value)) + elems.append(elem) + obj.postinit(elts=elems) + + from astroid import objects + + obj = objects.DictItems(obj) + + return self._generic_dict_attribute(obj, "items") + + @property + def attr_keys(self): + keys = [key for (key, _) in self._instance.items] + obj = node_classes.List(parent=self._instance) + obj.postinit(elts=keys) + + from astroid import objects + + obj = objects.DictKeys(obj) + + return self._generic_dict_attribute(obj, "keys") + + @property + def attr_values(self): + + values = [value for (_, value) in self._instance.items] + obj = node_classes.List(parent=self._instance) + obj.postinit(values) + + from astroid import objects + + obj = objects.DictValues(obj) + + return self._generic_dict_attribute(obj, "values") diff --git a/venv/lib/python3.7/site-packages/astroid/manager.py b/venv/lib/python3.7/site-packages/astroid/manager.py new file mode 100644 index 0000000..4388514 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/manager.py @@ -0,0 +1,327 @@ +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 BioGeek +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Iva Miholic +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""astroid manager: avoid multiple astroid build of a same module when +possible by providing a class responsible to get astroid representation +from various source and using a cache of built modules) +""" + +import os +import zipimport + +from astroid import exceptions +from astroid.interpreter._import import spec +from astroid import modutils +from astroid import transforms + + +def safe_repr(obj): + try: + return repr(obj) + except Exception: # pylint: disable=broad-except + return "???" + + +class AstroidManager: + """the astroid manager, responsible to build astroid from files + or modules. + + Use the Borg pattern. + """ + + name = "astroid loader" + brain = {} + + def __init__(self): + self.__dict__ = AstroidManager.brain + if not self.__dict__: + # NOTE: cache entries are added by the [re]builder + self.astroid_cache = {} + self._mod_file_cache = {} + self._failed_import_hooks = [] + self.always_load_extensions = False + self.optimize_ast = False + self.extension_package_whitelist = set() + self._transform = transforms.TransformVisitor() + + # Export these APIs for convenience + self.register_transform = self._transform.register_transform + self.unregister_transform = self._transform.unregister_transform + self.max_inferable_values = 100 + + @property + def builtins_module(self): + return self.astroid_cache["builtins"] + + def visit_transforms(self, node): + """Visit the transforms and apply them to the given *node*.""" + return self._transform.visit(node) + + def ast_from_file(self, filepath, modname=None, fallback=True, source=False): + """given a module name, return the astroid object""" + try: + filepath = modutils.get_source_file(filepath, include_no_ext=True) + source = True + except modutils.NoSourceFile: + pass + if modname is None: + try: + modname = ".".join(modutils.modpath_from_file(filepath)) + except ImportError: + modname = filepath + if ( + modname in self.astroid_cache + and self.astroid_cache[modname].file == filepath + ): + return self.astroid_cache[modname] + if source: + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).file_build(filepath, modname) + if fallback and modname: + return self.ast_from_module_name(modname) + raise exceptions.AstroidBuildingError( + "Unable to build an AST for {path}.", path=filepath + ) + + def _build_stub_module(self, modname): + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).string_build("", modname) + + def _build_namespace_module(self, modname, path): + from astroid.builder import build_namespace_package_module + + return build_namespace_package_module(modname, path) + + def _can_load_extension(self, modname): + if self.always_load_extensions: + return True + if modutils.is_standard_module(modname): + return True + parts = modname.split(".") + return any( + ".".join(parts[:x]) in self.extension_package_whitelist + for x in range(1, len(parts) + 1) + ) + + def ast_from_module_name(self, modname, context_file=None): + """given a module name, return the astroid object""" + if modname in self.astroid_cache: + return self.astroid_cache[modname] + if modname == "__main__": + return self._build_stub_module(modname) + old_cwd = os.getcwd() + if context_file: + os.chdir(os.path.dirname(context_file)) + try: + found_spec = self.file_from_module_name(modname, context_file) + if found_spec.type == spec.ModuleType.PY_ZIPMODULE: + module = self.zip_import_data(found_spec.location) + if module is not None: + return module + + elif found_spec.type in ( + spec.ModuleType.C_BUILTIN, + spec.ModuleType.C_EXTENSION, + ): + if ( + found_spec.type == spec.ModuleType.C_EXTENSION + and not self._can_load_extension(modname) + ): + return self._build_stub_module(modname) + try: + module = modutils.load_module_from_name(modname) + except Exception as ex: + raise exceptions.AstroidImportError( + "Loading {modname} failed with:\n{error}", + modname=modname, + path=found_spec.location, + ) from ex + return self.ast_from_module(module, modname) + + elif found_spec.type == spec.ModuleType.PY_COMPILED: + raise exceptions.AstroidImportError( + "Unable to load compiled module {modname}.", + modname=modname, + path=found_spec.location, + ) + + elif found_spec.type == spec.ModuleType.PY_NAMESPACE: + return self._build_namespace_module( + modname, found_spec.submodule_search_locations + ) + + if found_spec.location is None: + raise exceptions.AstroidImportError( + "Can't find a file for module {modname}.", modname=modname + ) + + return self.ast_from_file(found_spec.location, modname, fallback=False) + except exceptions.AstroidBuildingError as e: + for hook in self._failed_import_hooks: + try: + return hook(modname) + except exceptions.AstroidBuildingError: + pass + raise e + finally: + os.chdir(old_cwd) + + def zip_import_data(self, filepath): + if zipimport is None: + return None + from astroid.builder import AstroidBuilder + + builder = AstroidBuilder(self) + for ext in (".zip", ".egg"): + try: + eggpath, resource = filepath.rsplit(ext + os.path.sep, 1) + except ValueError: + continue + try: + importer = zipimport.zipimporter(eggpath + ext) + zmodname = resource.replace(os.path.sep, ".") + if importer.is_package(resource): + zmodname = zmodname + ".__init__" + module = builder.string_build( + importer.get_source(resource), zmodname, filepath + ) + return module + except Exception: # pylint: disable=broad-except + continue + return None + + def file_from_module_name(self, modname, contextfile): + try: + value = self._mod_file_cache[(modname, contextfile)] + except KeyError: + try: + value = modutils.file_info_from_modpath( + modname.split("."), context_file=contextfile + ) + except ImportError as ex: + value = exceptions.AstroidImportError( + "Failed to import module {modname} with error:\n{error}.", + modname=modname, + error=ex, + ) + self._mod_file_cache[(modname, contextfile)] = value + if isinstance(value, exceptions.AstroidBuildingError): + raise value + return value + + def ast_from_module(self, module, modname=None): + """given an imported module, return the astroid object""" + modname = modname or module.__name__ + if modname in self.astroid_cache: + return self.astroid_cache[modname] + try: + # some builtin modules don't have __file__ attribute + filepath = module.__file__ + if modutils.is_python_source(filepath): + return self.ast_from_file(filepath, modname) + except AttributeError: + pass + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).module_build(module, modname) + + def ast_from_class(self, klass, modname=None): + """get astroid for the given class""" + if modname is None: + try: + modname = klass.__module__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get module for class {class_name}.", + cls=klass, + class_repr=safe_repr(klass), + modname=modname, + ) from exc + modastroid = self.ast_from_module_name(modname) + return modastroid.getattr(klass.__name__)[0] # XXX + + def infer_ast_from_something(self, obj, context=None): + """infer astroid for the given class""" + if hasattr(obj, "__class__") and not isinstance(obj, type): + klass = obj.__class__ + else: + klass = obj + try: + modname = klass.__module__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get module for {class_repr}.", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + except Exception as exc: + raise exceptions.AstroidImportError( + "Unexpected error while retrieving module for {class_repr}:\n" + "{error}", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + try: + name = klass.__name__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get name for {class_repr}:\n", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + except Exception as exc: + raise exceptions.AstroidImportError( + "Unexpected error while retrieving name for {class_repr}:\n" "{error}", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + # take care, on living object __module__ is regularly wrong :( + modastroid = self.ast_from_module_name(modname) + if klass is obj: + for inferred in modastroid.igetattr(name, context): + yield inferred + else: + for inferred in modastroid.igetattr(name, context): + yield inferred.instantiate_class() + + def register_failed_import_hook(self, hook): + """Registers a hook to resolve imports that cannot be found otherwise. + + `hook` must be a function that accepts a single argument `modname` which + contains the name of the module or package that could not be imported. + If `hook` can resolve the import, must return a node of type `astroid.Module`, + otherwise, it must raise `AstroidBuildingError`. + """ + self._failed_import_hooks.append(hook) + + def cache_module(self, module): + """Cache a module if no module with the same name is known yet.""" + self.astroid_cache.setdefault(module.name, module) + + def bootstrap(self): + """Bootstrap the required AST modules needed for the manager to work + + The bootstrap usually involves building the AST for the builtins + module, which is required by the rest of astroid to work correctly. + """ + import astroid.raw_building + + astroid.raw_building._astroid_bootstrapping() + + def clear_cache(self): + """Clear the underlying cache. Also bootstraps the builtins module.""" + self.astroid_cache.clear() + self.bootstrap() diff --git a/venv/lib/python3.7/site-packages/astroid/mixins.py b/venv/lib/python3.7/site-packages/astroid/mixins.py new file mode 100644 index 0000000..497a840 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/mixins.py @@ -0,0 +1,160 @@ +# Copyright (c) 2010-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2016, 2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module contains some mixins for the different nodes. +""" +import itertools + +from astroid import decorators +from astroid import exceptions + + +class BlockRangeMixIn: + """override block range """ + + @decorators.cachedproperty + def blockstart_tolineno(self): + return self.lineno + + def _elsed_block_range(self, lineno, orelse, last=None): + """handle block line numbers range for try/finally, for, if and while + statements + """ + if lineno == self.fromlineno: + return lineno, lineno + if orelse: + if lineno >= orelse[0].fromlineno: + return lineno, orelse[-1].tolineno + return lineno, orelse[0].fromlineno - 1 + return lineno, last or self.tolineno + + +class FilterStmtsMixin: + """Mixin for statement filtering and assignment type""" + + def _get_filtered_stmts(self, _, node, _stmts, mystmt): + """method used in _filter_stmts to get statements and trigger break""" + if self.statement() is mystmt: + # original node's statement is the assignment, only keep + # current node (gen exp, list comp) + return [node], True + return _stmts, False + + def assign_type(self): + return self + + +class AssignTypeMixin: + def assign_type(self): + return self + + def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt): + """method used in filter_stmts""" + if self is mystmt: + return _stmts, True + if self.statement() is mystmt: + # original node's statement is the assignment, only keep + # current node (gen exp, list comp) + return [node], True + return _stmts, False + + +class ParentAssignTypeMixin(AssignTypeMixin): + def assign_type(self): + return self.parent.assign_type() + + +class ImportFromMixin(FilterStmtsMixin): + """MixIn for From and Import Nodes""" + + def _infer_name(self, frame, name): + return name + + def do_import_module(self, modname=None): + """return the ast for a module whose name is imported by + """ + # handle special case where we are on a package node importing a module + # using the same name as the package, which may end in an infinite loop + # on relative imports + # XXX: no more needed ? + mymodule = self.root() + level = getattr(self, "level", None) # Import as no level + if modname is None: + modname = self.modname + # XXX we should investigate deeper if we really want to check + # importing itself: modname and mymodule.name be relative or absolute + if mymodule.relative_to_absolute_name(modname, level) == mymodule.name: + # FIXME: we used to raise InferenceError here, but why ? + return mymodule + + return mymodule.import_module( + modname, level=level, relative_only=level and level >= 1 + ) + + def real_name(self, asname): + """get name from 'as' name""" + for name, _asname in self.names: + if name == "*": + return asname + if not _asname: + name = name.split(".", 1)[0] + _asname = name + if asname == _asname: + return name + raise exceptions.AttributeInferenceError( + "Could not find original name for {attribute} in {target!r}", + target=self, + attribute=asname, + ) + + +class MultiLineBlockMixin: + """Mixin for nodes with multi-line blocks, e.g. For and FunctionDef. + Note that this does not apply to every node with a `body` field. + For instance, an If node has a multi-line body, but the body of an + IfExpr is not multi-line, and hence cannot contain Return nodes, + Assign nodes, etc. + """ + + @decorators.cachedproperty + def _multi_line_blocks(self): + return tuple(getattr(self, field) for field in self._multi_line_block_fields) + + def _get_return_nodes_skip_functions(self): + for block in self._multi_line_blocks: + for child_node in block: + if child_node.is_function: + continue + yield from child_node._get_return_nodes_skip_functions() + + def _get_yield_nodes_skip_lambdas(self): + for block in self._multi_line_blocks: + for child_node in block: + if child_node.is_lambda: + continue + yield from child_node._get_yield_nodes_skip_lambdas() + + @decorators.cached + def _get_assign_nodes(self): + children_assign_nodes = ( + child_node._get_assign_nodes() + for block in self._multi_line_blocks + for child_node in block + ) + return list(itertools.chain.from_iterable(children_assign_nodes)) + + +class NoChildrenMixin: + """Mixin for nodes with no children, e.g. Pass.""" + + def get_children(self): + yield from () diff --git a/venv/lib/python3.7/site-packages/astroid/modutils.py b/venv/lib/python3.7/site-packages/astroid/modutils.py new file mode 100644 index 0000000..4e6f918 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/modutils.py @@ -0,0 +1,704 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Denis Laxalde +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 RadosÅ‚aw Ganczarek +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2018 Mario Corchero +# Copyright (c) 2018 Mario Corchero +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Python modules manipulation utility functions. + +:type PY_SOURCE_EXTS: tuple(str) +:var PY_SOURCE_EXTS: list of possible python source file extension + +:type STD_LIB_DIRS: set of str +:var STD_LIB_DIRS: directories where standard modules are located + +:type BUILTIN_MODULES: dict +:var BUILTIN_MODULES: dictionary with builtin module names has key +""" +import imp +import os +import platform +import sys +import itertools +from distutils.sysconfig import get_python_lib # pylint: disable=import-error + +# pylint: disable=import-error, no-name-in-module +from distutils.errors import DistutilsPlatformError + +# distutils is replaced by virtualenv with a module that does +# weird path manipulations in order to get to the +# real distutils module. + +from .interpreter._import import spec +from .interpreter._import import util + +if sys.platform.startswith("win"): + PY_SOURCE_EXTS = ("py", "pyw") + PY_COMPILED_EXTS = ("dll", "pyd") +else: + PY_SOURCE_EXTS = ("py",) + PY_COMPILED_EXTS = ("so",) + + +try: + # The explicit sys.prefix is to work around a patch in virtualenv that + # replaces the 'real' sys.prefix (i.e. the location of the binary) + # with the prefix from which the virtualenv was created. This throws + # off the detection logic for standard library modules, thus the + # workaround. + STD_LIB_DIRS = { + get_python_lib(standard_lib=True, prefix=sys.prefix), + # Take care of installations where exec_prefix != prefix. + get_python_lib(standard_lib=True, prefix=sys.exec_prefix), + get_python_lib(standard_lib=True), + } +# get_python_lib(standard_lib=1) is not available on pypy, set STD_LIB_DIR to +# non-valid path, see https://bugs.pypy.org/issue1164 +except DistutilsPlatformError: + STD_LIB_DIRS = set() + +if os.name == "nt": + STD_LIB_DIRS.add(os.path.join(sys.prefix, "dlls")) + try: + # real_prefix is defined when running inside virtual environments, + # created with the **virtualenv** library. + STD_LIB_DIRS.add(os.path.join(sys.real_prefix, "dlls")) + except AttributeError: + # sys.base_exec_prefix is always defined, but in a virtual environment + # created with the stdlib **venv** module, it points to the original + # installation, if the virtual env is activated. + try: + STD_LIB_DIRS.add(os.path.join(sys.base_exec_prefix, "dlls")) + except AttributeError: + pass + +if platform.python_implementation() == "PyPy": + _root = os.path.join(sys.prefix, "lib_pypy") + STD_LIB_DIRS.add(_root) + try: + # real_prefix is defined when running inside virtualenv. + STD_LIB_DIRS.add(os.path.join(sys.real_prefix, "lib_pypy")) + except AttributeError: + pass + del _root +if os.name == "posix": + # Need the real prefix is we're under a virtualenv, otherwise + # the usual one will do. + try: + prefix = sys.real_prefix + except AttributeError: + prefix = sys.prefix + + def _posix_path(path): + base_python = "python%d.%d" % sys.version_info[:2] + return os.path.join(prefix, path, base_python) + + STD_LIB_DIRS.add(_posix_path("lib")) + if sys.maxsize > 2 ** 32: + # This tries to fix a problem with /usr/lib64 builds, + # where systems are running both 32-bit and 64-bit code + # on the same machine, which reflects into the places where + # standard library could be found. More details can be found + # here http://bugs.python.org/issue1294959. + # An easy reproducing case would be + # https://github.com/PyCQA/pylint/issues/712#issuecomment-163178753 + STD_LIB_DIRS.add(_posix_path("lib64")) + +EXT_LIB_DIR = get_python_lib() +IS_JYTHON = platform.python_implementation() == "Jython" +BUILTIN_MODULES = dict.fromkeys(sys.builtin_module_names, True) + + +class NoSourceFile(Exception): + """exception raised when we are not able to get a python + source file for a precompiled file + """ + + +def _normalize_path(path): + return os.path.normcase(os.path.abspath(path)) + + +def _canonicalize_path(path): + return os.path.realpath(os.path.expanduser(path)) + + +def _path_from_filename(filename, is_jython=IS_JYTHON): + if not is_jython: + if sys.version_info > (3, 0): + return filename + if filename.endswith(".pyc"): + return filename[:-1] + return filename + head, has_pyclass, _ = filename.partition("$py.class") + if has_pyclass: + return head + ".py" + return filename + + +def _handle_blacklist(blacklist, dirnames, filenames): + """remove files/directories in the black list + + dirnames/filenames are usually from os.walk + """ + for norecurs in blacklist: + if norecurs in dirnames: + dirnames.remove(norecurs) + elif norecurs in filenames: + filenames.remove(norecurs) + + +_NORM_PATH_CACHE = {} + + +def _cache_normalize_path(path): + """abspath with caching""" + # _module_file calls abspath on every path in sys.path every time it's + # called; on a larger codebase this easily adds up to half a second just + # assembling path components. This cache alleviates that. + try: + return _NORM_PATH_CACHE[path] + except KeyError: + if not path: # don't cache result for '' + return _normalize_path(path) + result = _NORM_PATH_CACHE[path] = _normalize_path(path) + return result + + +def load_module_from_name(dotted_name, path=None, use_sys=True): + """Load a Python module from its name. + + :type dotted_name: str + :param dotted_name: python name of a module or package + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be + used or not + + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + return load_module_from_modpath(dotted_name.split("."), path, use_sys) + + +def load_module_from_modpath(parts, path=None, use_sys=1): + """Load a python module from its split name. + + :type parts: list(str) or tuple(str) + :param parts: + python name of a module or package split on '.' + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be used or not + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + if use_sys: + try: + return sys.modules[".".join(parts)] + except KeyError: + pass + modpath = [] + prevmodule = None + for part in parts: + modpath.append(part) + curname = ".".join(modpath) + module = None + if len(modpath) != len(parts): + # even with use_sys=False, should try to get outer packages from sys.modules + module = sys.modules.get(curname) + elif use_sys: + # because it may have been indirectly loaded through a parent + module = sys.modules.get(curname) + if module is None: + mp_file, mp_filename, mp_desc = imp.find_module(part, path) + module = imp.load_module(curname, mp_file, mp_filename, mp_desc) + # mp_file still needs to be closed. + if mp_file: + mp_file.close() + if prevmodule: + setattr(prevmodule, part, module) + _file = getattr(module, "__file__", "") + prevmodule = module + if not _file and util.is_namespace(curname): + continue + if not _file and len(modpath) != len(parts): + raise ImportError("no module in %s" % ".".join(parts[len(modpath) :])) + path = [os.path.dirname(_file)] + return module + + +def load_module_from_file(filepath, path=None, use_sys=True, extrapath=None): + """Load a Python module from it's path. + + :type filepath: str + :param filepath: path to the python module or package + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be + used or not + + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + modpath = modpath_from_file(filepath, extrapath) + return load_module_from_modpath(modpath, path, use_sys) + + +def check_modpath_has_init(path, mod_path): + """check there are some __init__.py all along the way""" + modpath = [] + for part in mod_path: + modpath.append(part) + path = os.path.join(path, part) + if not _has_init(path): + old_namespace = util.is_namespace(".".join(modpath)) + if not old_namespace: + return False + return True + + +def _get_relative_base_path(filename, path_to_check): + """Extracts the relative mod path of the file to import from + + Check if a file is within the passed in path and if so, returns the + relative mod path from the one passed in. + + If the filename is no in path_to_check, returns None + + Note this function will look for both abs and realpath of the file, + this allows to find the relative base path even if the file is a + symlink of a file in the passed in path + + Examples: + _get_relative_base_path("/a/b/c/d.py", "/a/b") -> ["c","d"] + _get_relative_base_path("/a/b/c/d.py", "/dev") -> None + """ + importable_path = None + path_to_check = os.path.normcase(path_to_check) + abs_filename = os.path.abspath(filename) + if os.path.normcase(abs_filename).startswith(path_to_check): + importable_path = abs_filename + + real_filename = os.path.realpath(filename) + if os.path.normcase(real_filename).startswith(path_to_check): + importable_path = real_filename + + if importable_path: + base_path = os.path.splitext(importable_path)[0] + relative_base_path = base_path[len(path_to_check) :] + return [pkg for pkg in relative_base_path.split(os.sep) if pkg] + + return None + + +def modpath_from_file_with_callback(filename, extrapath=None, is_package_cb=None): + filename = os.path.expanduser(_path_from_filename(filename)) + + if extrapath is not None: + for path_ in itertools.chain(map(_canonicalize_path, extrapath), extrapath): + path = os.path.abspath(path_) + if not path: + continue + submodpath = _get_relative_base_path(filename, path) + if not submodpath: + continue + if is_package_cb(path, submodpath[:-1]): + return extrapath[path_].split(".") + submodpath + + for path in itertools.chain(map(_canonicalize_path, sys.path), sys.path): + path = _cache_normalize_path(path) + if not path: + continue + modpath = _get_relative_base_path(filename, path) + if not modpath: + continue + if is_package_cb(path, modpath[:-1]): + return modpath + + raise ImportError( + "Unable to find module for %s in %s" % (filename, ", \n".join(sys.path)) + ) + + +def modpath_from_file(filename, extrapath=None): + """given a file path return the corresponding split module's name + (i.e name of a module or package split on '.') + + :type filename: str + :param filename: file's path for which we want the module's name + + :type extrapath: dict + :param extrapath: + optional extra search path, with path as key and package name for the path + as value. This is usually useful to handle package split in multiple + directories using __path__ trick. + + + :raise ImportError: + if the corresponding module's name has not been found + + :rtype: list(str) + :return: the corresponding split module's name + """ + return modpath_from_file_with_callback(filename, extrapath, check_modpath_has_init) + + +def file_from_modpath(modpath, path=None, context_file=None): + return file_info_from_modpath(modpath, path, context_file).location + + +def file_info_from_modpath(modpath, path=None, context_file=None): + """given a mod path (i.e. split module / package name), return the + corresponding file, giving priority to source file over precompiled + file if it exists + + :type modpath: list or tuple + :param modpath: + split module's name (i.e name of a module or package split + on '.') + (this means explicit relative imports that start with dots have + empty strings in this list!) + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type context_file: str or None + :param context_file: + context file to consider, necessary if the identifier has been + introduced using a relative import unresolvable in the actual + context (i.e. modutils) + + :raise ImportError: if there is no such module in the directory + + :rtype: (str or None, import type) + :return: + the path to the module's file or None if it's an integrated + builtin module such as 'sys' + """ + if context_file is not None: + context = os.path.dirname(context_file) + else: + context = context_file + if modpath[0] == "xml": + # handle _xmlplus + try: + return _spec_from_modpath(["_xmlplus"] + modpath[1:], path, context) + except ImportError: + return _spec_from_modpath(modpath, path, context) + elif modpath == ["os", "path"]: + # FIXME: currently ignoring search_path... + return spec.ModuleSpec( + name="os.path", location=os.path.__file__, module_type=imp.PY_SOURCE + ) + return _spec_from_modpath(modpath, path, context) + + +def get_module_part(dotted_name, context_file=None): + """given a dotted name return the module part of the name : + + >>> get_module_part('astroid.as_string.dump') + 'astroid.as_string' + + :type dotted_name: str + :param dotted_name: full name of the identifier we are interested in + + :type context_file: str or None + :param context_file: + context file to consider, necessary if the identifier has been + introduced using a relative import unresolvable in the actual + context (i.e. modutils) + + + :raise ImportError: if there is no such module in the directory + + :rtype: str or None + :return: + the module part of the name or None if we have not been able at + all to import the given name + + XXX: deprecated, since it doesn't handle package precedence over module + (see #10066) + """ + # os.path trick + if dotted_name.startswith("os.path"): + return "os.path" + parts = dotted_name.split(".") + if context_file is not None: + # first check for builtin module which won't be considered latter + # in that case (path != None) + if parts[0] in BUILTIN_MODULES: + if len(parts) > 2: + raise ImportError(dotted_name) + return parts[0] + # don't use += or insert, we want a new list to be created ! + path = None + starti = 0 + if parts[0] == "": + assert ( + context_file is not None + ), "explicit relative import, but no context_file?" + path = [] # prevent resolving the import non-relatively + starti = 1 + while parts[starti] == "": # for all further dots: change context + starti += 1 + context_file = os.path.dirname(context_file) + for i in range(starti, len(parts)): + try: + file_from_modpath( + parts[starti : i + 1], path=path, context_file=context_file + ) + except ImportError: + if i < max(1, len(parts) - 2): + raise + return ".".join(parts[:i]) + return dotted_name + + +def get_module_files(src_directory, blacklist, list_all=False): + """given a package directory return a list of all available python + module's files in the package and its subpackages + + :type src_directory: str + :param src_directory: + path of the directory corresponding to the package + + :type blacklist: list or tuple + :param blacklist: iterable + list of files or directories to ignore. + + :type list_all: bool + :param list_all: + get files from all paths, including ones without __init__.py + + :rtype: list + :return: + the list of all available python module's files in the package and + its subpackages + """ + files = [] + for directory, dirnames, filenames in os.walk(src_directory): + if directory in blacklist: + continue + _handle_blacklist(blacklist, dirnames, filenames) + # check for __init__.py + if not list_all and "__init__.py" not in filenames: + dirnames[:] = () + continue + for filename in filenames: + if _is_python_file(filename): + src = os.path.join(directory, filename) + files.append(src) + return files + + +def get_source_file(filename, include_no_ext=False): + """given a python module's file name return the matching source file + name (the filename will be returned identically if it's already an + absolute path to a python source file...) + + :type filename: str + :param filename: python module's file name + + + :raise NoSourceFile: if no source file exists on the file system + + :rtype: str + :return: the absolute path of the source file if it exists + """ + filename = os.path.abspath(_path_from_filename(filename)) + base, orig_ext = os.path.splitext(filename) + for ext in PY_SOURCE_EXTS: + source_path = "%s.%s" % (base, ext) + if os.path.exists(source_path): + return source_path + if include_no_ext and not orig_ext and os.path.exists(base): + return base + raise NoSourceFile(filename) + + +def is_python_source(filename): + """ + rtype: bool + return: True if the filename is a python source file + """ + return os.path.splitext(filename)[1][1:] in PY_SOURCE_EXTS + + +def is_standard_module(modname, std_path=None): + """try to guess if a module is a standard python module (by default, + see `std_path` parameter's description) + + :type modname: str + :param modname: name of the module we are interested in + + :type std_path: list(str) or tuple(str) + :param std_path: list of path considered has standard + + + :rtype: bool + :return: + true if the module: + - is located on the path listed in one of the directory in `std_path` + - is a built-in module + """ + modname = modname.split(".")[0] + try: + filename = file_from_modpath([modname]) + except ImportError: + # import failed, i'm probably not so wrong by supposing it's + # not standard... + return False + # modules which are not living in a file are considered standard + # (sys and __builtin__ for instance) + if filename is None: + # we assume there are no namespaces in stdlib + return not util.is_namespace(modname) + filename = _normalize_path(filename) + if filename.startswith(_cache_normalize_path(EXT_LIB_DIR)): + return False + if std_path is None: + std_path = STD_LIB_DIRS + for path in std_path: + if filename.startswith(_cache_normalize_path(path)): + return True + return False + + +def is_relative(modname, from_file): + """return true if the given module name is relative to the given + file name + + :type modname: str + :param modname: name of the module we are interested in + + :type from_file: str + :param from_file: + path of the module from which modname has been imported + + :rtype: bool + :return: + true if the module has been imported relatively to `from_file` + """ + if not os.path.isdir(from_file): + from_file = os.path.dirname(from_file) + if from_file in sys.path: + return False + try: + stream, _, _ = imp.find_module(modname.split(".")[0], [from_file]) + + # Close the stream to avoid ResourceWarnings. + if stream: + stream.close() + return True + except ImportError: + return False + + +# internal only functions ##################################################### + + +def _spec_from_modpath(modpath, path=None, context=None): + """given a mod path (i.e. split module / package name), return the + corresponding spec + + this function is used internally, see `file_from_modpath`'s + documentation for more information + """ + assert modpath + location = None + if context is not None: + try: + found_spec = spec.find_spec(modpath, [context]) + location = found_spec.location + except ImportError: + found_spec = spec.find_spec(modpath, path) + location = found_spec.location + else: + found_spec = spec.find_spec(modpath, path) + if found_spec.type == spec.ModuleType.PY_COMPILED: + try: + location = get_source_file(found_spec.location) + return found_spec._replace( + location=location, type=spec.ModuleType.PY_SOURCE + ) + except NoSourceFile: + return found_spec._replace(location=location) + elif found_spec.type == spec.ModuleType.C_BUILTIN: + # integrated builtin module + return found_spec._replace(location=None) + elif found_spec.type == spec.ModuleType.PKG_DIRECTORY: + location = _has_init(found_spec.location) + return found_spec._replace(location=location, type=spec.ModuleType.PY_SOURCE) + return found_spec + + +def _is_python_file(filename): + """return true if the given filename should be considered as a python file + + .pyc and .pyo are ignored + """ + for ext in (".py", ".so", ".pyd", ".pyw"): + if filename.endswith(ext): + return True + return False + + +def _has_init(directory): + """if the given directory has a valid __init__ file, return its path, + else return None + """ + mod_or_pack = os.path.join(directory, "__init__") + for ext in PY_SOURCE_EXTS + ("pyc", "pyo"): + if os.path.exists(mod_or_pack + "." + ext): + return mod_or_pack + "." + ext + return None + + +def is_namespace(specobj): + return specobj.type == spec.ModuleType.PY_NAMESPACE + + +def is_directory(specobj): + return specobj.type == spec.ModuleType.PKG_DIRECTORY diff --git a/venv/lib/python3.7/site-packages/astroid/node_classes.py b/venv/lib/python3.7/site-packages/astroid/node_classes.py new file mode 100644 index 0000000..204d802 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/node_classes.py @@ -0,0 +1,4697 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Dave Baum +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 brendanator +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +# pylint: disable=too-many-lines; https://github.com/PyCQA/astroid/issues/465 + +"""Module for some node classes. More nodes in scoped_nodes.py +""" + +import abc +import builtins as builtins_mod +import itertools +import pprint +from functools import lru_cache +from functools import singledispatch as _singledispatch + +from astroid import as_string +from astroid import bases +from astroid import context as contextmod +from astroid import decorators +from astroid import exceptions +from astroid import manager +from astroid import mixins +from astroid import util + + +BUILTINS = builtins_mod.__name__ +MANAGER = manager.AstroidManager() + + +@decorators.raise_if_nothing_inferred +def unpack_infer(stmt, context=None): + """recursively generate nodes inferred by the given statement. + If the inferred value is a list or a tuple, recurse on the elements + """ + if isinstance(stmt, (List, Tuple)): + for elt in stmt.elts: + if elt is util.Uninferable: + yield elt + continue + yield from unpack_infer(elt, context) + return dict(node=stmt, context=context) + # if inferred is a final node, return it and stop + inferred = next(stmt.infer(context)) + if inferred is stmt: + yield inferred + return dict(node=stmt, context=context) + # else, infer recursively, except Uninferable object that should be returned as is + for inferred in stmt.infer(context): + if inferred is util.Uninferable: + yield inferred + else: + yield from unpack_infer(inferred, context) + + return dict(node=stmt, context=context) + + +def are_exclusive( + stmt1, stmt2, exceptions=None +): # pylint: disable=redefined-outer-name + """return true if the two given statements are mutually exclusive + + `exceptions` may be a list of exception names. If specified, discard If + branches and check one of the statement is in an exception handler catching + one of the given exceptions. + + algorithm : + 1) index stmt1's parents + 2) climb among stmt2's parents until we find a common parent + 3) if the common parent is a If or TryExcept statement, look if nodes are + in exclusive branches + """ + # index stmt1's parents + stmt1_parents = {} + children = {} + node = stmt1.parent + previous = stmt1 + while node: + stmt1_parents[node] = 1 + children[node] = previous + previous = node + node = node.parent + # climb among stmt2's parents until we find a common parent + node = stmt2.parent + previous = stmt2 + while node: + if node in stmt1_parents: + # if the common parent is a If or TryExcept statement, look if + # nodes are in exclusive branches + if isinstance(node, If) and exceptions is None: + if ( + node.locate_child(previous)[1] + is not node.locate_child(children[node])[1] + ): + return True + elif isinstance(node, TryExcept): + c2attr, c2node = node.locate_child(previous) + c1attr, c1node = node.locate_child(children[node]) + if c1node is not c2node: + first_in_body_caught_by_handlers = ( + c2attr == "handlers" + and c1attr == "body" + and previous.catch(exceptions) + ) + second_in_body_caught_by_handlers = ( + c2attr == "body" + and c1attr == "handlers" + and children[node].catch(exceptions) + ) + first_in_else_other_in_handlers = ( + c2attr == "handlers" and c1attr == "orelse" + ) + second_in_else_other_in_handlers = ( + c2attr == "orelse" and c1attr == "handlers" + ) + if any( + ( + first_in_body_caught_by_handlers, + second_in_body_caught_by_handlers, + first_in_else_other_in_handlers, + second_in_else_other_in_handlers, + ) + ): + return True + elif c2attr == "handlers" and c1attr == "handlers": + return previous is not children[node] + return False + previous = node + node = node.parent + return False + + +# getitem() helpers. + +_SLICE_SENTINEL = object() + + +def _slice_value(index, context=None): + """Get the value of the given slice index.""" + + if isinstance(index, Const): + if isinstance(index.value, (int, type(None))): + return index.value + elif index is None: + return None + else: + # Try to infer what the index actually is. + # Since we can't return all the possible values, + # we'll stop at the first possible value. + try: + inferred = next(index.infer(context=context)) + except exceptions.InferenceError: + pass + else: + if isinstance(inferred, Const): + if isinstance(inferred.value, (int, type(None))): + return inferred.value + + # Use a sentinel, because None can be a valid + # value that this function can return, + # as it is the case for unspecified bounds. + return _SLICE_SENTINEL + + +def _infer_slice(node, context=None): + lower = _slice_value(node.lower, context) + upper = _slice_value(node.upper, context) + step = _slice_value(node.step, context) + if all(elem is not _SLICE_SENTINEL for elem in (lower, upper, step)): + return slice(lower, upper, step) + + raise exceptions.AstroidTypeError( + message="Could not infer slice used in subscript", + node=node, + index=node.parent, + context=context, + ) + + +def _container_getitem(instance, elts, index, context=None): + """Get a slice or an item, using the given *index*, for the given sequence.""" + try: + if isinstance(index, Slice): + index_slice = _infer_slice(index, context=context) + new_cls = instance.__class__() + new_cls.elts = elts[index_slice] + new_cls.parent = instance.parent + return new_cls + if isinstance(index, Const): + return elts[index.value] + except IndexError as exc: + raise exceptions.AstroidIndexError( + message="Index {index!s} out of range", + node=instance, + index=index, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.AstroidTypeError( + message="Type error {error!r}", node=instance, index=index, context=context + ) from exc + + raise exceptions.AstroidTypeError("Could not use %s as subscript index" % index) + + +OP_PRECEDENCE = { + op: precedence + for precedence, ops in enumerate( + [ + ["Lambda"], # lambda x: x + 1 + ["IfExp"], # 1 if True else 2 + ["or"], + ["and"], + ["not"], + ["Compare"], # in, not in, is, is not, <, <=, >, >=, !=, == + ["|"], + ["^"], + ["&"], + ["<<", ">>"], + ["+", "-"], + ["*", "@", "/", "//", "%"], + ["UnaryOp"], # +, -, ~ + ["**"], + ["Await"], + ] + ) + for op in ops +} + + +class NodeNG: + """ A node of the new Abstract Syntax Tree (AST). + + This is the base class for all Astroid node classes. + """ + + is_statement = False + """Whether this node indicates a statement. + + :type: bool + """ + optional_assign = False # True for For (and for Comprehension if py <3.0) + """Whether this node optionally assigns a variable. + + This is for loop assignments because loop won't necessarily perform an + assignment if the loop has no iterations. + This is also the case from comprehensions in Python 2. + + :type: bool + """ + is_function = False # True for FunctionDef nodes + """Whether this node indicates a function. + + :type: bool + """ + is_lambda = False + # Attributes below are set by the builder module or by raw factories + lineno = None + """The line that this node appears on in the source code. + + :type: int or None + """ + col_offset = None + """The column that this node appears on in the source code. + + :type: int or None + """ + parent = None + """The parent node in the syntax tree. + + :type: NodeNG or None + """ + _astroid_fields = () + """Node attributes that contain child nodes. + + This is redefined in most concrete classes. + + :type: tuple(str) + """ + _other_fields = () + """Node attributes that do not contain child nodes. + + :type: tuple(str) + """ + _other_other_fields = () + """Attributes that contain AST-dependent fields. + + :type: tuple(str) + """ + # instance specific inference function infer(node, context) + _explicit_inference = None + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.lineno = lineno + self.col_offset = col_offset + self.parent = parent + + def infer(self, context=None, **kwargs): + """Get a generator of the inferred values. + + This is the main entry point to the inference system. + + .. seealso:: :ref:`inference` + + If the instance has some explicit inference function set, it will be + called instead of the default interface. + + :returns: The inferred values. + :rtype: iterable + """ + if context is not None: + context = context.extra_context.get(self, context) + if self._explicit_inference is not None: + # explicit_inference is not bound, give it self explicitly + try: + # pylint: disable=not-callable + return self._explicit_inference(self, context, **kwargs) + except exceptions.UseInferenceDefault: + pass + + if not context: + return self._infer(context, **kwargs) + + key = (self, context.lookupname, context.callcontext, context.boundnode) + if key in context.inferred: + return iter(context.inferred[key]) + + gen = context.cache_generator(key, self._infer(context, **kwargs)) + return util.limit_inference(gen, MANAGER.max_inferable_values) + + def _repr_name(self): + """Get a name for nice representation. + + This is either :attr:`name`, :attr:`attrname`, or the empty string. + + :returns: The nice name. + :rtype: str + """ + names = {"name", "attrname"} + if all(name not in self._astroid_fields for name in names): + return getattr(self, "name", getattr(self, "attrname", "")) + return "" + + def __str__(self): + rname = self._repr_name() + cname = type(self).__name__ + if rname: + string = "%(cname)s.%(rname)s(%(fields)s)" + alignment = len(cname) + len(rname) + 2 + else: + string = "%(cname)s(%(fields)s)" + alignment = len(cname) + 1 + result = [] + for field in self._other_fields + self._astroid_fields: + value = getattr(self, field) + width = 80 - len(field) - alignment + lines = pprint.pformat(value, indent=2, width=width).splitlines(True) + + inner = [lines[0]] + for line in lines[1:]: + inner.append(" " * alignment + line) + result.append("%s=%s" % (field, "".join(inner))) + + return string % { + "cname": cname, + "rname": rname, + "fields": (",\n" + " " * alignment).join(result), + } + + def __repr__(self): + rname = self._repr_name() + if rname: + string = "<%(cname)s.%(rname)s l.%(lineno)s at 0x%(id)x>" + else: + string = "<%(cname)s l.%(lineno)s at 0x%(id)x>" + return string % { + "cname": type(self).__name__, + "rname": rname, + "lineno": self.fromlineno, + "id": id(self), + } + + def accept(self, visitor): + """Visit this node using the given visitor.""" + func = getattr(visitor, "visit_" + self.__class__.__name__.lower()) + return func(self) + + def get_children(self): + """Get the child nodes below this node. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for field in self._astroid_fields: + attr = getattr(self, field) + if attr is None: + continue + if isinstance(attr, (list, tuple)): + yield from attr + else: + yield attr + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child, or None if no children exist. + :rtype: NodeNG or None + """ + for field in self._astroid_fields[::-1]: + attr = getattr(self, field) + if not attr: # None or empty listy / tuple + continue + if isinstance(attr, (list, tuple)): + return attr[-1] + + return attr + return None + + def parent_of(self, node): + """Check if this node is the parent of the given node. + + :param node: The node to check if it is the child. + :type node: NodeNG + + :returns: True if this node is the parent of the given node, + False otherwise. + :rtype: bool + """ + parent = node.parent + while parent is not None: + if self is parent: + return True + parent = parent.parent + return False + + def statement(self): + """The first parent node, including self, marked as statement node. + + :returns: The first parent statement. + :rtype: NodeNG + """ + if self.is_statement: + return self + return self.parent.statement() + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self.parent.frame() + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + return self.parent.scope() + + def root(self): + """Return the root node of the syntax tree. + + :returns: The root node. + :rtype: Module + """ + if self.parent: + return self.parent.root() + return self + + def child_sequence(self, child): + """Search for the sequence that contains this child. + + :param child: The child node to search sequences for. + :type child: NodeNG + + :returns: The sequence containing the given child node. + :rtype: iterable(NodeNG) + + :raises AstroidError: If no sequence could be found that contains + the given child. + """ + for field in self._astroid_fields: + node_or_sequence = getattr(self, field) + if node_or_sequence is child: + return [node_or_sequence] + # /!\ compiler.ast Nodes have an __iter__ walking over child nodes + if ( + isinstance(node_or_sequence, (tuple, list)) + and child in node_or_sequence + ): + return node_or_sequence + + msg = "Could not find %s in %s's children" + raise exceptions.AstroidError(msg % (repr(child), repr(self))) + + def locate_child(self, child): + """Find the field of this node that contains the given child. + + :param child: The child node to search fields for. + :type child: NodeNG + + :returns: A tuple of the name of the field that contains the child, + and the sequence or node that contains the child node. + :rtype: tuple(str, iterable(NodeNG) or NodeNG) + + :raises AstroidError: If no field could be found that contains + the given child. + """ + for field in self._astroid_fields: + node_or_sequence = getattr(self, field) + # /!\ compiler.ast Nodes have an __iter__ walking over child nodes + if child is node_or_sequence: + return field, child + if ( + isinstance(node_or_sequence, (tuple, list)) + and child in node_or_sequence + ): + return field, node_or_sequence + msg = "Could not find %s in %s's children" + raise exceptions.AstroidError(msg % (repr(child), repr(self))) + + # FIXME : should we merge child_sequence and locate_child ? locate_child + # is only used in are_exclusive, child_sequence one time in pylint. + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + return self.parent.next_sibling() + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + return self.parent.previous_sibling() + + def nearest(self, nodes): + """Get the node closest to this one from the given list of nodes. + + :param nodes: The list of nodes to search. All of these nodes must + belong to the same module as this one. The list should be + sorted by the line number of the nodes, smallest first. + :type nodes: iterable(NodeNG) + + :returns: The node closest to this one in the source code, + or None if one could not be found. + :rtype: NodeNG or None + """ + myroot = self.root() + mylineno = self.fromlineno + nearest = None, 0 + for node in nodes: + assert node.root() is myroot, ( + "nodes %s and %s are not from the same module" % (self, node) + ) + lineno = node.fromlineno + if node.fromlineno > mylineno: + break + if lineno > nearest[1]: + nearest = node, lineno + # FIXME: raise an exception if nearest is None ? + return nearest[0] + + # these are lazy because they're relatively expensive to compute for every + # single node, and they rarely get looked at + + @decorators.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + if self.lineno is None: + return self._fixed_source_line() + + return self.lineno + + @decorators.cachedproperty + def tolineno(self): + """The last line that this node appears on in the source code. + + :type: int or None + """ + if not self._astroid_fields: + # can't have children + lastchild = None + else: + lastchild = self.last_child() + if lastchild is None: + return self.fromlineno + + return lastchild.tolineno + + def _fixed_source_line(self): + """Attempt to find the line that this node appears on. + + We need this method since not all nodes have :attr:`lineno` set. + + :returns: The line number of this node, + or None if this could not be determined. + :rtype: int or None + """ + line = self.lineno + _node = self + try: + while line is None: + _node = next(_node.get_children()) + line = _node.lineno + except StopIteration: + _node = self.parent + while _node and line is None: + line = _node.lineno + _node = _node.parent + return line + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int or None) + """ + return lineno, self.tolineno + + def set_local(self, name, stmt): + """Define that the given name is declared in the given statement node. + + This definition is stored on the parent scope node. + + .. seealso:: :meth:`scope` + + :param name: The name that is being defined. + :type name: str + + :param stmt: The statement that defines the given name. + :type stmt: NodeNG + """ + self.parent.set_local(name, stmt) + + def nodes_of_class(self, klass, skip_klass=None): + """Get the nodes (including this one or below) of the given type. + + :param klass: The type of node to search for. + :type klass: builtins.type + + :param skip_klass: A type of node to ignore. This is useful to ignore + subclasses of :attr:`klass`. + :type skip_klass: builtins.type + + :returns: The node of the given type. + :rtype: iterable(NodeNG) + """ + if isinstance(self, klass): + yield self + + if skip_klass is None: + for child_node in self.get_children(): + yield from child_node.nodes_of_class(klass, skip_klass) + + return + + for child_node in self.get_children(): + if isinstance(child_node, skip_klass): + continue + yield from child_node.nodes_of_class(klass, skip_klass) + + @decorators.cached + def _get_assign_nodes(self): + return [] + + def _get_name_nodes(self): + for child_node in self.get_children(): + yield from child_node._get_name_nodes() + + def _get_return_nodes_skip_functions(self): + yield from () + + def _get_yield_nodes_skip_lambdas(self): + yield from () + + def _infer_name(self, frame, name): + # overridden for ImportFrom, Import, Global, TryExcept and Arguments + pass + + def _infer(self, context=None): + """we don't know how to resolve a statement by default""" + # this method is overridden by most concrete classes + raise exceptions.InferenceError( + "No inference function for {node!r}.", node=self, context=context + ) + + def inferred(self): + """Get a list of the inferred values. + + .. seealso:: :ref:`inference` + + :returns: The inferred values. + :rtype: list + """ + return list(self.infer()) + + def instantiate_class(self): + """Instantiate an instance of the defined class. + + .. note:: + + On anything other than a :class:`ClassDef` this will return self. + + :returns: An instance of the defined class. + :rtype: object + """ + return self + + def has_base(self, node): + """Check if this node inherits from the given type. + + :param node: The node defining the base to look for. + Usually this is a :class:`Name` node. + :type node: NodeNG + """ + return False + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + :rtype: bool + """ + return False + + def eq(self, value): + return False + + def as_string(self): + """Get the source code that this node represents. + + :returns: The source code. + :rtype: str + """ + return as_string.to_code(self) + + def repr_tree( + self, + ids=False, + include_linenos=False, + ast_state=False, + indent=" ", + max_depth=0, + max_width=80, + ): + """Get a string representation of the AST from this node. + + :param ids: If true, includes the ids with the node type names. + :type ids: bool + + :param include_linenos: If true, includes the line numbers and + column offsets. + :type include_linenos: bool + + :param ast_state: If true, includes information derived from + the whole AST like local and global variables. + :type ast_state: bool + + :param indent: A string to use to indent the output string. + :type indent: str + + :param max_depth: If set to a positive integer, won't return + nodes deeper than max_depth in the string. + :type max_depth: int + + :param max_width: Attempt to format the output string to stay + within this number of characters, but can exceed it under some + circumstances. Only positive integer values are valid, the default is 80. + :type max_width: int + + :returns: The string representation of the AST. + :rtype: str + """ + # pylint: disable=too-many-statements + @_singledispatch + def _repr_tree(node, result, done, cur_indent="", depth=1): + """Outputs a representation of a non-tuple/list, non-node that's + contained within an AST, including strings. + """ + lines = pprint.pformat( + node, width=max(max_width - len(cur_indent), 1) + ).splitlines(True) + result.append(lines[0]) + result.extend([cur_indent + line for line in lines[1:]]) + return len(lines) != 1 + + # pylint: disable=unused-variable; doesn't understand singledispatch + @_repr_tree.register(tuple) + @_repr_tree.register(list) + def _repr_seq(node, result, done, cur_indent="", depth=1): + """Outputs a representation of a sequence that's contained within an AST.""" + cur_indent += indent + result.append("[") + if not node: + broken = False + elif len(node) == 1: + broken = _repr_tree(node[0], result, done, cur_indent, depth) + elif len(node) == 2: + broken = _repr_tree(node[0], result, done, cur_indent, depth) + if not broken: + result.append(", ") + else: + result.append(",\n") + result.append(cur_indent) + broken = _repr_tree(node[1], result, done, cur_indent, depth) or broken + else: + result.append("\n") + result.append(cur_indent) + for child in node[:-1]: + _repr_tree(child, result, done, cur_indent, depth) + result.append(",\n") + result.append(cur_indent) + _repr_tree(node[-1], result, done, cur_indent, depth) + broken = True + result.append("]") + return broken + + # pylint: disable=unused-variable; doesn't understand singledispatch + @_repr_tree.register(NodeNG) + def _repr_node(node, result, done, cur_indent="", depth=1): + """Outputs a strings representation of an astroid node.""" + if node in done: + result.append( + indent + + " max_depth: + result.append("...") + return False + depth += 1 + cur_indent += indent + if ids: + result.append("%s<0x%x>(\n" % (type(node).__name__, id(node))) + else: + result.append("%s(" % type(node).__name__) + fields = [] + if include_linenos: + fields.extend(("lineno", "col_offset")) + fields.extend(node._other_fields) + fields.extend(node._astroid_fields) + if ast_state: + fields.extend(node._other_other_fields) + if not fields: + broken = False + elif len(fields) == 1: + result.append("%s=" % fields[0]) + broken = _repr_tree( + getattr(node, fields[0]), result, done, cur_indent, depth + ) + else: + result.append("\n") + result.append(cur_indent) + for field in fields[:-1]: + result.append("%s=" % field) + _repr_tree(getattr(node, field), result, done, cur_indent, depth) + result.append(",\n") + result.append(cur_indent) + result.append("%s=" % fields[-1]) + _repr_tree(getattr(node, fields[-1]), result, done, cur_indent, depth) + broken = True + result.append(")") + return broken + + result = [] + _repr_tree(self, result, set()) + return "".join(result) + + def bool_value(self): + """Determine the boolean value of this node. + + The boolean value of a node can have three + possible values: + + * False: For instance, empty data structures, + False, empty strings, instances which return + explicitly False from the __nonzero__ / __bool__ + method. + * True: Most of constructs are True by default: + classes, functions, modules etc + * Uninferable: The inference engine is uncertain of the + node's value. + + :returns: The boolean value of this node. + :rtype: bool or Uninferable + """ + return util.Uninferable + + def op_precedence(self): + # Look up by class name or default to highest precedence + return OP_PRECEDENCE.get(self.__class__.__name__, len(OP_PRECEDENCE)) + + def op_left_associative(self): + # Everything is left associative except `**` and IfExp + return True + + +class Statement(NodeNG): + """Statement node adding a few attributes""" + + is_statement = True + """Whether this node indicates a statement. + + :type: bool + """ + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + stmts = self.parent.child_sequence(self) + index = stmts.index(self) + try: + return stmts[index + 1] + except IndexError: + pass + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + stmts = self.parent.child_sequence(self) + index = stmts.index(self) + if index >= 1: + return stmts[index - 1] + return None + + +class _BaseContainer( + mixins.ParentAssignTypeMixin, NodeNG, bases.Instance, metaclass=abc.ABCMeta +): + """Base class for Set, FrozenSet, Tuple and List.""" + + _astroid_fields = ("elts",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.elts = [] + """The elements in the node. + + :type: list(NodeNG) + """ + + super(_BaseContainer, self).__init__(lineno, col_offset, parent) + + def postinit(self, elts): + """Do some setup after initialisation. + + :param elts: The list of elements the that node contains. + :type elts: list(NodeNG) + """ + self.elts = elts + + @classmethod + def from_constants(cls, elts=None): + """Create a node of this type from the given list of elements. + + :param elts: The list of elements that the node should contain. + :type elts: list(NodeNG) + + :returns: A new node containing the given elements. + :rtype: NodeNG + """ + node = cls() + if elts is None: + node.elts = [] + else: + node.elts = [const_factory(e) for e in elts] + return node + + def itered(self): + """An iterator over the elements this node contains. + + :returns: The contents of this node. + :rtype: iterable(NodeNG) + """ + return self.elts + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool or Uninferable + """ + return bool(self.elts) + + @abc.abstractmethod + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + + def get_children(self): + yield from self.elts + + +class LookupMixIn: + """Mixin to look up a name in the right scope.""" + + @lru_cache(maxsize=None) + def lookup(self, name): + """Lookup where the given variable is assigned. + + The lookup starts from self's scope. If self is not a frame itself + and the name is found in the inner frame locals, statements will be + filtered to remove ignorable statements according to self's location. + + :param name: The name of the variable to find assignments for. + :type name: str + + :returns: The scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + return self.scope().scope_lookup(self, name) + + def ilookup(self, name): + """Lookup the inferred values of the given variable. + + :param name: The variable name to find values for. + :type name: str + + :returns: The inferred values of the statements returned from + :meth:`lookup`. + :rtype: iterable + """ + frame, stmts = self.lookup(name) + context = contextmod.InferenceContext() + return bases._infer_stmts(stmts, context, frame) + + def _get_filtered_node_statements(self, nodes): + statements = [(node, node.statement()) for node in nodes] + # Next we check if we have ExceptHandlers that are parent + # of the underlying variable, in which case the last one survives + if len(statements) > 1 and all( + isinstance(stmt, ExceptHandler) for _, stmt in statements + ): + statements = [ + (node, stmt) for node, stmt in statements if stmt.parent_of(self) + ] + return statements + + def _filter_stmts(self, stmts, frame, offset): + """Filter the given list of statements to remove ignorable statements. + + If self is not a frame itself and the name is found in the inner + frame locals, statements will be filtered to remove ignorable + statements according to self's location. + + :param stmts: The statements to filter. + :type stmts: list(NodeNG) + + :param frame: The frame that all of the given statements belong to. + :type frame: NodeNG + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: The filtered statements. + :rtype: list(NodeNG) + """ + # if offset == -1, my actual frame is not the inner frame but its parent + # + # class A(B): pass + # + # we need this to resolve B correctly + if offset == -1: + myframe = self.frame().parent.frame() + else: + myframe = self.frame() + # If the frame of this node is the same as the statement + # of this node, then the node is part of a class or + # a function definition and the frame of this node should be the + # the upper frame, not the frame of the definition. + # For more information why this is important, + # see Pylint issue #295. + # For example, for 'b', the statement is the same + # as the frame / scope: + # + # def test(b=1): + # ... + + if self.statement() is myframe and myframe.parent: + myframe = myframe.parent.frame() + mystmt = self.statement() + # line filtering if we are in the same frame + # + # take care node may be missing lineno information (this is the case for + # nodes inserted for living objects) + if myframe is frame and mystmt.fromlineno is not None: + assert mystmt.fromlineno is not None, mystmt + mylineno = mystmt.fromlineno + offset + else: + # disabling lineno filtering + mylineno = 0 + + _stmts = [] + _stmt_parents = [] + statements = self._get_filtered_node_statements(stmts) + + for node, stmt in statements: + # line filtering is on and we have reached our location, break + if stmt.fromlineno > mylineno > 0: + break + # Ignore decorators with the same name as the + # decorated function + # Fixes issue #375 + if mystmt is stmt and is_from_decorator(self): + continue + assert hasattr(node, "assign_type"), ( + node, + node.scope(), + node.scope().locals, + ) + assign_type = node.assign_type() + if node.has_base(self): + break + + _stmts, done = assign_type._get_filtered_stmts(self, node, _stmts, mystmt) + if done: + break + + optional_assign = assign_type.optional_assign + if optional_assign and assign_type.parent_of(self): + # we are inside a loop, loop var assignment is hiding previous + # assignment + _stmts = [node] + _stmt_parents = [stmt.parent] + continue + + # XXX comment various branches below!!! + try: + pindex = _stmt_parents.index(stmt.parent) + except ValueError: + pass + else: + # we got a parent index, this means the currently visited node + # is at the same block level as a previously visited node + if _stmts[pindex].assign_type().parent_of(assign_type): + # both statements are not at the same block level + continue + # if currently visited node is following previously considered + # assignment and both are not exclusive, we can drop the + # previous one. For instance in the following code :: + # + # if a: + # x = 1 + # else: + # x = 2 + # print x + # + # we can't remove neither x = 1 nor x = 2 when looking for 'x' + # of 'print x'; while in the following :: + # + # x = 1 + # x = 2 + # print x + # + # we can remove x = 1 when we see x = 2 + # + # moreover, on loop assignment types, assignment won't + # necessarily be done if the loop has no iteration, so we don't + # want to clear previous assignments if any (hence the test on + # optional_assign) + if not (optional_assign or are_exclusive(_stmts[pindex], node)): + if ( + # In case of partial function node, if the statement is different + # from the origin function then it can be deleted otherwise it should + # remain to be able to correctly infer the call to origin function. + not node.is_function + or node.qname() != "PartialFunction" + or node.name != _stmts[pindex].name + ): + del _stmt_parents[pindex] + del _stmts[pindex] + if isinstance(node, AssignName): + if not optional_assign and stmt.parent is mystmt.parent: + _stmts = [] + _stmt_parents = [] + elif isinstance(node, DelName): + _stmts = [] + _stmt_parents = [] + continue + if not are_exclusive(self, node): + _stmts.append(node) + _stmt_parents.append(stmt.parent) + return _stmts + + +# Name classes + + +class AssignName( + mixins.NoChildrenMixin, LookupMixIn, mixins.ParentAssignTypeMixin, NodeNG +): + """Variation of :class:`ast.Assign` representing assignment to a name. + + An :class:`AssignName` is the name of something that is assigned to. + This includes variables defined in a function signature or in a loop. + + >>> node = astroid.extract_node('variable = range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'variable' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that is assigned to. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that is assigned to. + + :type: str or None + """ + + super(AssignName, self).__init__(lineno, col_offset, parent) + + +class DelName( + mixins.NoChildrenMixin, LookupMixIn, mixins.ParentAssignTypeMixin, NodeNG +): + """Variation of :class:`ast.Delete` representing deletion of a name. + + A :class:`DelName` is the name of something that is deleted. + + >>> node = astroid.extract_node("del variable #@") + >>> list(node.get_children()) + [] + >>> list(node.get_children())[0].as_string() + 'variable' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that is being deleted. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that is being deleted. + + :type: str or None + """ + + super(DelName, self).__init__(lineno, col_offset, parent) + + +class Name(mixins.NoChildrenMixin, LookupMixIn, NodeNG): + """Class representing an :class:`ast.Name` node. + + A :class:`Name` node is something that is named, but not covered by + :class:`AssignName` or :class:`DelName`. + + >>> node = astroid.extract_node('range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'range' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that this node refers to. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that this node refers to. + + :type: str or None + """ + + super(Name, self).__init__(lineno, col_offset, parent) + + def _get_name_nodes(self): + yield self + + for child_node in self.get_children(): + yield from child_node._get_name_nodes() + + +class Arguments(mixins.AssignTypeMixin, NodeNG): + """Class representing an :class:`ast.arguments` node. + + An :class:`Arguments` node represents that arguments in a + function definition. + + >>> node = astroid.extract_node('def foo(bar): pass') + >>> node + + >>> node.args + + """ + + # Python 3.4+ uses a different approach regarding annotations, + # each argument is a new class, _ast.arg, which exposes an + # 'annotation' attribute. In astroid though, arguments are exposed + # as is in the Arguments node and the only way to expose annotations + # is by using something similar with Python 3.3: + # - we expose 'varargannotation' and 'kwargannotation' of annotations + # of varargs and kwargs. + # - we expose 'annotation', a list with annotations for + # for each normal argument. If an argument doesn't have an + # annotation, its value will be None. + + _astroid_fields = ( + "args", + "defaults", + "kwonlyargs", + "kw_defaults", + "annotations", + "varargannotation", + "kwargannotation", + "kwonlyargs_annotations", + ) + varargannotation = None + """The type annotation for the variable length arguments. + + :type: NodeNG + """ + kwargannotation = None + """The type annotation for the variable length keyword arguments. + + :type: NodeNG + """ + + _other_fields = ("vararg", "kwarg") + + def __init__(self, vararg=None, kwarg=None, parent=None): + """ + :param vararg: The name of the variable length arguments. + :type vararg: str or None + + :param kwarg: The name of the variable length keyword arguments. + :type kwarg: str or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + super(Arguments, self).__init__(parent=parent) + self.vararg = vararg + """The name of the variable length arguments. + + :type: str or None + """ + + self.kwarg = kwarg + """The name of the variable length keyword arguments. + + :type: str or None + """ + + self.args = [] + """The names of the required arguments. + + :type: list(AssignName) + """ + + self.defaults = [] + """The default values for arguments that can be passed positionally. + + :type: list(NodeNG) + """ + + self.kwonlyargs = [] + """The keyword arguments that cannot be passed positionally. + + :type: list(AssignName) + """ + + self.kw_defaults = [] + """The default values for keyword arguments that cannot be passed positionally. + + :type: list(NodeNG) + """ + + self.annotations = [] + """The type annotations of arguments that can be passed positionally. + + :type: list(NodeNG) + """ + + self.kwonlyargs_annotations = [] + """The type annotations of arguments that cannot be passed positionally. + + :type: list(NodeNG) + """ + + def postinit( + self, + args, + defaults, + kwonlyargs, + kw_defaults, + annotations, + kwonlyargs_annotations=None, + varargannotation=None, + kwargannotation=None, + ): + """Do some setup after initialisation. + + :param args: The names of the required arguments. + :type args: list(AssignName) + + :param defaults: The default values for arguments that can be passed + positionally. + :type defaults: list(NodeNG) + + :param kwonlyargs: The keyword arguments that cannot be passed + positionally. + :type kwonlyargs: list(AssignName) + + :param kw_defaults: The default values for keyword arguments that + cannot be passed positionally. + :type kw_defaults: list(NodeNG) + + :param annotations: The type annotations of arguments that can be + passed positionally. + :type annotations: list(NodeNG) + + :param kwonlyargs_annotations: The type annotations of arguments that + cannot be passed positionally. This should always be passed in + Python 3. + :type kwonlyargs_annotations: list(NodeNG) + + :param varargannotation: The type annotation for the variable length + arguments. + :type varargannotation: NodeNG + + :param kwargannotation: The type annotation for the variable length + keyword arguments. + :type kwargannotation: NodeNG + """ + self.args = args + self.defaults = defaults + self.kwonlyargs = kwonlyargs + self.kw_defaults = kw_defaults + self.annotations = annotations + self.kwonlyargs_annotations = kwonlyargs_annotations + self.varargannotation = varargannotation + self.kwargannotation = kwargannotation + + def _infer_name(self, frame, name): + if self.parent is frame: + return name + return None + + @decorators.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + lineno = super(Arguments, self).fromlineno + return max(lineno, self.parent.fromlineno or 0) + + def format_args(self): + """Get the arguments formatted as string. + + :returns: The formatted arguments. + :rtype: str + """ + result = [] + if self.args: + result.append( + _format_args( + self.args, self.defaults, getattr(self, "annotations", None) + ) + ) + if self.vararg: + result.append("*%s" % self.vararg) + if self.kwonlyargs: + if not self.vararg: + result.append("*") + result.append( + _format_args( + self.kwonlyargs, self.kw_defaults, self.kwonlyargs_annotations + ) + ) + if self.kwarg: + result.append("**%s" % self.kwarg) + return ", ".join(result) + + def default_value(self, argname): + """Get the default value for an argument. + + :param argname: The name of the argument to get the default value for. + :type argname: str + + :raises NoDefault: If there is no default value defined for the + given argument. + """ + i = _find_arg(argname, self.args)[0] + if i is not None: + idx = i - (len(self.args) - len(self.defaults)) + if idx >= 0: + return self.defaults[idx] + i = _find_arg(argname, self.kwonlyargs)[0] + if i is not None and self.kw_defaults[i] is not None: + return self.kw_defaults[i] + raise exceptions.NoDefault(func=self.parent, name=argname) + + def is_argument(self, name): + """Check if the given name is defined in the arguments. + + :param name: The name to check for. + :type name: str + + :returns: True if the given name is defined in the arguments, + False otherwise. + :rtype: bool + """ + if name == self.vararg: + return True + if name == self.kwarg: + return True + return ( + self.find_argname(name, True)[1] is not None + or self.kwonlyargs + and _find_arg(name, self.kwonlyargs, True)[1] is not None + ) + + def find_argname(self, argname, rec=False): + """Get the index and :class:`AssignName` node for given name. + + :param argname: The name of the argument to search for. + :type argname: str + + :param rec: Whether or not to include arguments in unpacked tuples + in the search. + :type rec: bool + + :returns: The index and node for the argument. + :rtype: tuple(str or None, AssignName or None) + """ + if self.args: # self.args may be None in some cases (builtin function) + return _find_arg(argname, self.args, rec) + return None, None + + def get_children(self): + yield from self.args or () + + yield from self.defaults + yield from self.kwonlyargs + + for elt in self.kw_defaults: + if elt is not None: + yield elt + + for elt in self.annotations: + if elt is not None: + yield elt + + if self.varargannotation is not None: + yield self.varargannotation + + if self.kwargannotation is not None: + yield self.kwargannotation + + for elt in self.kwonlyargs_annotations: + if elt is not None: + yield elt + + +def _find_arg(argname, args, rec=False): + for i, arg in enumerate(args): + if isinstance(arg, Tuple): + if rec: + found = _find_arg(argname, arg.elts) + if found[0] is not None: + return found + elif arg.name == argname: + return i, arg + return None, None + + +def _format_args(args, defaults=None, annotations=None): + values = [] + if args is None: + return "" + if annotations is None: + annotations = [] + if defaults is not None: + default_offset = len(args) - len(defaults) + packed = itertools.zip_longest(args, annotations) + for i, (arg, annotation) in enumerate(packed): + if isinstance(arg, Tuple): + values.append("(%s)" % _format_args(arg.elts)) + else: + argname = arg.name + if annotation is not None: + argname += ":" + annotation.as_string() + values.append(argname) + + if defaults is not None and i >= default_offset: + if defaults[i - default_offset] is not None: + values[-1] += "=" + defaults[i - default_offset].as_string() + return ", ".join(values) + + +class AssignAttr(mixins.ParentAssignTypeMixin, NodeNG): + """Variation of :class:`ast.Assign` representing assignment to an attribute. + + >>> node = astroid.extract_node('self.attribute = range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'self.attribute' + """ + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """What has the attribute that is being assigned to. + + :type: NodeNG or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute being assigned to. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute being assigned to. + + :type: str or None + """ + + super(AssignAttr, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: What has the attribute that is being assigned to. + :type expr: NodeNG or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Assert(Statement): + """Class representing an :class:`ast.Assert` node. + + An :class:`Assert` node represents an assert statement. + + >>> node = astroid.extract_node('assert len(things) == 10, "Not enough things"') + >>> node + + """ + + _astroid_fields = ("test", "fail") + test = None + """The test that passes or fails the assertion. + + :type: NodeNG or None + """ + fail = None + """The message shown when the assertion fails. + + :type: NodeNG or None + """ + + def postinit(self, test=None, fail=None): + """Do some setup after initialisation. + + :param test: The test that passes or fails the assertion. + :type test: NodeNG or None + + :param fail: The message shown when the assertion fails. + :type fail: NodeNG or None + """ + self.fail = fail + self.test = test + + def get_children(self): + yield self.test + + if self.fail is not None: + yield self.fail + + +class Assign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.Assign` node. + + An :class:`Assign` is a statement where something is explicitly + asssigned to. + + >>> node = astroid.extract_node('variable = range(10)') + >>> node + + """ + + _astroid_fields = ("targets", "value") + _other_other_fields = ("type_annotation",) + targets = None + """What is being assigned to. + + :type: list(NodeNG) or None + """ + value = None + """The value being assigned to the variables. + + :type: NodeNG or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + def postinit(self, targets=None, value=None, type_annotation=None): + """Do some setup after initialisation. + + :param targets: What is being assigned to. + :type targets: list(NodeNG) or None + + :param value: The value being assigned to the variables. + :type: NodeNG or None + """ + self.targets = targets + self.value = value + self.type_annotation = type_annotation + + def get_children(self): + yield from self.targets + + yield self.value + + @decorators.cached + def _get_assign_nodes(self): + return [self] + list(self.value._get_assign_nodes()) + + def _get_yield_nodes_skip_lambdas(self): + yield from self.value._get_yield_nodes_skip_lambdas() + + +class AnnAssign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.AnnAssign` node. + + An :class:`AnnAssign` is an assignment with a type annotation. + + >>> node = astroid.extract_node('variable: List[int] = range(10)') + >>> node + + """ + + _astroid_fields = ("target", "annotation", "value") + _other_fields = ("simple",) + target = None + """What is being assigned to. + + :type: NodeNG or None + """ + annotation = None + """The type annotation of what is being assigned to. + + :type: NodeNG + """ + value = None + """The value being assigned to the variables. + + :type: NodeNG or None + """ + simple = None + """Whether :attr:`target` is a pure name or a complex statement. + + :type: int + """ + + def postinit(self, target, annotation, simple, value=None): + """Do some setup after initialisation. + + :param target: What is being assigned to. + :type target: NodeNG + + :param annotation: The type annotation of what is being assigned to. + :type: NodeNG + + :param simple: Whether :attr:`target` is a pure name + or a complex statement. + :type simple: int + + :param value: The value being assigned to the variables. + :type: NodeNG or None + """ + self.target = target + self.annotation = annotation + self.value = value + self.simple = simple + + def get_children(self): + yield self.target + yield self.annotation + + if self.value is not None: + yield self.value + + +class AugAssign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.AugAssign` node. + + An :class:`AugAssign` is an assignment paired with an operator. + + >>> node = astroid.extract_node('variable += 1') + >>> node + + """ + + _astroid_fields = ("target", "value") + _other_fields = ("op",) + target = None + """What is being assigned to. + + :type: NodeNG or None + """ + value = None + """The value being assigned to the variable. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator that is being combined with the assignment. + This includes the equals sign. + :type op: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator that is being combined with the assignment. + + This includes the equals sign. + + :type: str or None + """ + + super(AugAssign, self).__init__(lineno, col_offset, parent) + + def postinit(self, target=None, value=None): + """Do some setup after initialisation. + + :param target: What is being assigned to. + :type target: NodeNG or None + + :param value: The value being assigned to the variable. + :type: NodeNG or None + """ + self.target = target + self.value = value + + # This is set by inference.py + def _infer_augassign(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage` , + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_augassign(context=context) + return [ + result + for result in results + if isinstance(result, util.BadBinaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.target + yield self.value + + +class Repr(NodeNG): + """Class representing an :class:`ast.Repr` node. + + A :class:`Repr` node represents the backtick syntax, + which is a deprecated alias for :func:`repr` removed in Python 3. + + >>> node = astroid.extract_node('`variable`') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """What is having :func:`repr` called on it. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What is having :func:`repr` called on it. + :type value: NodeNG or None + """ + self.value = value + + +class BinOp(NodeNG): + """Class representing an :class:`ast.BinOp` node. + + A :class:`BinOp` node is an application of a binary operator. + + >>> node = astroid.extract_node('a + b') + >>> node + + """ + + _astroid_fields = ("left", "right") + _other_fields = ("op",) + left = None + """What is being applied to the operator on the left side. + + :type: NodeNG or None + """ + right = None + """What is being applied to the operator on the right side. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(BinOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, left=None, right=None): + """Do some setup after initialisation. + + :param left: What is being applied to the operator on the left side. + :type left: NodeNG or None + + :param right: What is being applied to the operator on the right side. + :type right: NodeNG or None + """ + self.left = left + self.right = right + + # This is set by inference.py + def _infer_binop(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage`, + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_binop(context=context) + return [ + result + for result in results + if isinstance(result, util.BadBinaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.left + yield self.right + + def op_precedence(self): + return OP_PRECEDENCE[self.op] + + def op_left_associative(self): + # 2**3**4 == 2**(3**4) + return self.op != "**" + + +class BoolOp(NodeNG): + """Class representing an :class:`ast.BoolOp` node. + + A :class:`BoolOp` is an application of a boolean operator. + + >>> node = astroid.extract_node('a and b') + >>> node + + """ + + _astroid_fields = ("values",) + _other_fields = ("op",) + values = None + """The values being applied to the operator. + + :type: list(NodeNG) or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(BoolOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, values=None): + """Do some setup after initialisation. + + :param values: The values being applied to the operator. + :type values: list(NodeNG) or None + """ + self.values = values + + def get_children(self): + yield from self.values + + def op_precedence(self): + return OP_PRECEDENCE[self.op] + + +class Break(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Break` node. + + >>> node = astroid.extract_node('break') + >>> node + + """ + + +class Call(NodeNG): + """Class representing an :class:`ast.Call` node. + + A :class:`Call` node is a call to a function, method, etc. + + >>> node = astroid.extract_node('function()') + >>> node + + """ + + _astroid_fields = ("func", "args", "keywords") + func = None + """What is being called. + + :type: NodeNG or None + """ + args = None + """The positional arguments being given to the call. + + :type: list(NodeNG) or None + """ + keywords = None + """The keyword arguments being given to the call. + + :type: list(NodeNG) or None + """ + + def postinit(self, func=None, args=None, keywords=None): + """Do some setup after initialisation. + + :param func: What is being called. + :type func: NodeNG or None + + :param args: The positional arguments being given to the call. + :type args: list(NodeNG) or None + + :param keywords: The keyword arguments being given to the call. + :type keywords: list(NodeNG) or None + """ + self.func = func + self.args = args + self.keywords = keywords + + @property + def starargs(self): + """The positional arguments that unpack something. + + :type: list(Starred) + """ + args = self.args or [] + return [arg for arg in args if isinstance(arg, Starred)] + + @property + def kwargs(self): + """The keyword arguments that unpack something. + + :type: list(Keyword) + """ + keywords = self.keywords or [] + return [keyword for keyword in keywords if keyword.arg is None] + + def get_children(self): + yield self.func + + yield from self.args + + yield from self.keywords or () + + +class Compare(NodeNG): + """Class representing an :class:`ast.Compare` node. + + A :class:`Compare` node indicates a comparison. + + >>> node = astroid.extract_node('a <= b <= c') + >>> node + + >>> node.ops + [('<=', ), ('<=', )] + """ + + _astroid_fields = ("left", "ops") + left = None + """The value at the left being applied to a comparison operator. + + :type: NodeNG or None + """ + ops = None + """The remainder of the operators and their relevant right hand value. + + :type: list(tuple(str, NodeNG)) or None + """ + + def postinit(self, left=None, ops=None): + """Do some setup after initialisation. + + :param left: The value at the left being applied to a comparison + operator. + :type left: NodeNG or None + + :param ops: The remainder of the operators + and their relevant right hand value. + :type ops: list(tuple(str, NodeNG)) or None + """ + self.left = left + self.ops = ops + + def get_children(self): + """Get the child nodes below this node. + + Overridden to handle the tuple fields and skip returning the operator + strings. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + yield self.left + for _, comparator in self.ops: + yield comparator # we don't want the 'op' + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child. + :rtype: NodeNG + """ + # XXX maybe if self.ops: + return self.ops[-1][1] + # return self.left + + +class Comprehension(NodeNG): + """Class representing an :class:`ast.comprehension` node. + + A :class:`Comprehension` indicates the loop inside any type of + comprehension including generator expressions. + + >>> node = astroid.extract_node('[x for x in some_values]') + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[1].as_string() + 'for x in some_values' + """ + + _astroid_fields = ("target", "iter", "ifs") + _other_fields = ("is_async",) + target = None + """What is assigned to by the comprehension. + + :type: NodeNG or None + """ + iter = None + """What is iterated over by the comprehension. + + :type: NodeNG or None + """ + ifs = None + """The contents of any if statements that filter the comprehension. + + :type: list(NodeNG) or None + """ + is_async = None + """Whether this is an asynchronous comprehension or not. + + :type: bool or None + """ + + def __init__(self, parent=None): + """ + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + super(Comprehension, self).__init__() + self.parent = parent + + # pylint: disable=redefined-builtin; same name as builtin ast module. + def postinit(self, target=None, iter=None, ifs=None, is_async=None): + """Do some setup after initialisation. + + :param target: What is assigned to by the comprehension. + :type target: NodeNG or None + + :param iter: What is iterated over by the comprehension. + :type iter: NodeNG or None + + :param ifs: The contents of any if statements that filter + the comprehension. + :type ifs: list(NodeNG) or None + + :param is_async: Whether this is an asynchronous comprehension or not. + :type: bool or None + """ + self.target = target + self.iter = iter + self.ifs = ifs + self.is_async = is_async + + optional_assign = True + """Whether this node optionally assigns a variable. + + :type: bool + """ + + def assign_type(self): + """The type of assignment that this node performs. + + :returns: The assignment type. + :rtype: NodeNG + """ + return self + + def _get_filtered_stmts(self, lookup_node, node, stmts, mystmt): + """method used in filter_stmts""" + if self is mystmt: + if isinstance(lookup_node, (Const, Name)): + return [lookup_node], True + + elif self.statement() is mystmt: + # original node's statement is the assignment, only keeps + # current node (gen exp, list comp) + + return [node], True + + return stmts, False + + def get_children(self): + yield self.target + yield self.iter + + yield from self.ifs + + +class Const(mixins.NoChildrenMixin, NodeNG, bases.Instance): + """Class representing any constant including num, str, bool, None, bytes. + + >>> node = astroid.extract_node('(5, "This is a string.", True, None, b"bytes")') + >>> node + + >>> list(node.get_children()) + [, + , + , + , + ] + """ + + _other_fields = ("value",) + + def __init__(self, value, lineno=None, col_offset=None, parent=None): + """ + :param value: The value that the constant represents. + :type value: object + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.value = value + """The value that the constant represents. + + :type: object + """ + + super(Const, self).__init__(lineno, col_offset, parent) + + def __getattr__(self, name): + # This is needed because of Proxy's __getattr__ method. + # Calling object.__new__ on this class without calling + # __init__ would result in an infinite loop otherwise + # since __getattr__ is called when an attribute doesn't + # exist and self._proxied indirectly calls self.value + # and Proxy __getattr__ calls self.value + if name == "value": + raise AttributeError + return super().__getattr__(name) + + def getitem(self, index, context=None): + """Get an item from this node if subscriptable. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + + :raises AstroidTypeError: When the given index cannot be used as a + subscript index, or if this node is not subscriptable. + """ + if isinstance(index, Const): + index_value = index.value + elif isinstance(index, Slice): + index_value = _infer_slice(index, context=context) + + else: + raise exceptions.AstroidTypeError( + "Could not use type {} as subscript index".format(type(index)) + ) + + try: + if isinstance(self.value, (str, bytes)): + return Const(self.value[index_value]) + except IndexError as exc: + raise exceptions.AstroidIndexError( + message="Index {index!r} out of range", + node=self, + index=index, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.AstroidTypeError( + message="Type error {error!r}", node=self, index=index, context=context + ) from exc + + raise exceptions.AstroidTypeError("%r (value=%s)" % (self, self.value)) + + def has_dynamic_getattr(self): + """Check if the node has a custom __getattr__ or __getattribute__. + + :returns: True if the class has a custom + __getattr__ or __getattribute__, False otherwise. + For a :class:`Const` this is always ``False``. + :rtype: bool + """ + return False + + def itered(self): + """An iterator over the elements this node contains. + + :returns: The contents of this node. + :rtype: iterable(str) + + :raises TypeError: If this node does not represent something that is iterable. + """ + if isinstance(self.value, str): + return self.value + raise TypeError() + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return self._proxied.qname() + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool + """ + return bool(self.value) + + +class Continue(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Continue` node. + + >>> node = astroid.extract_node('continue') + >>> node + + """ + + +class Decorators(NodeNG): + """A node representing a list of decorators. + + A :class:`Decorators` is the decorators that are applied to + a method or function. + + >>> node = astroid.extract_node(''' + @property + def my_property(self): + return 3 + ''') + >>> node + + >>> list(node.get_children())[0] + + """ + + _astroid_fields = ("nodes",) + nodes = None + """The decorators that this node contains. + + :type: list(Name or Call) or None + """ + + def postinit(self, nodes): + """Do some setup after initialisation. + + :param nodes: The decorators that this node contains. + :type nodes: list(Name or Call) + """ + self.nodes = nodes + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + # skip the function node to go directly to the upper level scope + return self.parent.parent.scope() + + def get_children(self): + yield from self.nodes + + +class DelAttr(mixins.ParentAssignTypeMixin, NodeNG): + """Variation of :class:`ast.Delete` representing deletion of an attribute. + + >>> node = astroid.extract_node('del self.attr') + >>> node + + >>> list(node.get_children())[0] + + """ + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """The name that this node represents. + + :type: Name or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute that is being deleted. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute that is being deleted. + + :type: str or None + """ + + super(DelAttr, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: The name that this node represents. + :type expr: Name or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Delete(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.Delete` node. + + A :class:`Delete` is a ``del`` statement this is deleting something. + + >>> node = astroid.extract_node('del self.attr') + >>> node + + """ + + _astroid_fields = ("targets",) + targets = None + """What is being deleted. + + :type: list(NodeNG) or None + """ + + def postinit(self, targets=None): + """Do some setup after initialisation. + + :param targets: What is being deleted. + :type targets: list(NodeNG) or None + """ + self.targets = targets + + def get_children(self): + yield from self.targets + + +class Dict(NodeNG, bases.Instance): + """Class representing an :class:`ast.Dict` node. + + A :class:`Dict` is a dictionary that is created with ``{}`` syntax. + + >>> node = astroid.extract_node('{1: "1"}') + >>> node + + """ + + _astroid_fields = ("items",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.items = [] + """The key-value pairs contained in the dictionary. + + :type: list(tuple(NodeNG, NodeNG)) + """ + + super(Dict, self).__init__(lineno, col_offset, parent) + + def postinit(self, items): + """Do some setup after initialisation. + + :param items: The key-value pairs contained in the dictionary. + :type items: list(tuple(NodeNG, NodeNG)) + """ + self.items = items + + @classmethod + def from_constants(cls, items=None): + """Create a :class:`Dict` of constants from a live dictionary. + + :param items: The items to store in the node. + :type items: dict + + :returns: The created dictionary node. + :rtype: Dict + """ + node = cls() + if items is None: + node.items = [] + else: + node.items = [ + (const_factory(k), const_factory(v)) for k, v in items.items() + ] + return node + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.dict" % BUILTINS + + def get_children(self): + """Get the key and value nodes below this node. + + Children are returned in the order that they are defined in the source + code, key first then the value. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for key, value in self.items: + yield key + yield value + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child, or None if no children exist. + :rtype: NodeNG or None + """ + if self.items: + return self.items[-1][1] + return None + + def itered(self): + """An iterator over the keys this node contains. + + :returns: The keys of this node. + :rtype: iterable(NodeNG) + """ + return [key for (key, _) in self.items] + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + + :raises AstroidTypeError: When the given index cannot be used as a + subscript index, or if this node is not subscriptable. + :raises AstroidIndexError: If the given index does not exist in the + dictionary. + """ + for key, value in self.items: + # TODO(cpopa): no support for overriding yet, {1:2, **{1: 3}}. + if isinstance(key, DictUnpack): + try: + return value.getitem(index, context) + except (exceptions.AstroidTypeError, exceptions.AstroidIndexError): + continue + for inferredkey in key.infer(context): + if inferredkey is util.Uninferable: + continue + if isinstance(inferredkey, Const) and isinstance(index, Const): + if inferredkey.value == index.value: + return value + + raise exceptions.AstroidIndexError(index) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool + """ + return bool(self.items) + + +class Expr(Statement): + """Class representing an :class:`ast.Expr` node. + + An :class:`Expr` is any expression that does not have its value used or + stored. + + >>> node = astroid.extract_node('method()') + >>> node + + >>> node.parent + + """ + + _astroid_fields = ("value",) + value = None + """What the expression does. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What the expression does. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + def _get_yield_nodes_skip_lambdas(self): + if not self.value.is_lambda: + yield from self.value._get_yield_nodes_skip_lambdas() + + +class Ellipsis(mixins.NoChildrenMixin, NodeNG): # pylint: disable=redefined-builtin + """Class representing an :class:`ast.Ellipsis` node. + + An :class:`Ellipsis` is the ``...`` syntax. + + >>> node = astroid.extract_node('...') + >>> node + + """ + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For an :class:`Ellipsis` this is always ``True``. + :rtype: bool + """ + return True + + +class EmptyNode(mixins.NoChildrenMixin, NodeNG): + """Holds an arbitrary object in the :attr:`LocalsDictNodeNG.locals`.""" + + object = None + + +class ExceptHandler(mixins.MultiLineBlockMixin, mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.ExceptHandler`. node. + + An :class:`ExceptHandler` is an ``except`` block on a try-except. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + ''') + >>> node + + >>> >>> node.handlers + [] + """ + + _astroid_fields = ("type", "name", "body") + _multi_line_block_fields = ("body",) + type = None + """The types that the block handles. + + :type: Tuple or NodeNG or None + """ + name = None + """The name that the caught exception is assigned to. + + :type: AssignName or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + + def get_children(self): + if self.type is not None: + yield self.type + + if self.name is not None: + yield self.name + + yield from self.body + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, type=None, name=None, body=None): + """Do some setup after initialisation. + + :param type: The types that the block handles. + :type type: Tuple or NodeNG or None + + :param name: The name that the caught exception is assigned to. + :type name: AssignName or None + + :param body:The contents of the block. + :type body: list(NodeNG) or None + """ + self.type = type + self.name = name + self.body = body + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + if self.name: + return self.name.tolineno + if self.type: + return self.type.tolineno + return self.lineno + + def catch(self, exceptions): # pylint: disable=redefined-outer-name + """Check if this node handles any of the given exceptions. + + If ``exceptions`` is empty, this will default to ``True``. + + :param exceptions: The name of the exceptions to check for. + :type exceptions: list(str) + """ + if self.type is None or exceptions is None: + return True + for node in self.type._get_name_nodes(): + if node.name in exceptions: + return True + return False + + +class Exec(Statement): + """Class representing the ``exec`` statement. + + >>> node = astroid.extract_node('exec "True"') + >>> node + + """ + + _astroid_fields = ("expr", "globals", "locals") + expr = None + """The expression to be executed. + + :type: NodeNG or None + """ + globals = None + """The globals dictionary to execute with. + + :type: NodeNG or None + """ + locals = None + """The locals dictionary to execute with. + + :type: NodeNG or None + """ + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, expr=None, globals=None, locals=None): + """Do some setup after initialisation. + + :param expr: The expression to be executed. + :type expr: NodeNG or None + + :param globals:The globals dictionary to execute with. + :type globals: NodeNG or None + + :param locals: The locals dictionary to execute with. + :type locals: NodeNG or None + """ + self.expr = expr + self.globals = globals + self.locals = locals + + +class ExtSlice(NodeNG): + """Class representing an :class:`ast.ExtSlice` node. + + An :class:`ExtSlice` is a complex slice expression. + + >>> node = astroid.extract_node('l[1:3, 5]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("dims",) + dims = None + """The simple dimensions that form the complete slice. + + :type: list(NodeNG) or None + """ + + def postinit(self, dims=None): + """Do some setup after initialisation. + + :param dims: The simple dimensions that form the complete slice. + :type dims: list(NodeNG) or None + """ + self.dims = dims + + +class For( + mixins.MultiLineBlockMixin, + mixins.BlockRangeMixIn, + mixins.AssignTypeMixin, + Statement, +): + """Class representing an :class:`ast.For` node. + + >>> node = astroid.extract_node('for thing in things: print(thing)') + >>> node + + """ + + _astroid_fields = ("target", "iter", "body", "orelse") + _other_other_fields = ("type_annotation",) + _multi_line_block_fields = ("body", "orelse") + target = None + """What the loop assigns to. + + :type: NodeNG or None + """ + iter = None + """What the loop iterates over. + + :type: NodeNG or None + """ + body = None + """The contents of the body of the loop. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block of the loop. + + :type: list(NodeNG) or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit( + self, target=None, iter=None, body=None, orelse=None, type_annotation=None + ): + """Do some setup after initialisation. + + :param target: What the loop assigns to. + :type target: NodeNG or None + + :param iter: What the loop iterates over. + :type iter: NodeNG or None + + :param body: The contents of the body of the loop. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block of the loop. + :type orelse: list(NodeNG) or None + """ + self.target = target + self.iter = iter + self.body = body + self.orelse = orelse + self.type_annotation = type_annotation + + optional_assign = True + """Whether this node optionally assigns a variable. + + This is always ``True`` for :class:`For` nodes. + + :type: bool + """ + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.iter.tolineno + + def get_children(self): + yield self.target + yield self.iter + + yield from self.body + yield from self.orelse + + +class AsyncFor(For): + """Class representing an :class:`ast.AsyncFor` node. + + An :class:`AsyncFor` is an asynchronous :class:`For` built with + the ``async`` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + async for thing in things: + print(thing) + ''') + >>> node + + >>> node.body[0] + + """ + + +class Await(NodeNG): + """Class representing an :class:`ast.Await` node. + + An :class:`Await` is the ``await`` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + await other_func() + ''') + >>> node + + >>> node.body[0] + + >>> list(node.body[0].get_children())[0] + + """ + + _astroid_fields = ("value",) + value = None + """What to wait for. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What to wait for. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class ImportFrom(mixins.NoChildrenMixin, mixins.ImportFromMixin, Statement): + """Class representing an :class:`ast.ImportFrom` node. + + >>> node = astroid.extract_node('from my_package import my_module') + >>> node + + """ + + _other_fields = ("modname", "names", "level") + + def __init__( + self, fromname, names, level=0, lineno=None, col_offset=None, parent=None + ): + """ + :param fromname: The module that is being imported from. + :type fromname: str or None + + :param names: What is being imported from the module. + :type names: list(tuple(str, str or None)) + + :param level: The level of relative import. + :type level: int + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.modname = fromname + """The module that is being imported from. + + This is ``None`` for relative imports. + + :type: str or None + """ + + self.names = names + """What is being imported from the module. + + Each entry is a :class:`tuple` of the name being imported, + and the alias that the name is assigned to (if any). + + :type: list(tuple(str, str or None)) + """ + + self.level = level + """The level of relative import. + + Essentially this is the number of dots in the import. + This is always 0 for absolute imports. + + :type: int + """ + + super(ImportFrom, self).__init__(lineno, col_offset, parent) + + +class Attribute(NodeNG): + """Class representing an :class:`ast.Attribute` node.""" + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """The name that this node represents. + + :type: Name or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute. + + :type: str or None + """ + + super(Attribute, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: The name that this node represents. + :type expr: Name or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Global(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Global` node. + + >>> node = astroid.extract_node('global a_global') + >>> node + + """ + + _other_fields = ("names",) + + def __init__(self, names, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being declared as global. + :type names: list(str) + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being declared as global. + + :type: list(str) + """ + + super(Global, self).__init__(lineno, col_offset, parent) + + def _infer_name(self, frame, name): + return name + + +class If(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.If` node. + + >>> node = astroid.extract_node('if condition: print(True)') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + _multi_line_block_fields = ("body", "orelse") + test = None + """The condition that the statement tests. + + :type: NodeNG or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the statement tests. + :type test: NodeNG or None + + :param body: The contents of the block. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.test.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + if lineno == self.body[0].fromlineno: + return lineno, lineno + if lineno <= self.body[-1].tolineno: + return lineno, self.body[-1].tolineno + return self._elsed_block_range(lineno, self.orelse, self.body[0].fromlineno - 1) + + def get_children(self): + yield self.test + + yield from self.body + yield from self.orelse + + def has_elif_block(self): + return len(self.orelse) == 1 and isinstance(self.orelse[0], If) + + +class IfExp(NodeNG): + """Class representing an :class:`ast.IfExp` node. + + >>> node = astroid.extract_node('value if condition else other') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + test = None + """The condition that the statement tests. + + :type: NodeNG or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the statement tests. + :type test: NodeNG or None + + :param body: The contents of the block. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + def get_children(self): + yield self.test + yield self.body + yield self.orelse + + def op_left_associative(self): + # `1 if True else 2 if False else 3` is parsed as + # `1 if True else (2 if False else 3)` + return False + + +class Import(mixins.NoChildrenMixin, mixins.ImportFromMixin, Statement): + """Class representing an :class:`ast.Import` node. + + >>> node = astroid.extract_node('import astroid') + >>> node + + """ + + _other_fields = ("names",) + + def __init__(self, names=None, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being imported. + :type names: list(tuple(str, str or None)) or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being imported. + + Each entry is a :class:`tuple` of the name being imported, + and the alias that the name is assigned to (if any). + + :type: list(tuple(str, str or None)) or None + """ + + super(Import, self).__init__(lineno, col_offset, parent) + + +class Index(NodeNG): + """Class representing an :class:`ast.Index` node. + + An :class:`Index` is a simple subscript. + + >>> node = astroid.extract_node('things[1]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("value",) + value = None + """The value to subscript with. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value to subscript with. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class Keyword(NodeNG): + """Class representing an :class:`ast.keyword` node. + + >>> node = astroid.extract_node('function(a_kwarg=True)') + >>> node + + >>> node.keywords + [] + """ + + _astroid_fields = ("value",) + _other_fields = ("arg",) + value = None + """The value being assigned to the keyword argument. + + :type: NodeNG or None + """ + + def __init__(self, arg=None, lineno=None, col_offset=None, parent=None): + """ + :param arg: The argument being assigned to. + :type arg: Name or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.arg = arg + """The argument being assigned to. + + :type: Name or None + """ + + super(Keyword, self).__init__(lineno, col_offset, parent) + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value being assigned to the ketword argument. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class List(_BaseContainer): + """Class representing an :class:`ast.List` node. + + >>> node = astroid.extract_node('[1, 2, 3]') + >>> node + + """ + + _other_fields = ("ctx",) + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the list is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the list is assigned to or loaded from. + + :type: Context or None + """ + + super(List, self).__init__(lineno, col_offset, parent) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.list" % BUILTINS + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + """ + return _container_getitem(self, self.elts, index, context=context) + + +class Nonlocal(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Nonlocal` node. + + >>> node = astroid.extract_node(''' + def function(): + nonlocal var + ''') + >>> node + + >>> node.body[0] + + """ + + _other_fields = ("names",) + + def __init__(self, names, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being declared as not local. + :type names: list(str) + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being declared as not local. + + :type: list(str) + """ + + super(Nonlocal, self).__init__(lineno, col_offset, parent) + + def _infer_name(self, frame, name): + return name + + +class Pass(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Pass` node. + + >>> node = astroid.extract_node('pass') + >>> node + + """ + + +class Print(Statement): + """Class representing an :class:`ast.Print` node. + + >>> node = astroid.extract_node('print "A message"') + >>> node + + """ + + _astroid_fields = ("dest", "values") + dest = None + """Where to print to. + + :type: NodeNG or None + """ + values = None + """What to print. + + :type: list(NodeNG) or None + """ + + def __init__(self, nl=None, lineno=None, col_offset=None, parent=None): + """ + :param nl: Whether to print a new line. + :type nl: bool or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.nl = nl + """Whether to print a new line. + + :type: bool or None + """ + + super(Print, self).__init__(lineno, col_offset, parent) + + def postinit(self, dest=None, values=None): + """Do some setup after initialisation. + + :param dest: Where to print to. + :type dest: NodeNG or None + + :param values: What to print. + :type values: list(NodeNG) or None + """ + self.dest = dest + self.values = values + + +class Raise(Statement): + """Class representing an :class:`ast.Raise` node. + + >>> node = astroid.extract_node('raise RuntimeError("Something bad happened!")') + >>> node + + """ + + exc = None + """What is being raised. + + :type: NodeNG or None + """ + _astroid_fields = ("exc", "cause") + cause = None + """The exception being used to raise this one. + + :type: NodeNG or None + """ + + def postinit(self, exc=None, cause=None): + """Do some setup after initialisation. + + :param exc: What is being raised. + :type exc: NodeNG or None + + :param cause: The exception being used to raise this one. + :type cause: NodeNG or None + """ + self.exc = exc + self.cause = cause + + def raises_not_implemented(self): + """Check if this node raises a :class:`NotImplementedError`. + + :returns: True if this node raises a :class:`NotImplementedError`, + False otherwise. + :rtype: bool + """ + if not self.exc: + return False + for name in self.exc._get_name_nodes(): + if name.name == "NotImplementedError": + return True + return False + + def get_children(self): + if self.exc is not None: + yield self.exc + + if self.cause is not None: + yield self.cause + + +class Return(Statement): + """Class representing an :class:`ast.Return` node. + + >>> node = astroid.extract_node('return True') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """The value being returned. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value being returned. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + if self.value is not None: + yield self.value + + def is_tuple_return(self): + return isinstance(self.value, Tuple) + + def _get_return_nodes_skip_functions(self): + yield self + + +class Set(_BaseContainer): + """Class representing an :class:`ast.Set` node. + + >>> node = astroid.extract_node('{1, 2, 3}') + >>> node + + """ + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.set" % BUILTINS + + +class Slice(NodeNG): + """Class representing an :class:`ast.Slice` node. + + >>> node = astroid.extract_node('things[1:3]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("lower", "upper", "step") + lower = None + """The lower index in the slice. + + :type: NodeNG or None + """ + upper = None + """The upper index in the slice. + + :type: NodeNG or None + """ + step = None + """The step to take between indexes. + + :type: NodeNG or None + """ + + def postinit(self, lower=None, upper=None, step=None): + """Do some setup after initialisation. + + :param lower: The lower index in the slice. + :value lower: NodeNG or None + + :param upper: The upper index in the slice. + :value upper: NodeNG or None + + :param step: The step to take between index. + :param step: NodeNG or None + """ + self.lower = lower + self.upper = upper + self.step = step + + def _wrap_attribute(self, attr): + """Wrap the empty attributes of the Slice in a Const node.""" + if not attr: + const = const_factory(attr) + const.parent = self + return const + return attr + + @decorators.cachedproperty + def _proxied(self): + builtins = MANAGER.builtins_module + return builtins.getattr("slice")[0] + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.slice" % BUILTINS + + def igetattr(self, attrname, context=None): + """Infer the possible values of the given attribute on the slice. + + :param attrname: The name of the attribute to infer. + :type attrname: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG) + """ + if attrname == "start": + yield self._wrap_attribute(self.lower) + elif attrname == "stop": + yield self._wrap_attribute(self.upper) + elif attrname == "step": + yield self._wrap_attribute(self.step) + else: + yield from self.getattr(attrname, context=context) + + def getattr(self, attrname, context=None): + return self._proxied.getattr(attrname, context) + + def get_children(self): + if self.lower is not None: + yield self.lower + + if self.upper is not None: + yield self.upper + + if self.step is not None: + yield self.step + + +class Starred(mixins.ParentAssignTypeMixin, NodeNG): + """Class representing an :class:`ast.Starred` node. + + >>> node = astroid.extract_node('*args') + >>> node + + """ + + _astroid_fields = ("value",) + _other_fields = ("ctx",) + value = None + """What is being unpacked. + + :type: NodeNG or None + """ + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the list is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the starred item is assigned to or loaded from. + + :type: Context or None + """ + + super(Starred, self).__init__( + lineno=lineno, col_offset=col_offset, parent=parent + ) + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What is being unpacked. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class Subscript(NodeNG): + """Class representing an :class:`ast.Subscript` node. + + >>> node = astroid.extract_node('things[1:3]') + >>> node + + """ + + _astroid_fields = ("value", "slice") + _other_fields = ("ctx",) + value = None + """What is being indexed. + + :type: NodeNG or None + """ + slice = None + """The slice being used to lookup. + + :type: NodeNG or None + """ + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the subscripted item is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the subscripted item is assigned to or loaded from. + + :type: Context or None + """ + + super(Subscript, self).__init__( + lineno=lineno, col_offset=col_offset, parent=parent + ) + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, value=None, slice=None): + """Do some setup after initialisation. + + :param value: What is being indexed. + :type value: NodeNG or None + + :param slice: The slice being used to lookup. + :type slice: NodeNG or None + """ + self.value = value + self.slice = slice + + def get_children(self): + yield self.value + yield self.slice + + +class TryExcept(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.TryExcept` node. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + ''') + >>> node + + """ + + _astroid_fields = ("body", "handlers", "orelse") + _multi_line_block_fields = ("body", "handlers", "orelse") + body = None + """The contents of the block to catch exceptions from. + + :type: list(NodeNG) or None + """ + handlers = None + """The exception handlers. + + :type: list(ExceptHandler) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, body=None, handlers=None, orelse=None): + """Do some setup after initialisation. + + :param body: The contents of the block to catch exceptions from. + :type body: list(NodeNG) or None + + :param handlers: The exception handlers. + :type handlers: list(ExceptHandler) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.body = body + self.handlers = handlers + self.orelse = orelse + + def _infer_name(self, frame, name): + return name + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + last = None + for exhandler in self.handlers: + if exhandler.type and lineno == exhandler.type.fromlineno: + return lineno, lineno + if exhandler.body[0].fromlineno <= lineno <= exhandler.body[-1].tolineno: + return lineno, exhandler.body[-1].tolineno + if last is None: + last = exhandler.body[0].fromlineno - 1 + return self._elsed_block_range(lineno, self.orelse, last) + + def get_children(self): + yield from self.body + + yield from self.handlers or () + yield from self.orelse or () + + +class TryFinally(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.TryFinally` node. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + finally: + print("Cleanup!") + ''') + >>> node + + """ + + _astroid_fields = ("body", "finalbody") + _multi_line_block_fields = ("body", "finalbody") + body = None + """The try-except that the finally is attached to. + + :type: list(TryExcept) or None + """ + finalbody = None + """The contents of the ``finally`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, body=None, finalbody=None): + """Do some setup after initialisation. + + :param body: The try-except that the finally is attached to. + :type body: list(TryExcept) or None + + :param finalbody: The contents of the ``finally`` block. + :type finalbody: list(NodeNG) or None + """ + self.body = body + self.finalbody = finalbody + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + child = self.body[0] + # py2.5 try: except: finally: + if ( + isinstance(child, TryExcept) + and child.fromlineno == self.fromlineno + and child.tolineno >= lineno > self.fromlineno + ): + return child.block_range(lineno) + return self._elsed_block_range(lineno, self.finalbody) + + def get_children(self): + yield from self.body + yield from self.finalbody + + +class Tuple(_BaseContainer): + """Class representing an :class:`ast.Tuple` node. + + >>> node = astroid.extract_node('(1, 2, 3)') + >>> node + + """ + + _other_fields = ("ctx",) + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the tuple is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the tuple is assigned to or loaded from. + + :type: Context or None + """ + + super(Tuple, self).__init__(lineno, col_offset, parent) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.tuple" % BUILTINS + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + """ + return _container_getitem(self, self.elts, index, context=context) + + +class UnaryOp(NodeNG): + """Class representing an :class:`ast.UnaryOp` node. + + >>> node = astroid.extract_node('-5') + >>> node + + """ + + _astroid_fields = ("operand",) + _other_fields = ("op",) + operand = None + """What the unary operator is applied to. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(UnaryOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, operand=None): + """Do some setup after initialisation. + + :param operand: What the unary operator is applied to. + :type operand: NodeNG or None + """ + self.operand = operand + + # This is set by inference.py + def _infer_unaryop(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage`, + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_unaryop(context=context) + return [ + result + for result in results + if isinstance(result, util.BadUnaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.operand + + def op_precedence(self): + if self.op == "not": + return OP_PRECEDENCE[self.op] + + return super().op_precedence() + + +class While(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.While` node. + + >>> node = astroid.extract_node(''' + while condition(): + print("True") + ''') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + _multi_line_block_fields = ("body", "orelse") + test = None + """The condition that the loop tests. + + :type: NodeNG or None + """ + body = None + """The contents of the loop. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the loop tests. + :type test: NodeNG or None + + :param body: The contents of the loop. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.test.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + return self._elsed_block_range(lineno, self.orelse) + + def get_children(self): + yield self.test + + yield from self.body + yield from self.orelse + + +class With( + mixins.MultiLineBlockMixin, + mixins.BlockRangeMixIn, + mixins.AssignTypeMixin, + Statement, +): + """Class representing an :class:`ast.With` node. + + >>> node = astroid.extract_node(''' + with open(file_path) as file_: + print(file_.read()) + ''') + >>> node + + """ + + _astroid_fields = ("items", "body") + _other_other_fields = ("type_annotation",) + _multi_line_block_fields = ("body",) + items = None + """The pairs of context managers and the names they are assigned to. + + :type: list(tuple(NodeNG, AssignName or None)) or None + """ + body = None + """The contents of the ``with`` block. + + :type: list(NodeNG) or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + def postinit(self, items=None, body=None, type_annotation=None): + """Do some setup after initialisation. + + :param items: The pairs of context managers and the names + they are assigned to. + :type items: list(tuple(NodeNG, AssignName or None)) or None + + :param body: The contents of the ``with`` block. + :type body: list(NodeNG) or None + """ + self.items = items + self.body = body + self.type_annotation = type_annotation + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.items[-1][0].tolineno + + def get_children(self): + """Get the child nodes below this node. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for expr, var in self.items: + yield expr + if var: + yield var + yield from self.body + + +class AsyncWith(With): + """Asynchronous ``with`` built with the ``async`` keyword.""" + + +class Yield(NodeNG): + """Class representing an :class:`ast.Yield` node. + + >>> node = astroid.extract_node('yield True') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """The value to yield. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value to yield. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + if self.value is not None: + yield self.value + + def _get_yield_nodes_skip_lambdas(self): + yield self + + +class YieldFrom(Yield): + """Class representing an :class:`ast.YieldFrom` node.""" + + +class DictUnpack(mixins.NoChildrenMixin, NodeNG): + """Represents the unpacking of dicts into dicts using :pep:`448`.""" + + +class FormattedValue(NodeNG): + """Class representing an :class:`ast.FormattedValue` node. + + Represents a :pep:`498` format string. + + >>> node = astroid.extract_node('f"Format {type_}"') + >>> node + + >>> node.values + [, ] + """ + + _astroid_fields = ("value", "format_spec") + value = None + """The value to be formatted into the string. + + :type: NodeNG or None + """ + conversion = None + """The type of formatting to be applied to the value. + + .. seealso:: + :class:`ast.FormattedValue` + + :type: int or None + """ + format_spec = None + """The formatting to be applied to the value. + + .. seealso:: + :class:`ast.FormattedValue` + + :type: JoinedStr or None + """ + + def postinit(self, value, conversion=None, format_spec=None): + """Do some setup after initialisation. + + :param value: The value to be formatted into the string. + :type value: NodeNG + + :param conversion: The type of formatting to be applied to the value. + :type conversion: int or None + + :param format_spec: The formatting to be applied to the value. + :type format_spec: JoinedStr or None + """ + self.value = value + self.conversion = conversion + self.format_spec = format_spec + + def get_children(self): + yield self.value + + if self.format_spec is not None: + yield self.format_spec + + +class JoinedStr(NodeNG): + """Represents a list of string expressions to be joined. + + >>> node = astroid.extract_node('f"Format {type_}"') + >>> node + + """ + + _astroid_fields = ("values",) + values = None + """The string expressions to be joined. + + :type: list(FormattedValue or Const) or None + """ + + def postinit(self, values=None): + """Do some setup after initialisation. + + :param value: The string expressions to be joined. + + :type: list(FormattedValue or Const) or None + """ + self.values = values + + def get_children(self): + yield from self.values + + +class Unknown(mixins.AssignTypeMixin, NodeNG): + """This node represents a node in a constructed AST where + introspection is not possible. At the moment, it's only used in + the args attribute of FunctionDef nodes where function signature + introspection failed. + """ + + name = "Unknown" + + def qname(self): + return "Unknown" + + def infer(self, context=None, **kwargs): + """Inference on an Unknown node immediately terminates.""" + yield util.Uninferable + + +# constants ############################################################## + +CONST_CLS = { + list: List, + tuple: Tuple, + dict: Dict, + set: Set, + type(None): Const, + type(NotImplemented): Const, +} + + +def _update_const_classes(): + """update constant classes, so the keys of CONST_CLS can be reused""" + klasses = (bool, int, float, complex, str, bytes) + for kls in klasses: + CONST_CLS[kls] = Const + + +_update_const_classes() + + +def _two_step_initialization(cls, value): + instance = cls() + instance.postinit(value) + return instance + + +def _dict_initialization(cls, value): + if isinstance(value, dict): + value = tuple(value.items()) + return _two_step_initialization(cls, value) + + +_CONST_CLS_CONSTRUCTORS = { + List: _two_step_initialization, + Tuple: _two_step_initialization, + Dict: _dict_initialization, + Set: _two_step_initialization, + Const: lambda cls, value: cls(value), +} + + +def const_factory(value): + """return an astroid node for a python value""" + # XXX we should probably be stricter here and only consider stuff in + # CONST_CLS or do better treatment: in case where value is not in CONST_CLS, + # we should rather recall the builder on this value than returning an empty + # node (another option being that const_factory shouldn't be called with something + # not in CONST_CLS) + assert not isinstance(value, NodeNG) + + # Hack for ignoring elements of a sequence + # or a mapping, in order to avoid transforming + # each element to an AST. This is fixed in 2.0 + # and this approach is a temporary hack. + if isinstance(value, (list, set, tuple, dict)): + elts = [] + else: + elts = value + + try: + initializer_cls = CONST_CLS[value.__class__] + initializer = _CONST_CLS_CONSTRUCTORS[initializer_cls] + return initializer(initializer_cls, elts) + except (KeyError, AttributeError): + node = EmptyNode() + node.object = value + return node + + +def is_from_decorator(node): + """Return True if the given node is the child of a decorator""" + parent = node.parent + while parent is not None: + if isinstance(parent, Decorators): + return True + parent = parent.parent + return False diff --git a/venv/lib/python3.7/site-packages/astroid/nodes.py b/venv/lib/python3.7/site-packages/astroid/nodes.py new file mode 100644 index 0000000..2067259 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/nodes.py @@ -0,0 +1,173 @@ +# Copyright (c) 2006-2011, 2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2017 Ashley Whetter +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Every available node class. + +.. seealso:: + :doc:`ast documentation ` + +All nodes inherit from :class:`~astroid.node_classes.NodeNG`. +""" +# pylint: disable=unused-import,redefined-builtin + +from astroid.node_classes import ( + Arguments, + AssignAttr, + Assert, + Assign, + AnnAssign, + AssignName, + AugAssign, + Repr, + BinOp, + BoolOp, + Break, + Call, + Compare, + Comprehension, + Const, + Continue, + Decorators, + DelAttr, + DelName, + Delete, + Dict, + Expr, + Ellipsis, + EmptyNode, + ExceptHandler, + Exec, + ExtSlice, + For, + ImportFrom, + Attribute, + Global, + If, + IfExp, + Import, + Index, + Keyword, + List, + Name, + Nonlocal, + Pass, + Print, + Raise, + Return, + Set, + Slice, + Starred, + Subscript, + TryExcept, + TryFinally, + Tuple, + UnaryOp, + While, + With, + Yield, + YieldFrom, + const_factory, + AsyncFor, + Await, + AsyncWith, + FormattedValue, + JoinedStr, + # Node not present in the builtin ast module. + DictUnpack, + Unknown, +) +from astroid.scoped_nodes import ( + Module, + GeneratorExp, + Lambda, + DictComp, + ListComp, + SetComp, + FunctionDef, + ClassDef, + AsyncFunctionDef, +) + + +ALL_NODE_CLASSES = ( + AsyncFunctionDef, + AsyncFor, + AsyncWith, + Await, + Arguments, + AssignAttr, + Assert, + Assign, + AnnAssign, + AssignName, + AugAssign, + Repr, + BinOp, + BoolOp, + Break, + Call, + ClassDef, + Compare, + Comprehension, + Const, + Continue, + Decorators, + DelAttr, + DelName, + Delete, + Dict, + DictComp, + DictUnpack, + Expr, + Ellipsis, + EmptyNode, + ExceptHandler, + Exec, + ExtSlice, + For, + ImportFrom, + FunctionDef, + Attribute, + GeneratorExp, + Global, + If, + IfExp, + Import, + Index, + Keyword, + Lambda, + List, + ListComp, + Name, + Nonlocal, + Module, + Pass, + Print, + Raise, + Return, + Set, + SetComp, + Slice, + Starred, + Subscript, + TryExcept, + TryFinally, + Tuple, + UnaryOp, + While, + With, + Yield, + YieldFrom, + FormattedValue, + JoinedStr, +) diff --git a/venv/lib/python3.7/site-packages/astroid/objects.py b/venv/lib/python3.7/site-packages/astroid/objects.py new file mode 100644 index 0000000..888ca36 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/objects.py @@ -0,0 +1,282 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +Inference objects are a way to represent composite AST nodes, +which are used only as inference results, so they can't be found in the +original AST tree. For instance, inferring the following frozenset use, +leads to an inferred FrozenSet: + + Call(func=Name('frozenset'), args=Tuple(...)) +""" + +import builtins + +from astroid import bases +from astroid import decorators +from astroid import exceptions +from astroid import MANAGER +from astroid import node_classes +from astroid import scoped_nodes +from astroid import util + + +BUILTINS = builtins.__name__ +objectmodel = util.lazy_import("interpreter.objectmodel") + + +class FrozenSet(node_classes._BaseContainer): + """class representing a FrozenSet composite node""" + + def pytype(self): + return "%s.frozenset" % BUILTINS + + def _infer(self, context=None): + yield self + + @decorators.cachedproperty + def _proxied(self): # pylint: disable=method-hidden + ast_builtins = MANAGER.builtins_module + return ast_builtins.getattr("frozenset")[0] + + +class Super(node_classes.NodeNG): + """Proxy class over a super call. + + This class offers almost the same behaviour as Python's super, + which is MRO lookups for retrieving attributes from the parents. + + The *mro_pointer* is the place in the MRO from where we should + start looking, not counting it. *mro_type* is the object which + provides the MRO, it can be both a type or an instance. + *self_class* is the class where the super call is, while + *scope* is the function where the super call is. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.SuperModel()) + + # pylint: disable=super-init-not-called + def __init__(self, mro_pointer, mro_type, self_class, scope): + self.type = mro_type + self.mro_pointer = mro_pointer + self._class_based = False + self._self_class = self_class + self._scope = scope + + def _infer(self, context=None): + yield self + + def super_mro(self): + """Get the MRO which will be used to lookup attributes in this super.""" + if not isinstance(self.mro_pointer, scoped_nodes.ClassDef): + raise exceptions.SuperError( + "The first argument to super must be a subtype of " + "type, not {mro_pointer}.", + super_=self, + ) + + if isinstance(self.type, scoped_nodes.ClassDef): + # `super(type, type)`, most likely in a class method. + self._class_based = True + mro_type = self.type + else: + mro_type = getattr(self.type, "_proxied", None) + if not isinstance(mro_type, (bases.Instance, scoped_nodes.ClassDef)): + raise exceptions.SuperError( + "The second argument to super must be an " + "instance or subtype of type, not {type}.", + super_=self, + ) + + if not mro_type.newstyle: + raise exceptions.SuperError( + "Unable to call super on old-style classes.", super_=self + ) + + mro = mro_type.mro() + if self.mro_pointer not in mro: + raise exceptions.SuperError( + "The second argument to super must be an " + "instance or subtype of type, not {type}.", + super_=self, + ) + + index = mro.index(self.mro_pointer) + return mro[index + 1 :] + + @decorators.cachedproperty + def _proxied(self): + ast_builtins = MANAGER.builtins_module + return ast_builtins.getattr("super")[0] + + def pytype(self): + return "%s.super" % BUILTINS + + def display_type(self): + return "Super of" + + @property + def name(self): + """Get the name of the MRO pointer.""" + return self.mro_pointer.name + + def qname(self): + return "super" + + def igetattr(self, name, context=None): + """Retrieve the inferred values of the given attribute name.""" + + if name in self.special_attributes: + yield self.special_attributes.lookup(name) + return + + try: + mro = self.super_mro() + # Don't let invalid MROs or invalid super calls + # leak out as is from this function. + except exceptions.SuperError as exc: + raise exceptions.AttributeInferenceError( + ( + "Lookup for {name} on {target!r} because super call {super!r} " + "is invalid." + ), + target=self, + attribute=name, + context=context, + super_=exc.super_, + ) from exc + except exceptions.MroError as exc: + raise exceptions.AttributeInferenceError( + ( + "Lookup for {name} on {target!r} failed because {cls!r} has an " + "invalid MRO." + ), + target=self, + attribute=name, + context=context, + mros=exc.mros, + cls=exc.cls, + ) from exc + found = False + for cls in mro: + if name not in cls.locals: + continue + + found = True + for inferred in bases._infer_stmts([cls[name]], context, frame=self): + if not isinstance(inferred, scoped_nodes.FunctionDef): + yield inferred + continue + + # We can obtain different descriptors from a super depending + # on what we are accessing and where the super call is. + if inferred.type == "classmethod": + yield bases.BoundMethod(inferred, cls) + elif self._scope.type == "classmethod" and inferred.type == "method": + yield inferred + elif self._class_based or inferred.type == "staticmethod": + yield inferred + elif bases._is_property(inferred): + # TODO: support other descriptors as well. + try: + yield from inferred.infer_call_result(self, context) + except exceptions.InferenceError: + yield util.Uninferable + else: + yield bases.BoundMethod(inferred, cls) + + if not found: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def getattr(self, name, context=None): + return list(self.igetattr(name, context=context)) + + +class ExceptionInstance(bases.Instance): + """Class for instances of exceptions + + It has special treatment for some of the exceptions's attributes, + which are transformed at runtime into certain concrete objects, such as + the case of .args. + """ + + @decorators.cachedproperty + def special_attributes(self): + qname = self.qname() + instance = objectmodel.BUILTIN_EXCEPTIONS.get( + qname, objectmodel.ExceptionInstanceModel + ) + return instance()(self) + + +class DictInstance(bases.Instance): + """Special kind of instances for dictionaries + + This instance knows the underlying object model of the dictionaries, which means + that methods such as .values or .items can be properly inferred. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.DictModel()) + + +# Custom objects tailored for dictionaries, which are used to +# disambiguate between the types of Python 2 dict's method returns +# and Python 3 (where they return set like objects). +class DictItems(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class DictKeys(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class DictValues(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class PartialFunction(scoped_nodes.FunctionDef): + """A class representing partial function obtained via functools.partial""" + + def __init__( + self, call, name=None, doc=None, lineno=None, col_offset=None, parent=None + ): + super().__init__(name, doc, lineno, col_offset, parent) + self.filled_positionals = len(call.positional_arguments[1:]) + self.filled_args = call.positional_arguments[1:] + self.filled_keywords = call.keyword_arguments + + def infer_call_result(self, caller=None, context=None): + if context: + current_passed_keywords = { + keyword for (keyword, _) in context.callcontext.keywords + } + for keyword, value in self.filled_keywords.items(): + if keyword not in current_passed_keywords: + context.callcontext.keywords.append((keyword, value)) + + call_context_args = context.callcontext.args or [] + context.callcontext.args = self.filled_args + call_context_args + + return super().infer_call_result(caller=caller, context=context) + + def qname(self): + return self.__class__.__name__ + + +# TODO: Hack to solve the circular import problem between node_classes and objects +# This is not needed in 2.0, which has a cleaner design overall +node_classes.Dict.__bases__ = (node_classes.NodeNG, DictInstance) diff --git a/venv/lib/python3.7/site-packages/astroid/protocols.py b/venv/lib/python3.7/site-packages/astroid/protocols.py new file mode 100644 index 0000000..db0f5d9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/protocols.py @@ -0,0 +1,755 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to handle python protocols for nodes +where it makes sense. +""" + +import collections +import operator as operator_mod +import sys + +import itertools + +from astroid import Store +from astroid import arguments +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators +from astroid import node_classes +from astroid import helpers +from astroid import nodes +from astroid import util + +raw_building = util.lazy_import("raw_building") +objects = util.lazy_import("objects") + + +def _reflected_name(name): + return "__r" + name[2:] + + +def _augmented_name(name): + return "__i" + name[2:] + + +_CONTEXTLIB_MGR = "contextlib.contextmanager" +BIN_OP_METHOD = { + "+": "__add__", + "-": "__sub__", + "/": "__truediv__", + "//": "__floordiv__", + "*": "__mul__", + "**": "__pow__", + "%": "__mod__", + "&": "__and__", + "|": "__or__", + "^": "__xor__", + "<<": "__lshift__", + ">>": "__rshift__", + "@": "__matmul__", +} + +REFLECTED_BIN_OP_METHOD = { + key: _reflected_name(value) for (key, value) in BIN_OP_METHOD.items() +} +AUGMENTED_OP_METHOD = { + key + "=": _augmented_name(value) for (key, value) in BIN_OP_METHOD.items() +} + +UNARY_OP_METHOD = { + "+": "__pos__", + "-": "__neg__", + "~": "__invert__", + "not": None, # XXX not '__nonzero__' +} +_UNARY_OPERATORS = { + "+": operator_mod.pos, + "-": operator_mod.neg, + "~": operator_mod.invert, + "not": operator_mod.not_, +} + + +def _infer_unary_op(obj, op): + func = _UNARY_OPERATORS[op] + value = func(obj) + return nodes.const_factory(value) + + +nodes.Tuple.infer_unary_op = lambda self, op: _infer_unary_op(tuple(self.elts), op) +nodes.List.infer_unary_op = lambda self, op: _infer_unary_op(self.elts, op) +nodes.Set.infer_unary_op = lambda self, op: _infer_unary_op(set(self.elts), op) +nodes.Const.infer_unary_op = lambda self, op: _infer_unary_op(self.value, op) +nodes.Dict.infer_unary_op = lambda self, op: _infer_unary_op(dict(self.items), op) + +# Binary operations + +BIN_OP_IMPL = { + "+": lambda a, b: a + b, + "-": lambda a, b: a - b, + "/": lambda a, b: a / b, + "//": lambda a, b: a // b, + "*": lambda a, b: a * b, + "**": lambda a, b: a ** b, + "%": lambda a, b: a % b, + "&": lambda a, b: a & b, + "|": lambda a, b: a | b, + "^": lambda a, b: a ^ b, + "<<": lambda a, b: a << b, + ">>": lambda a, b: a >> b, +} +if sys.version_info >= (3, 5): + # MatMult is available since Python 3.5+. + BIN_OP_IMPL["@"] = operator_mod.matmul + +for _KEY, _IMPL in list(BIN_OP_IMPL.items()): + BIN_OP_IMPL[_KEY + "="] = _IMPL + + +@decorators.yes_if_nothing_inferred +def const_infer_binary_op(self, opnode, operator, other, context, _): + not_implemented = nodes.Const(NotImplemented) + if isinstance(other, nodes.Const): + try: + impl = BIN_OP_IMPL[operator] + try: + yield nodes.const_factory(impl(self.value, other.value)) + except TypeError: + # ArithmeticError is not enough: float >> float is a TypeError + yield not_implemented + except Exception: # pylint: disable=broad-except + yield util.Uninferable + except TypeError: + yield not_implemented + elif isinstance(self.value, str) and operator == "%": + # TODO(cpopa): implement string interpolation later on. + yield util.Uninferable + else: + yield not_implemented + + +nodes.Const.infer_binary_op = const_infer_binary_op + + +def _multiply_seq_by_int(self, opnode, other, context): + node = self.__class__(parent=opnode) + filtered_elts = ( + helpers.safe_infer(elt, context) or util.Uninferable + for elt in self.elts + if elt is not util.Uninferable + ) + node.elts = list(filtered_elts) * other.value + return node + + +def _filter_uninferable_nodes(elts, context): + for elt in elts: + if elt is util.Uninferable: + yield nodes.Unknown() + else: + for inferred in elt.infer(context): + if inferred is not util.Uninferable: + yield inferred + else: + yield nodes.Unknown() + + +@decorators.yes_if_nothing_inferred +def tl_infer_binary_op(self, opnode, operator, other, context, method): + not_implemented = nodes.Const(NotImplemented) + if isinstance(other, self.__class__) and operator == "+": + node = self.__class__(parent=opnode) + node.elts = list( + itertools.chain( + _filter_uninferable_nodes(self.elts, context), + _filter_uninferable_nodes(other.elts, context), + ) + ) + yield node + elif isinstance(other, nodes.Const) and operator == "*": + if not isinstance(other.value, int): + yield not_implemented + return + yield _multiply_seq_by_int(self, opnode, other, context) + elif isinstance(other, bases.Instance) and operator == "*": + # Verify if the instance supports __index__. + as_index = helpers.class_instance_as_index(other) + if not as_index: + yield util.Uninferable + else: + yield _multiply_seq_by_int(self, opnode, as_index, context) + else: + yield not_implemented + + +nodes.Tuple.infer_binary_op = tl_infer_binary_op +nodes.List.infer_binary_op = tl_infer_binary_op + + +@decorators.yes_if_nothing_inferred +def instance_class_infer_binary_op(self, opnode, operator, other, context, method): + return method.infer_call_result(self, context) + + +bases.Instance.infer_binary_op = instance_class_infer_binary_op +nodes.ClassDef.infer_binary_op = instance_class_infer_binary_op + + +# assignment ################################################################## + +"""the assigned_stmts method is responsible to return the assigned statement +(e.g. not inferred) according to the assignment type. + +The `assign_path` argument is used to record the lhs path of the original node. +For instance if we want assigned statements for 'c' in 'a, (b,c)', assign_path +will be [1, 1] once arrived to the Assign node. + +The `context` argument is the current inference context which should be given +to any intermediary inference necessary. +""" + + +def _resolve_looppart(parts, assign_path, context): + """recursive function to resolve multiple assignments on loops""" + assign_path = assign_path[:] + index = assign_path.pop(0) + for part in parts: + if part is util.Uninferable: + continue + if not hasattr(part, "itered"): + continue + try: + itered = part.itered() + except TypeError: + continue + for stmt in itered: + index_node = nodes.Const(index) + try: + assigned = stmt.getitem(index_node, context) + except ( + AttributeError, + exceptions.AstroidTypeError, + exceptions.AstroidIndexError, + ): + continue + if not assign_path: + # we achieved to resolved the assignment path, + # don't infer the last part + yield assigned + elif assigned is util.Uninferable: + break + else: + # we are not yet on the last part of the path + # search on each possibly inferred value + try: + yield from _resolve_looppart( + assigned.infer(context), assign_path, context + ) + except exceptions.InferenceError: + break + + +@decorators.raise_if_nothing_inferred +def for_assigned_stmts(self, node=None, context=None, assign_path=None): + if isinstance(self, nodes.AsyncFor) or getattr(self, "is_async", False): + # Skip inferring of async code for now + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + if assign_path is None: + for lst in self.iter.infer(context): + if isinstance(lst, (nodes.Tuple, nodes.List)): + yield from lst.elts + else: + yield from _resolve_looppart(self.iter.infer(context), assign_path, context) + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.For.assigned_stmts = for_assigned_stmts +nodes.Comprehension.assigned_stmts = for_assigned_stmts + + +def sequence_assigned_stmts(self, node=None, context=None, assign_path=None): + if assign_path is None: + assign_path = [] + try: + index = self.elts.index(node) + except ValueError as exc: + raise exceptions.InferenceError( + "Tried to retrieve a node {node!r} which does not exist", + node=self, + assign_path=assign_path, + context=context, + ) from exc + + assign_path.insert(0, index) + return self.parent.assigned_stmts( + node=self, context=context, assign_path=assign_path + ) + + +nodes.Tuple.assigned_stmts = sequence_assigned_stmts +nodes.List.assigned_stmts = sequence_assigned_stmts + + +def assend_assigned_stmts(self, node=None, context=None, assign_path=None): + return self.parent.assigned_stmts(node=self, context=context) + + +nodes.AssignName.assigned_stmts = assend_assigned_stmts +nodes.AssignAttr.assigned_stmts = assend_assigned_stmts + + +def _arguments_infer_argname(self, name, context): + # arguments information may be missing, in which case we can't do anything + # more + if not (self.args or self.vararg or self.kwarg): + yield util.Uninferable + return + # first argument of instance/class method + if self.args and getattr(self.args[0], "name", None) == name: + functype = self.parent.type + cls = self.parent.parent.scope() + is_metaclass = isinstance(cls, nodes.ClassDef) and cls.type == "metaclass" + # If this is a metaclass, then the first argument will always + # be the class, not an instance. + if is_metaclass or functype == "classmethod": + yield cls + return + if functype == "method": + yield bases.Instance(cls) + return + + if context and context.callcontext: + call_site = arguments.CallSite(context.callcontext, context.extra_context) + yield from call_site.infer_argument(self.parent, name, context) + return + + if name == self.vararg: + vararg = nodes.const_factory(()) + vararg.parent = self + yield vararg + return + if name == self.kwarg: + kwarg = nodes.const_factory({}) + kwarg.parent = self + yield kwarg + return + # if there is a default value, yield it. And then yield Uninferable to reflect + # we can't guess given argument value + try: + context = contextmod.copy_context(context) + yield from self.default_value(name).infer(context) + yield util.Uninferable + except exceptions.NoDefault: + yield util.Uninferable + + +def arguments_assigned_stmts(self, node=None, context=None, assign_path=None): + if context.callcontext: + # reset call context/name + callcontext = context.callcontext + context = contextmod.copy_context(context) + context.callcontext = None + args = arguments.CallSite(callcontext) + return args.infer_argument(self.parent, node.name, context) + return _arguments_infer_argname(self, node.name, context) + + +nodes.Arguments.assigned_stmts = arguments_assigned_stmts + + +@decorators.raise_if_nothing_inferred +def assign_assigned_stmts(self, node=None, context=None, assign_path=None): + if not assign_path: + yield self.value + return None + yield from _resolve_assignment_parts( + self.value.infer(context), assign_path, context + ) + + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +def assign_annassigned_stmts(self, node=None, context=None, assign_path=None): + for inferred in assign_assigned_stmts(self, node, context, assign_path): + if inferred is None: + yield util.Uninferable + else: + yield inferred + + +nodes.Assign.assigned_stmts = assign_assigned_stmts +nodes.AnnAssign.assigned_stmts = assign_annassigned_stmts +nodes.AugAssign.assigned_stmts = assign_assigned_stmts + + +def _resolve_assignment_parts(parts, assign_path, context): + """recursive function to resolve multiple assignments""" + assign_path = assign_path[:] + index = assign_path.pop(0) + for part in parts: + assigned = None + if isinstance(part, nodes.Dict): + # A dictionary in an iterating context + try: + assigned, _ = part.items[index] + except IndexError: + return + + elif hasattr(part, "getitem"): + index_node = nodes.Const(index) + try: + assigned = part.getitem(index_node, context) + except (exceptions.AstroidTypeError, exceptions.AstroidIndexError): + return + + if not assigned: + return + + if not assign_path: + # we achieved to resolved the assignment path, don't infer the + # last part + yield assigned + elif assigned is util.Uninferable: + return + else: + # we are not yet on the last part of the path search on each + # possibly inferred value + try: + yield from _resolve_assignment_parts( + assigned.infer(context), assign_path, context + ) + except exceptions.InferenceError: + return + + +@decorators.raise_if_nothing_inferred +def excepthandler_assigned_stmts(self, node=None, context=None, assign_path=None): + for assigned in node_classes.unpack_infer(self.type): + if isinstance(assigned, nodes.ClassDef): + assigned = objects.ExceptionInstance(assigned) + + yield assigned + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.ExceptHandler.assigned_stmts = excepthandler_assigned_stmts + + +def _infer_context_manager(self, mgr, context): + inferred = next(mgr.infer(context=context)) + if isinstance(inferred, bases.Generator): + # Check if it is decorated with contextlib.contextmanager. + func = inferred.parent + if not func.decorators: + raise exceptions.InferenceError( + "No decorators found on inferred generator %s", node=func + ) + + for decorator_node in func.decorators.nodes: + decorator = next(decorator_node.infer(context)) + if isinstance(decorator, nodes.FunctionDef): + if decorator.qname() == _CONTEXTLIB_MGR: + break + else: + # It doesn't interest us. + raise exceptions.InferenceError(node=func) + + # Get the first yield point. If it has multiple yields, + # then a RuntimeError will be raised. + + possible_yield_points = func.nodes_of_class(nodes.Yield) + # Ignore yields in nested functions + yield_point = next( + (node for node in possible_yield_points if node.scope() == func), None + ) + if yield_point: + if not yield_point.value: + const = nodes.Const(None) + const.parent = yield_point + const.lineno = yield_point.lineno + yield const + else: + yield from yield_point.value.infer(context=context) + elif isinstance(inferred, bases.Instance): + try: + enter = next(inferred.igetattr("__enter__", context=context)) + except (exceptions.InferenceError, exceptions.AttributeInferenceError): + raise exceptions.InferenceError(node=inferred) + if not isinstance(enter, bases.BoundMethod): + raise exceptions.InferenceError(node=enter) + if not context.callcontext: + context.callcontext = contextmod.CallContext(args=[inferred]) + yield from enter.infer_call_result(self, context) + else: + raise exceptions.InferenceError(node=mgr) + + +@decorators.raise_if_nothing_inferred +def with_assigned_stmts(self, node=None, context=None, assign_path=None): + """Infer names and other nodes from a *with* statement. + + This enables only inference for name binding in a *with* statement. + For instance, in the following code, inferring `func` will return + the `ContextManager` class, not whatever ``__enter__`` returns. + We are doing this intentionally, because we consider that the context + manager result is whatever __enter__ returns and what it is binded + using the ``as`` keyword. + + class ContextManager(object): + def __enter__(self): + return 42 + with ContextManager() as f: + pass + + # ContextManager().infer() will return ContextManager + # f.infer() will return 42. + + Arguments: + self: nodes.With + node: The target of the assignment, `as (a, b)` in `with foo as (a, b)`. + context: Inference context used for caching already inferred objects + assign_path: + A list of indices, where each index specifies what item to fetch from + the inference results. + """ + try: + mgr = next(mgr for (mgr, vars) in self.items if vars == node) + except StopIteration: + return None + if assign_path is None: + yield from _infer_context_manager(self, mgr, context) + else: + for result in _infer_context_manager(self, mgr, context): + # Walk the assign_path and get the item at the final index. + obj = result + for index in assign_path: + if not hasattr(obj, "elts"): + raise exceptions.InferenceError( + "Wrong type ({targets!r}) for {node!r} assignment", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) + try: + obj = obj.elts[index] + except IndexError as exc: + raise exceptions.InferenceError( + "Tried to infer a nonexistent target with index {index} " + "in {node!r}.", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.InferenceError( + "Tried to unpack a non-iterable value " "in {node!r}.", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) from exc + yield obj + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.With.assigned_stmts = with_assigned_stmts + + +@decorators.yes_if_nothing_inferred +def starred_assigned_stmts(self, node=None, context=None, assign_path=None): + """ + Arguments: + self: nodes.Starred + node: a node related to the current underlying Node. + context: Inference context used for caching already inferred objects + assign_path: + A list of indices, where each index specifies what item to fetch from + the inference results. + """ + # pylint: disable=too-many-locals,too-many-branches,too-many-statements + def _determine_starred_iteration_lookups(starred, target, lookups): + # Determine the lookups for the rhs of the iteration + itered = target.itered() + for index, element in enumerate(itered): + if ( + isinstance(element, nodes.Starred) + and element.value.name == starred.value.name + ): + lookups.append((index, len(itered))) + break + if isinstance(element, nodes.Tuple): + lookups.append((index, len(element.itered()))) + _determine_starred_iteration_lookups(starred, element, lookups) + + stmt = self.statement() + if not isinstance(stmt, (nodes.Assign, nodes.For)): + raise exceptions.InferenceError( + "Statement {stmt!r} enclosing {node!r} " "must be an Assign or For node.", + node=self, + stmt=stmt, + unknown=node, + context=context, + ) + + if context is None: + context = contextmod.InferenceContext() + + if isinstance(stmt, nodes.Assign): + value = stmt.value + lhs = stmt.targets[0] + + if sum(1 for _ in lhs.nodes_of_class(nodes.Starred)) > 1: + raise exceptions.InferenceError( + "Too many starred arguments in the " " assignment targets {lhs!r}.", + node=self, + targets=lhs, + unknown=node, + context=context, + ) + + try: + rhs = next(value.infer(context)) + except exceptions.InferenceError: + yield util.Uninferable + return + if rhs is util.Uninferable or not hasattr(rhs, "itered"): + yield util.Uninferable + return + + try: + elts = collections.deque(rhs.itered()) + except TypeError: + yield util.Uninferable + return + + # Unpack iteratively the values from the rhs of the assignment, + # until the find the starred node. What will remain will + # be the list of values which the Starred node will represent + # This is done in two steps, from left to right to remove + # anything before the starred node and from right to left + # to remove anything after the starred node. + + for index, left_node in enumerate(lhs.elts): + if not isinstance(left_node, nodes.Starred): + if not elts: + break + elts.popleft() + continue + lhs_elts = collections.deque(reversed(lhs.elts[index:])) + for right_node in lhs_elts: + if not isinstance(right_node, nodes.Starred): + if not elts: + break + elts.pop() + continue + # We're done + packed = nodes.List( + ctx=Store, parent=self, lineno=lhs.lineno, col_offset=lhs.col_offset + ) + packed.postinit(elts=elts) + yield packed + break + + if isinstance(stmt, nodes.For): + try: + inferred_iterable = next(stmt.iter.infer(context=context)) + except exceptions.InferenceError: + yield util.Uninferable + return + if inferred_iterable is util.Uninferable or not hasattr( + inferred_iterable, "itered" + ): + yield util.Uninferable + return + try: + itered = inferred_iterable.itered() + except TypeError: + yield util.Uninferable + return + + target = stmt.target + + if not isinstance(target, nodes.Tuple): + raise exceptions.InferenceError( + "Could not make sense of this, the target must be a tuple", + context=context, + ) + + lookups = [] + _determine_starred_iteration_lookups(self, target, lookups) + if not lookups: + raise exceptions.InferenceError( + "Could not make sense of this, needs at least a lookup", context=context + ) + + # Make the last lookup a slice, since that what we want for a Starred node + last_element_index, last_element_length = lookups[-1] + is_starred_last = last_element_index == (last_element_length - 1) + + lookup_slice = slice( + last_element_index, + None if is_starred_last else (last_element_length - last_element_index), + ) + lookups[-1] = lookup_slice + + for element in itered: + + # We probably want to infer the potential values *for each* element in an + # iterable, but we can't infer a list of all values, when only a list of + # step values are expected: + # + # for a, *b in [...]: + # b + # + # *b* should now point to just the elements at that particular iteration step, + # which astroid can't know about. + + found_element = None + for lookup in lookups: + if not hasattr(element, "itered"): + break + if not isinstance(lookup, slice): + # Grab just the index, not the whole length + lookup = lookup[0] + try: + itered_inner_element = element.itered() + element = itered_inner_element[lookup] + except IndexError: + break + except TypeError: + # Most likely the itered() call failed, cannot make sense of this + yield util.Uninferable + return + else: + found_element = element + + unpacked = nodes.List( + ctx=Store, parent=self, lineno=self.lineno, col_offset=self.col_offset + ) + unpacked.postinit(elts=found_element or []) + yield unpacked + return + + yield util.Uninferable + + +nodes.Starred.assigned_stmts = starred_assigned_stmts diff --git a/venv/lib/python3.7/site-packages/astroid/raw_building.py b/venv/lib/python3.7/site-packages/astroid/raw_building.py new file mode 100644 index 0000000..7707ea1 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/raw_building.py @@ -0,0 +1,449 @@ +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Ovidiu Sabou +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to create astroid trees from scratch +(build_* functions) or from living object (object_build_* functions) +""" + +import builtins +import inspect +import logging +import os +import sys +import types + +from astroid import bases +from astroid import manager +from astroid import node_classes +from astroid import nodes + + +MANAGER = manager.AstroidManager() +# the keys of CONST_CLS eg python builtin types + +_CONSTANTS = tuple(node_classes.CONST_CLS) +_BUILTINS = vars(builtins) +_LOG = logging.getLogger(__name__) + + +def _io_discrepancy(member): + # _io module names itself `io`: http://bugs.python.org/issue18602 + member_self = getattr(member, "__self__", None) + return ( + member_self + and inspect.ismodule(member_self) + and member_self.__name__ == "_io" + and member.__module__ == "io" + ) + + +def _attach_local_node(parent, node, name): + node.name = name # needed by add_local_node + parent.add_local_node(node) + + +def _add_dunder_class(func, member): + """Add a __class__ member to the given func node, if we can determine it.""" + python_cls = member.__class__ + cls_name = getattr(python_cls, "__name__", None) + if not cls_name: + return + cls_bases = [ancestor.__name__ for ancestor in python_cls.__bases__] + ast_klass = build_class(cls_name, cls_bases, python_cls.__doc__) + func.instance_attrs["__class__"] = [ast_klass] + + +_marker = object() + + +def attach_dummy_node(node, name, runtime_object=_marker): + """create a dummy node and register it in the locals of the given + node with the specified name + """ + enode = nodes.EmptyNode() + enode.object = runtime_object + _attach_local_node(node, enode, name) + + +def _has_underlying_object(self): + return self.object is not None and self.object is not _marker + + +nodes.EmptyNode.has_underlying_object = _has_underlying_object + + +def attach_const_node(node, name, value): + """create a Const node and register it in the locals of the given + node with the specified name + """ + if name not in node.special_attributes: + _attach_local_node(node, nodes.const_factory(value), name) + + +def attach_import_node(node, modname, membername): + """create a ImportFrom node and register it in the locals of the given + node with the specified name + """ + from_node = nodes.ImportFrom(modname, [(membername, None)]) + _attach_local_node(node, from_node, membername) + + +def build_module(name, doc=None): + """create and initialize an astroid Module node""" + node = nodes.Module(name, doc, pure_python=False) + node.package = False + node.parent = None + return node + + +def build_class(name, basenames=(), doc=None): + """create and initialize an astroid ClassDef node""" + node = nodes.ClassDef(name, doc) + for base in basenames: + basenode = nodes.Name() + basenode.name = base + node.bases.append(basenode) + basenode.parent = node + return node + + +def build_function(name, args=None, defaults=None, doc=None): + """create and initialize an astroid FunctionDef node""" + args, defaults = args or [], defaults or [] + # first argument is now a list of decorators + func = nodes.FunctionDef(name, doc) + func.args = argsnode = nodes.Arguments() + argsnode.args = [] + for arg in args: + argsnode.args.append(nodes.Name()) + argsnode.args[-1].name = arg + argsnode.args[-1].parent = argsnode + argsnode.defaults = [] + for default in defaults: + argsnode.defaults.append(nodes.const_factory(default)) + argsnode.defaults[-1].parent = argsnode + argsnode.kwarg = None + argsnode.vararg = None + argsnode.parent = func + if args: + register_arguments(func) + return func + + +def build_from_import(fromname, names): + """create and initialize an astroid ImportFrom import statement""" + return nodes.ImportFrom(fromname, [(name, None) for name in names]) + + +def register_arguments(func, args=None): + """add given arguments to local + + args is a list that may contains nested lists + (i.e. def func(a, (b, c, d)): ...) + """ + if args is None: + args = func.args.args + if func.args.vararg: + func.set_local(func.args.vararg, func.args) + if func.args.kwarg: + func.set_local(func.args.kwarg, func.args) + for arg in args: + if isinstance(arg, nodes.Name): + func.set_local(arg.name, arg) + else: + register_arguments(func, arg.elts) + + +def object_build_class(node, member, localname): + """create astroid for a living class object""" + basenames = [base.__name__ for base in member.__bases__] + return _base_class_object_build(node, member, basenames, localname=localname) + + +def object_build_function(node, member, localname): + """create astroid for a living function object""" + # pylint: disable=deprecated-method; completely removed in 2.0 + args, varargs, varkw, defaults = inspect.getargspec(member) + if varargs is not None: + args.append(varargs) + if varkw is not None: + args.append(varkw) + func = build_function( + getattr(member, "__name__", None) or localname, args, defaults, member.__doc__ + ) + node.add_local_node(func, localname) + + +def object_build_datadescriptor(node, member, name): + """create astroid for a living data descriptor object""" + return _base_class_object_build(node, member, [], name) + + +def object_build_methoddescriptor(node, member, localname): + """create astroid for a living method descriptor object""" + # FIXME get arguments ? + func = build_function( + getattr(member, "__name__", None) or localname, doc=member.__doc__ + ) + # set node's arguments to None to notice that we have no information, not + # and empty argument list + func.args.args = None + node.add_local_node(func, localname) + _add_dunder_class(func, member) + + +def _base_class_object_build(node, member, basenames, name=None, localname=None): + """create astroid for a living class object, with a given set of base names + (e.g. ancestors) + """ + klass = build_class( + name or getattr(member, "__name__", None) or localname, + basenames, + member.__doc__, + ) + klass._newstyle = isinstance(member, type) + node.add_local_node(klass, localname) + try: + # limit the instantiation trick since it's too dangerous + # (such as infinite test execution...) + # this at least resolves common case such as Exception.args, + # OSError.errno + if issubclass(member, Exception): + instdict = member().__dict__ + else: + raise TypeError + except: # pylint: disable=bare-except + pass + else: + for item_name, obj in instdict.items(): + valnode = nodes.EmptyNode() + valnode.object = obj + valnode.parent = klass + valnode.lineno = 1 + klass.instance_attrs[item_name] = [valnode] + return klass + + +def _build_from_function(node, name, member, module): + # verify this is not an imported function + try: + code = member.__code__ + except AttributeError: + # Some implementations don't provide the code object, + # such as Jython. + code = None + filename = getattr(code, "co_filename", None) + if filename is None: + assert isinstance(member, object) + object_build_methoddescriptor(node, member, name) + elif filename != getattr(module, "__file__", None): + attach_dummy_node(node, name, member) + else: + object_build_function(node, member, name) + + +class InspectBuilder: + """class for building nodes from living object + + this is actually a really minimal representation, including only Module, + FunctionDef and ClassDef nodes and some others as guessed. + """ + + def __init__(self): + self._done = {} + self._module = None + + def inspect_build(self, module, modname=None, path=None): + """build astroid from a living module (i.e. using inspect) + this is used when there is no python source code available (either + because it's a built-in module or because the .py is not available) + """ + self._module = module + if modname is None: + modname = module.__name__ + try: + node = build_module(modname, module.__doc__) + except AttributeError: + # in jython, java modules have no __doc__ (see #109562) + node = build_module(modname) + node.file = node.path = os.path.abspath(path) if path else path + node.name = modname + MANAGER.cache_module(node) + node.package = hasattr(module, "__path__") + self._done = {} + self.object_build(node, module) + return node + + def object_build(self, node, obj): + """recursive method which create a partial ast from real objects + (only function, class, and method are handled) + """ + if obj in self._done: + return self._done[obj] + self._done[obj] = node + for name in dir(obj): + try: + member = getattr(obj, name) + except AttributeError: + # damned ExtensionClass.Base, I know you're there ! + attach_dummy_node(node, name) + continue + if inspect.ismethod(member): + member = member.__func__ + if inspect.isfunction(member): + _build_from_function(node, name, member, self._module) + elif inspect.isbuiltin(member): + if not _io_discrepancy(member) and self.imported_member( + node, member, name + ): + continue + object_build_methoddescriptor(node, member, name) + elif inspect.isclass(member): + if self.imported_member(node, member, name): + continue + if member in self._done: + class_node = self._done[member] + if class_node not in node.locals.get(name, ()): + node.add_local_node(class_node, name) + else: + class_node = object_build_class(node, member, name) + # recursion + self.object_build(class_node, member) + if name == "__class__" and class_node.parent is None: + class_node.parent = self._done[self._module] + elif inspect.ismethoddescriptor(member): + assert isinstance(member, object) + object_build_methoddescriptor(node, member, name) + elif inspect.isdatadescriptor(member): + assert isinstance(member, object) + object_build_datadescriptor(node, member, name) + elif isinstance(member, _CONSTANTS): + attach_const_node(node, name, member) + elif inspect.isroutine(member): + # This should be called for Jython, where some builtin + # methods aren't caught by isbuiltin branch. + _build_from_function(node, name, member, self._module) + else: + # create an empty node so that the name is actually defined + attach_dummy_node(node, name, member) + return None + + def imported_member(self, node, member, name): + """verify this is not an imported class or handle it""" + # /!\ some classes like ExtensionClass doesn't have a __module__ + # attribute ! Also, this may trigger an exception on badly built module + # (see http://www.logilab.org/ticket/57299 for instance) + try: + modname = getattr(member, "__module__", None) + except: # pylint: disable=bare-except + _LOG.exception( + "unexpected error while building " "astroid from living object" + ) + modname = None + if modname is None: + if name in ("__new__", "__subclasshook__"): + # Python 2.5.1 (r251:54863, Sep 1 2010, 22:03:14) + # >>> print object.__new__.__module__ + # None + modname = builtins.__name__ + else: + attach_dummy_node(node, name, member) + return True + + real_name = {"gtk": "gtk_gtk", "_io": "io"}.get(modname, modname) + + if real_name != self._module.__name__: + # check if it sounds valid and then add an import node, else use a + # dummy node + try: + getattr(sys.modules[modname], name) + except (KeyError, AttributeError): + attach_dummy_node(node, name, member) + else: + attach_import_node(node, modname, name) + return True + return False + + +### astroid bootstrapping ###################################################### + +_CONST_PROXY = {} + +# TODO : find a nicer way to handle this situation; +def _set_proxied(const): + return _CONST_PROXY[const.value.__class__] + + +def _astroid_bootstrapping(): + """astroid bootstrapping the builtins module""" + # this boot strapping is necessary since we need the Const nodes to + # inspect_build builtins, and then we can proxy Const + builder = InspectBuilder() + astroid_builtin = builder.inspect_build(builtins) + + # pylint: disable=redefined-outer-name + for cls, node_cls in node_classes.CONST_CLS.items(): + if cls is type(None): + proxy = build_class("NoneType") + proxy.parent = astroid_builtin + elif cls is type(NotImplemented): + proxy = build_class("NotImplementedType") + proxy.parent = astroid_builtin + else: + proxy = astroid_builtin.getattr(cls.__name__)[0] + if cls in (dict, list, set, tuple): + node_cls._proxied = proxy + else: + _CONST_PROXY[cls] = proxy + + # Set the builtin module as parent for some builtins. + nodes.Const._proxied = property(_set_proxied) + + _GeneratorType = nodes.ClassDef( + types.GeneratorType.__name__, types.GeneratorType.__doc__ + ) + _GeneratorType.parent = astroid_builtin + bases.Generator._proxied = _GeneratorType + builder.object_build(bases.Generator._proxied, types.GeneratorType) + + if hasattr(types, "AsyncGeneratorType"): + # pylint: disable=no-member; AsyncGeneratorType + _AsyncGeneratorType = nodes.ClassDef( + types.AsyncGeneratorType.__name__, types.AsyncGeneratorType.__doc__ + ) + _AsyncGeneratorType.parent = astroid_builtin + bases.AsyncGenerator._proxied = _AsyncGeneratorType + builder.object_build(bases.AsyncGenerator._proxied, types.AsyncGeneratorType) + builtin_types = ( + types.GetSetDescriptorType, + types.GeneratorType, + types.MemberDescriptorType, + type(None), + type(NotImplemented), + types.FunctionType, + types.MethodType, + types.BuiltinFunctionType, + types.ModuleType, + types.TracebackType, + ) + for _type in builtin_types: + if _type.__name__ not in astroid_builtin: + cls = nodes.ClassDef(_type.__name__, _type.__doc__) + cls.parent = astroid_builtin + builder.object_build(cls, _type) + astroid_builtin[_type.__name__] = cls + + +_astroid_bootstrapping() diff --git a/venv/lib/python3.7/site-packages/astroid/rebuilder.py b/venv/lib/python3.7/site-packages/astroid/rebuilder.py new file mode 100644 index 0000000..1b313ee --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/rebuilder.py @@ -0,0 +1,1066 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013-2018 Claudiu Popa +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 Alexander Presnyakov +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains utilities for rebuilding a _ast tree in +order to get a single Astroid representation +""" + +import sys + +import astroid +from astroid._ast import _parse, _get_parser_module, parse_function_type_comment +from astroid import nodes + + +CONST_NAME_TRANSFORMS = {"None": None, "True": True, "False": False} + +REDIRECT = { + "arguments": "Arguments", + "comprehension": "Comprehension", + "ListCompFor": "Comprehension", + "GenExprFor": "Comprehension", + "excepthandler": "ExceptHandler", + "keyword": "Keyword", +} +PY3 = sys.version_info >= (3, 0) +PY34 = sys.version_info >= (3, 4) +PY37 = sys.version_info >= (3, 7) + + +def _binary_operators_from_module(module): + binary_operators = { + module.Add: "+", + module.BitAnd: "&", + module.BitOr: "|", + module.BitXor: "^", + module.Div: "/", + module.FloorDiv: "//", + module.Mod: "%", + module.Mult: "*", + module.Pow: "**", + module.Sub: "-", + module.LShift: "<<", + module.RShift: ">>", + } + if sys.version_info >= (3, 5): + binary_operators[module.MatMult] = "@" + return binary_operators + + +def _bool_operators_from_module(module): + return {module.And: "and", module.Or: "or"} + + +def _unary_operators_from_module(module): + return {module.UAdd: "+", module.USub: "-", module.Not: "not", module.Invert: "~"} + + +def _compare_operators_from_module(module): + return { + module.Eq: "==", + module.Gt: ">", + module.GtE: ">=", + module.In: "in", + module.Is: "is", + module.IsNot: "is not", + module.Lt: "<", + module.LtE: "<=", + module.NotEq: "!=", + module.NotIn: "not in", + } + + +def _contexts_from_module(module): + return { + module.Load: astroid.Load, + module.Store: astroid.Store, + module.Del: astroid.Del, + module.Param: astroid.Store, + } + + +def _visit_or_none(node, attr, visitor, parent, visit="visit", **kws): + """If the given node has an attribute, visits the attribute, and + otherwise returns None. + + """ + value = getattr(node, attr, None) + if value: + return getattr(visitor, visit)(value, parent, **kws) + + return None + + +class TreeRebuilder: + """Rebuilds the _ast tree to become an Astroid tree""" + + def __init__(self, manager, parse_python_two: bool = False): + self._manager = manager + self._global_names = [] + self._import_from_nodes = [] + self._delayed_assattr = [] + self._visit_meths = {} + + # Configure the right classes for the right module + self._parser_module = _get_parser_module(parse_python_two=parse_python_two) + self._unary_op_classes = _unary_operators_from_module(self._parser_module) + self._cmp_op_classes = _compare_operators_from_module(self._parser_module) + self._bool_op_classes = _bool_operators_from_module(self._parser_module) + self._bin_op_classes = _binary_operators_from_module(self._parser_module) + self._context_classes = _contexts_from_module(self._parser_module) + + def _get_doc(self, node): + try: + if PY37 and hasattr(node, "docstring"): + doc = node.docstring + return node, doc + if ( + node.body + and isinstance(node.body[0], self._parser_module.Expr) + and isinstance(node.body[0].value, self._parser_module.Str) + ): + doc = node.body[0].value.s + node.body = node.body[1:] + return node, doc + except IndexError: + pass # ast built from scratch + return node, None + + def _get_context(self, node): + return self._context_classes.get(type(node.ctx), astroid.Load) + + def visit_module(self, node, modname, modpath, package): + """visit a Module node by returning a fresh instance of it""" + node, doc = self._get_doc(node) + newnode = nodes.Module( + name=modname, + doc=doc, + file=modpath, + path=[modpath], + package=package, + parent=None, + ) + newnode.postinit([self.visit(child, newnode) for child in node.body]) + return newnode + + def visit(self, node, parent): + cls = node.__class__ + if cls in self._visit_meths: + visit_method = self._visit_meths[cls] + else: + cls_name = cls.__name__ + visit_name = "visit_" + REDIRECT.get(cls_name, cls_name).lower() + visit_method = getattr(self, visit_name) + self._visit_meths[cls] = visit_method + return visit_method(node, parent) + + def _save_assignment(self, node, name=None): + """save assignement situation since node.parent is not available yet""" + if self._global_names and node.name in self._global_names[-1]: + node.root().set_local(node.name, node) + else: + node.parent.set_local(node.name, node) + + def visit_arguments(self, node, parent): + """visit an Arguments node by returning a fresh instance of it""" + vararg, kwarg = node.vararg, node.kwarg + if PY34: + newnode = nodes.Arguments( + vararg.arg if vararg else None, kwarg.arg if kwarg else None, parent + ) + else: + newnode = nodes.Arguments(vararg, kwarg, parent) + args = [self.visit(child, newnode) for child in node.args] + defaults = [self.visit(child, newnode) for child in node.defaults] + varargannotation = None + kwargannotation = None + # change added in 82732 (7c5c678e4164), vararg and kwarg + # are instances of `_ast.arg`, not strings + if vararg: + if PY34: + if node.vararg.annotation: + varargannotation = self.visit(node.vararg.annotation, newnode) + vararg = vararg.arg + if kwarg: + if PY34: + if node.kwarg.annotation: + kwargannotation = self.visit(node.kwarg.annotation, newnode) + kwarg = kwarg.arg + if PY3: + kwonlyargs = [self.visit(child, newnode) for child in node.kwonlyargs] + kw_defaults = [ + self.visit(child, newnode) if child else None + for child in node.kw_defaults + ] + annotations = [ + self.visit(arg.annotation, newnode) if arg.annotation else None + for arg in node.args + ] + kwonlyargs_annotations = [ + self.visit(arg.annotation, newnode) if arg.annotation else None + for arg in node.kwonlyargs + ] + else: + kwonlyargs = [] + kw_defaults = [] + annotations = [] + kwonlyargs_annotations = [] + + newnode.postinit( + args=args, + defaults=defaults, + kwonlyargs=kwonlyargs, + kw_defaults=kw_defaults, + annotations=annotations, + kwonlyargs_annotations=kwonlyargs_annotations, + varargannotation=varargannotation, + kwargannotation=kwargannotation, + ) + # save argument names in locals: + if vararg: + newnode.parent.set_local(vararg, newnode) + if kwarg: + newnode.parent.set_local(kwarg, newnode) + return newnode + + def visit_assert(self, node, parent): + """visit a Assert node by returning a fresh instance of it""" + newnode = nodes.Assert(node.lineno, node.col_offset, parent) + if node.msg: + msg = self.visit(node.msg, newnode) + else: + msg = None + newnode.postinit(self.visit(node.test, newnode), msg) + return newnode + + def check_type_comment(self, node): + type_comment = getattr(node, "type_comment", None) + if not type_comment: + return None + + try: + type_comment_ast = _parse(type_comment) + except SyntaxError: + # Invalid type comment, just skip it. + return None + + type_object = self.visit(type_comment_ast.body[0], node) + if not isinstance(type_object, nodes.Expr): + return None + + return type_object.value + + def check_function_type_comment(self, node): + type_comment = getattr(node, "type_comment", None) + if not type_comment: + return None + + try: + type_comment_ast = parse_function_type_comment(type_comment) + except SyntaxError: + # Invalid type comment, just skip it. + return None + + returns = None + argtypes = [ + self.visit(elem, node) for elem in (type_comment_ast.argtypes or []) + ] + if type_comment_ast.returns: + returns = self.visit(type_comment_ast.returns, node) + + return returns, argtypes + + def visit_assign(self, node, parent): + """visit a Assign node by returning a fresh instance of it""" + type_annotation = self.check_type_comment(node) + newnode = nodes.Assign(node.lineno, node.col_offset, parent) + newnode.postinit( + targets=[self.visit(child, newnode) for child in node.targets], + value=self.visit(node.value, newnode), + type_annotation=type_annotation, + ) + return newnode + + def visit_assignname(self, node, parent, node_name=None): + """visit a node and return a AssignName node""" + newnode = nodes.AssignName( + node_name, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + self._save_assignment(newnode) + return newnode + + def visit_augassign(self, node, parent): + """visit a AugAssign node by returning a fresh instance of it""" + newnode = nodes.AugAssign( + self._bin_op_classes[type(node.op)] + "=", + node.lineno, + node.col_offset, + parent, + ) + newnode.postinit( + self.visit(node.target, newnode), self.visit(node.value, newnode) + ) + return newnode + + def visit_repr(self, node, parent): + """visit a Backquote node by returning a fresh instance of it""" + newnode = nodes.Repr(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_binop(self, node, parent): + """visit a BinOp node by returning a fresh instance of it""" + newnode = nodes.BinOp( + self._bin_op_classes[type(node.op)], node.lineno, node.col_offset, parent + ) + newnode.postinit( + self.visit(node.left, newnode), self.visit(node.right, newnode) + ) + return newnode + + def visit_boolop(self, node, parent): + """visit a BoolOp node by returning a fresh instance of it""" + newnode = nodes.BoolOp( + self._bool_op_classes[type(node.op)], node.lineno, node.col_offset, parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.values]) + return newnode + + def visit_break(self, node, parent): + """visit a Break node by returning a fresh instance of it""" + return nodes.Break( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_call(self, node, parent): + """visit a CallFunc node by returning a fresh instance of it""" + newnode = nodes.Call(node.lineno, node.col_offset, parent) + starargs = _visit_or_none(node, "starargs", self, newnode) + kwargs = _visit_or_none(node, "kwargs", self, newnode) + args = [self.visit(child, newnode) for child in node.args] + + if node.keywords: + keywords = [self.visit(child, newnode) for child in node.keywords] + else: + keywords = None + if starargs: + new_starargs = nodes.Starred( + col_offset=starargs.col_offset, + lineno=starargs.lineno, + parent=starargs.parent, + ) + new_starargs.postinit(value=starargs) + args.append(new_starargs) + if kwargs: + new_kwargs = nodes.Keyword( + arg=None, + col_offset=kwargs.col_offset, + lineno=kwargs.lineno, + parent=kwargs.parent, + ) + new_kwargs.postinit(value=kwargs) + if keywords: + keywords.append(new_kwargs) + else: + keywords = [new_kwargs] + + newnode.postinit(self.visit(node.func, newnode), args, keywords) + return newnode + + def visit_classdef(self, node, parent, newstyle=None): + """visit a ClassDef node to become astroid""" + node, doc = self._get_doc(node) + newnode = nodes.ClassDef(node.name, doc, node.lineno, node.col_offset, parent) + metaclass = None + if PY3: + for keyword in node.keywords: + if keyword.arg == "metaclass": + metaclass = self.visit(keyword, newnode).value + break + if node.decorator_list: + decorators = self.visit_decorators(node, newnode) + else: + decorators = None + newnode.postinit( + [self.visit(child, newnode) for child in node.bases], + [self.visit(child, newnode) for child in node.body], + decorators, + newstyle, + metaclass, + [ + self.visit(kwd, newnode) + for kwd in node.keywords + if kwd.arg != "metaclass" + ] + if PY3 + else [], + ) + return newnode + + def visit_const(self, node, parent): + """visit a Const node by returning a fresh instance of it""" + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_continue(self, node, parent): + """visit a Continue node by returning a fresh instance of it""" + return nodes.Continue( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_compare(self, node, parent): + """visit a Compare node by returning a fresh instance of it""" + newnode = nodes.Compare(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.left, newnode), + [ + (self._cmp_op_classes[op.__class__], self.visit(expr, newnode)) + for (op, expr) in zip(node.ops, node.comparators) + ], + ) + return newnode + + def visit_comprehension(self, node, parent): + """visit a Comprehension node by returning a fresh instance of it""" + newnode = nodes.Comprehension(parent) + newnode.postinit( + self.visit(node.target, newnode), + self.visit(node.iter, newnode), + [self.visit(child, newnode) for child in node.ifs], + getattr(node, "is_async", None), + ) + return newnode + + def visit_decorators(self, node, parent): + """visit a Decorators node by returning a fresh instance of it""" + # /!\ node is actually a _ast.FunctionDef node while + # parent is an astroid.nodes.FunctionDef node + newnode = nodes.Decorators(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.decorator_list]) + return newnode + + def visit_delete(self, node, parent): + """visit a Delete node by returning a fresh instance of it""" + newnode = nodes.Delete(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.targets]) + return newnode + + def _visit_dict_items(self, node, parent, newnode): + for key, value in zip(node.keys, node.values): + rebuilt_value = self.visit(value, newnode) + if not key: + # Python 3.5 and extended unpacking + rebuilt_key = nodes.DictUnpack( + rebuilt_value.lineno, rebuilt_value.col_offset, parent + ) + else: + rebuilt_key = self.visit(key, newnode) + yield rebuilt_key, rebuilt_value + + def visit_dict(self, node, parent): + """visit a Dict node by returning a fresh instance of it""" + newnode = nodes.Dict(node.lineno, node.col_offset, parent) + items = list(self._visit_dict_items(node, parent, newnode)) + newnode.postinit(items) + return newnode + + def visit_dictcomp(self, node, parent): + """visit a DictComp node by returning a fresh instance of it""" + newnode = nodes.DictComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.key, newnode), + self.visit(node.value, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_expr(self, node, parent): + """visit a Expr node by returning a fresh instance of it""" + newnode = nodes.Expr(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + # Not used in Python 3.8+. + def visit_ellipsis(self, node, parent): + """visit an Ellipsis node by returning a fresh instance of it""" + return nodes.Ellipsis( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_emptynode(self, node, parent): + """visit an EmptyNode node by returning a fresh instance of it""" + return nodes.EmptyNode( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_excepthandler(self, node, parent): + """visit an ExceptHandler node by returning a fresh instance of it""" + newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent) + # /!\ node.name can be a tuple + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + _visit_or_none(node, "name", self, newnode), + [self.visit(child, newnode) for child in node.body], + ) + return newnode + + def visit_exec(self, node, parent): + """visit an Exec node by returning a fresh instance of it""" + newnode = nodes.Exec(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.body, newnode), + _visit_or_none(node, "globals", self, newnode), + _visit_or_none(node, "locals", self, newnode), + ) + return newnode + + # Not used in Python 3.8+. + def visit_extslice(self, node, parent): + """visit an ExtSlice node by returning a fresh instance of it""" + newnode = nodes.ExtSlice(parent=parent) + newnode.postinit([self.visit(dim, newnode) for dim in node.dims]) + return newnode + + def _visit_for(self, cls, node, parent): + """visit a For node by returning a fresh instance of it""" + newnode = cls(node.lineno, node.col_offset, parent) + type_annotation = self.check_type_comment(node) + newnode.postinit( + target=self.visit(node.target, newnode), + iter=self.visit(node.iter, newnode), + body=[self.visit(child, newnode) for child in node.body], + orelse=[self.visit(child, newnode) for child in node.orelse], + type_annotation=type_annotation, + ) + return newnode + + def visit_for(self, node, parent): + return self._visit_for(nodes.For, node, parent) + + def visit_importfrom(self, node, parent): + """visit an ImportFrom node by returning a fresh instance of it""" + names = [(alias.name, alias.asname) for alias in node.names] + newnode = nodes.ImportFrom( + node.module or "", + names, + node.level or None, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + # store From names to add them to locals after building + self._import_from_nodes.append(newnode) + return newnode + + def _visit_functiondef(self, cls, node, parent): + """visit an FunctionDef node to become astroid""" + self._global_names.append({}) + node, doc = self._get_doc(node) + newnode = cls(node.name, doc, node.lineno, node.col_offset, parent) + if node.decorator_list: + decorators = self.visit_decorators(node, newnode) + else: + decorators = None + if PY3 and node.returns: + returns = self.visit(node.returns, newnode) + else: + returns = None + + type_comment_args = type_comment_returns = None + type_comment_annotation = self.check_function_type_comment(node) + if type_comment_annotation: + type_comment_returns, type_comment_args = type_comment_annotation + newnode.postinit( + args=self.visit(node.args, newnode), + body=[self.visit(child, newnode) for child in node.body], + decorators=decorators, + returns=returns, + type_comment_returns=type_comment_returns, + type_comment_args=type_comment_args, + ) + self._global_names.pop() + return newnode + + def visit_functiondef(self, node, parent): + return self._visit_functiondef(nodes.FunctionDef, node, parent) + + def visit_generatorexp(self, node, parent): + """visit a GeneratorExp node by returning a fresh instance of it""" + newnode = nodes.GeneratorExp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_attribute(self, node, parent): + """visit an Attribute node by returning a fresh instance of it""" + context = self._get_context(node) + if context == astroid.Del: + # FIXME : maybe we should reintroduce and visit_delattr ? + # for instance, deactivating assign_ctx + newnode = nodes.DelAttr(node.attr, node.lineno, node.col_offset, parent) + elif context == astroid.Store: + newnode = nodes.AssignAttr(node.attr, node.lineno, node.col_offset, parent) + # Prohibit a local save if we are in an ExceptHandler. + if not isinstance(parent, astroid.ExceptHandler): + self._delayed_assattr.append(newnode) + else: + newnode = nodes.Attribute(node.attr, node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_global(self, node, parent): + """visit a Global node to become astroid""" + newnode = nodes.Global( + node.names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + if self._global_names: # global at the module level, no effect + for name in node.names: + self._global_names[-1].setdefault(name, []).append(newnode) + return newnode + + def visit_if(self, node, parent): + """visit an If node by returning a fresh instance of it""" + newnode = nodes.If(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_ifexp(self, node, parent): + """visit a IfExp node by returning a fresh instance of it""" + newnode = nodes.IfExp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + self.visit(node.body, newnode), + self.visit(node.orelse, newnode), + ) + return newnode + + def visit_import(self, node, parent): + """visit a Import node by returning a fresh instance of it""" + names = [(alias.name, alias.asname) for alias in node.names] + newnode = nodes.Import( + names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + # save import names in parent's locals: + for (name, asname) in newnode.names: + name = asname or name + parent.set_local(name.split(".")[0], newnode) + return newnode + + # Not used in Python 3.8+. + def visit_index(self, node, parent): + """visit a Index node by returning a fresh instance of it""" + newnode = nodes.Index(parent=parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_keyword(self, node, parent): + """visit a Keyword node by returning a fresh instance of it""" + newnode = nodes.Keyword(node.arg, parent=parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_lambda(self, node, parent): + """visit a Lambda node by returning a fresh instance of it""" + newnode = nodes.Lambda(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.args, newnode), self.visit(node.body, newnode)) + return newnode + + def visit_list(self, node, parent): + """visit a List node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.List( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_listcomp(self, node, parent): + """visit a ListComp node by returning a fresh instance of it""" + newnode = nodes.ListComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_name(self, node, parent): + """visit a Name node by returning a fresh instance of it""" + context = self._get_context(node) + # True and False can be assigned to something in py2x, so we have to + # check first the context. + if context == astroid.Del: + newnode = nodes.DelName(node.id, node.lineno, node.col_offset, parent) + elif context == astroid.Store: + newnode = nodes.AssignName(node.id, node.lineno, node.col_offset, parent) + elif node.id in CONST_NAME_TRANSFORMS: + newnode = nodes.Const( + CONST_NAME_TRANSFORMS[node.id], + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + return newnode + else: + newnode = nodes.Name(node.id, node.lineno, node.col_offset, parent) + # XXX REMOVE me : + if context in (astroid.Del, astroid.Store): # 'Aug' ?? + self._save_assignment(newnode) + return newnode + + def visit_constant(self, node, parent): + """visit a Constant node by returning a fresh instance of Const""" + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + # Not used in Python 3.8+. + def visit_str(self, node, parent): + """visit a String/Bytes node by returning a fresh instance of Const""" + return nodes.Const( + node.s, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + visit_bytes = visit_str + + # Not used in Python 3.8+. + def visit_num(self, node, parent): + """visit a Num node by returning a fresh instance of Const""" + return nodes.Const( + node.n, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_pass(self, node, parent): + """visit a Pass node by returning a fresh instance of it""" + return nodes.Pass(node.lineno, node.col_offset, parent) + + def visit_print(self, node, parent): + """visit a Print node by returning a fresh instance of it""" + newnode = nodes.Print(node.nl, node.lineno, node.col_offset, parent) + newnode.postinit( + _visit_or_none(node, "dest", self, newnode), + [self.visit(child, newnode) for child in node.values], + ) + return newnode + + def visit_raise(self, node, parent): + """visit a Raise node by returning a fresh instance of it""" + newnode = nodes.Raise(node.lineno, node.col_offset, parent) + # pylint: disable=too-many-function-args + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + _visit_or_none(node, "inst", self, newnode), + _visit_or_none(node, "tback", self, newnode), + ) + return newnode + + def visit_return(self, node, parent): + """visit a Return node by returning a fresh instance of it""" + newnode = nodes.Return(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_set(self, node, parent): + """visit a Set node by returning a fresh instance of it""" + newnode = nodes.Set(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_setcomp(self, node, parent): + """visit a SetComp node by returning a fresh instance of it""" + newnode = nodes.SetComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_slice(self, node, parent): + """visit a Slice node by returning a fresh instance of it""" + newnode = nodes.Slice(parent=parent) + newnode.postinit( + _visit_or_none(node, "lower", self, newnode), + _visit_or_none(node, "upper", self, newnode), + _visit_or_none(node, "step", self, newnode), + ) + return newnode + + def visit_subscript(self, node, parent): + """visit a Subscript node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.Subscript( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit( + self.visit(node.value, newnode), self.visit(node.slice, newnode) + ) + return newnode + + def visit_tryexcept(self, node, parent): + """visit a TryExcept node by returning a fresh instance of it""" + newnode = nodes.TryExcept(node.lineno, node.col_offset, parent) + newnode.postinit( + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.handlers], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_tryfinally(self, node, parent): + """visit a TryFinally node by returning a fresh instance of it""" + newnode = nodes.TryFinally(node.lineno, node.col_offset, parent) + newnode.postinit( + [self.visit(child, newnode) for child in node.body], + [self.visit(n, newnode) for n in node.finalbody], + ) + return newnode + + def visit_tuple(self, node, parent): + """visit a Tuple node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.Tuple( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_unaryop(self, node, parent): + """visit a UnaryOp node by returning a fresh instance of it""" + newnode = nodes.UnaryOp( + self._unary_op_classes[node.op.__class__], + node.lineno, + node.col_offset, + parent, + ) + newnode.postinit(self.visit(node.operand, newnode)) + return newnode + + def visit_while(self, node, parent): + """visit a While node by returning a fresh instance of it""" + newnode = nodes.While(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_with(self, node, parent): + newnode = nodes.With(node.lineno, node.col_offset, parent) + expr = self.visit(node.context_expr, newnode) + if node.optional_vars is not None: + optional_vars = self.visit(node.optional_vars, newnode) + else: + optional_vars = None + + type_annotation = self.check_type_comment(node) + newnode.postinit( + items=[(expr, optional_vars)], + body=[self.visit(child, newnode) for child in node.body], + type_annotation=type_annotation, + ) + return newnode + + def visit_yield(self, node, parent): + """visit a Yield node by returning a fresh instance of it""" + newnode = nodes.Yield(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + +class TreeRebuilder3(TreeRebuilder): + """extend and overwrite TreeRebuilder for python3k""" + + def visit_arg(self, node, parent): + """visit an arg node by returning a fresh AssName instance""" + return self.visit_assignname(node, parent, node.arg) + + # Not used in Python 3.8+. + def visit_nameconstant(self, node, parent): + # in Python 3.4 we have NameConstant for True / False / None + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_excepthandler(self, node, parent): + """visit an ExceptHandler node by returning a fresh instance of it""" + newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent) + if node.name: + name = self.visit_assignname(node, newnode, node.name) + else: + name = None + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + name, + [self.visit(child, newnode) for child in node.body], + ) + return newnode + + def visit_nonlocal(self, node, parent): + """visit a Nonlocal node and return a new instance of it""" + return nodes.Nonlocal( + node.names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_raise(self, node, parent): + """visit a Raise node by returning a fresh instance of it""" + newnode = nodes.Raise(node.lineno, node.col_offset, parent) + # no traceback; anyway it is not used in Pylint + newnode.postinit( + _visit_or_none(node, "exc", self, newnode), + _visit_or_none(node, "cause", self, newnode), + ) + return newnode + + def visit_starred(self, node, parent): + """visit a Starred node and return a new instance of it""" + context = self._get_context(node) + newnode = nodes.Starred( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_try(self, node, parent): + # python 3.3 introduce a new Try node replacing + # TryFinally/TryExcept nodes + if node.finalbody: + newnode = nodes.TryFinally(node.lineno, node.col_offset, parent) + if node.handlers: + body = [self.visit_tryexcept(node, newnode)] + else: + body = [self.visit(child, newnode) for child in node.body] + newnode.postinit(body, [self.visit(n, newnode) for n in node.finalbody]) + return newnode + if node.handlers: + return self.visit_tryexcept(node, parent) + return None + + def visit_annassign(self, node, parent): + """visit an AnnAssign node by returning a fresh instance of it""" + newnode = nodes.AnnAssign(node.lineno, node.col_offset, parent) + annotation = _visit_or_none(node, "annotation", self, newnode) + newnode.postinit( + target=self.visit(node.target, newnode), + annotation=annotation, + simple=node.simple, + value=_visit_or_none(node, "value", self, newnode), + ) + return newnode + + def _visit_with(self, cls, node, parent): + if "items" not in node._fields: + # python < 3.3 + return super(TreeRebuilder3, self).visit_with(node, parent) + + newnode = cls(node.lineno, node.col_offset, parent) + + def visit_child(child): + expr = self.visit(child.context_expr, newnode) + var = _visit_or_none(child, "optional_vars", self, newnode) + return expr, var + + type_annotation = self.check_type_comment(node) + newnode.postinit( + items=[visit_child(child) for child in node.items], + body=[self.visit(child, newnode) for child in node.body], + type_annotation=type_annotation, + ) + return newnode + + def visit_with(self, node, parent): + return self._visit_with(nodes.With, node, parent) + + def visit_yieldfrom(self, node, parent): + newnode = nodes.YieldFrom(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_classdef(self, node, parent, newstyle=True): + return super(TreeRebuilder3, self).visit_classdef( + node, parent, newstyle=newstyle + ) + + # Async structs added in Python 3.5 + def visit_asyncfunctiondef(self, node, parent): + return self._visit_functiondef(nodes.AsyncFunctionDef, node, parent) + + def visit_asyncfor(self, node, parent): + return self._visit_for(nodes.AsyncFor, node, parent) + + def visit_await(self, node, parent): + newnode = nodes.Await(node.lineno, node.col_offset, parent) + newnode.postinit(value=self.visit(node.value, newnode)) + return newnode + + def visit_asyncwith(self, node, parent): + return self._visit_with(nodes.AsyncWith, node, parent) + + def visit_joinedstr(self, node, parent): + newnode = nodes.JoinedStr(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.values]) + return newnode + + def visit_formattedvalue(self, node, parent): + newnode = nodes.FormattedValue(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.value, newnode), + node.conversion, + _visit_or_none(node, "format_spec", self, newnode), + ) + return newnode + + +if sys.version_info >= (3, 0): + TreeRebuilder = TreeRebuilder3 diff --git a/venv/lib/python3.7/site-packages/astroid/scoped_nodes.py b/venv/lib/python3.7/site-packages/astroid/scoped_nodes.py new file mode 100644 index 0000000..b94fbe4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/scoped_nodes.py @@ -0,0 +1,2798 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2011, 2013-2015 Google, Inc. +# Copyright (c) 2013-2018 Claudiu Popa +# Copyright (c) 2013 Phil Schaf +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Florian Bruhin +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Rene Zhang +# Copyright (c) 2015 Philip Lorenz +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2017-2018 Bryce Guinta +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Åukasz Rogalski +# Copyright (c) 2017 David Euresti +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Anthony Sottile +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +This module contains the classes for "scoped" node, i.e. which are opening a +new local scope in the language definition : Module, ClassDef, FunctionDef (and +Lambda, GeneratorExp, DictComp and SetComp to some extent). +""" + +import builtins +import sys +import io +import itertools +from typing import Optional, List + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators as decorators_mod +from astroid.interpreter import objectmodel +from astroid.interpreter import dunder_lookup +from astroid import manager +from astroid import mixins +from astroid import node_classes +from astroid import util + + +BUILTINS = builtins.__name__ +ITER_METHODS = ("__iter__", "__getitem__") + + +def _c3_merge(sequences, cls, context): + """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 not candidate: + # Show all the remaining bases, which were considered as + # candidates for the next mro sequence. + raise exceptions.InconsistentMroError( + message="Cannot create a consistent method resolution order " + "for MROs {mros} of class {cls!r}.", + mros=sequences, + cls=cls, + context=context, + ) + + result.append(candidate) + # remove the chosen candidate + for seq in sequences: + if seq[0] == candidate: + del seq[0] + return None + + +def _verify_duplicates_mro(sequences, cls, context): + for sequence in sequences: + names = [(node.lineno, node.qname()) for node in sequence if node.name] + if len(names) != len(set(names)): + raise exceptions.DuplicateBasesError( + message="Duplicates found in MROs {mros} for {cls!r}.", + mros=sequences, + cls=cls, + context=context, + ) + + +def function_to_method(n, klass): + if isinstance(n, FunctionDef): + if n.type == "classmethod": + return bases.BoundMethod(n, klass) + if n.type != "staticmethod": + return bases.UnboundMethod(n) + return n + + +MANAGER = manager.AstroidManager() + + +def builtin_lookup(name): + """lookup a name into the builtin module + return the list of matching statements and the astroid for the builtin + module + """ + builtin_astroid = MANAGER.ast_from_module(builtins) + if name == "__dict__": + return builtin_astroid, () + try: + stmts = builtin_astroid.locals[name] + except KeyError: + stmts = () + return builtin_astroid, stmts + + +# TODO move this Mixin to mixins.py; problem: 'FunctionDef' in _scope_lookup +class LocalsDictNodeNG(node_classes.LookupMixIn, node_classes.NodeNG): + """ this class provides locals handling common to Module, FunctionDef + and ClassDef nodes, including a dict like interface for direct access + to locals information + """ + + # attributes below are set by the builder module or by raw factories + + locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + def qname(self): + """Get the 'qualified' name of the node. + + For example: module.name, module.class.name ... + + :returns: The qualified name. + :rtype: str + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/278 + if self.parent is None: + return self.name + return "%s.%s" % (self.parent.frame().qname(), self.name) + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + return self + + def _scope_lookup(self, node, name, offset=0): + """XXX method for interfacing the scope lookup""" + try: + stmts = node._filter_stmts(self.locals[name], self, offset) + except KeyError: + stmts = () + if stmts: + return self, stmts + if self.parent: # i.e. not Module + # nested scope: if parent scope is a function, that's fine + # else jump to the module + pscope = self.parent.scope() + if not pscope.is_function: + pscope = pscope.root() + return pscope.scope_lookup(node, name) + return builtin_lookup(name) # Module + + def set_local(self, name, stmt): + """Define that the given name is declared in the given statement node. + + .. seealso:: :meth:`scope` + + :param name: The name that is being defined. + :type name: str + + :param stmt: The statement that defines the given name. + :type stmt: NodeNG + """ + # assert not stmt in self.locals.get(name, ()), (self, stmt) + self.locals.setdefault(name, []).append(stmt) + + __setitem__ = set_local + + def _append_node(self, child): + """append a child, linking it in the tree""" + # pylint: disable=no-member; depending by the class + # which uses the current class as a mixin or base class. + # It's rewritten in 2.0, so it makes no sense for now + # to spend development time on it. + self.body.append(child) + child.parent = self + + def add_local_node(self, child_node, name=None): + """Append a child that should alter the locals of this scope node. + + :param child_node: The child node that will alter locals. + :type child_node: NodeNG + + :param name: The name of the local that will be altered by + the given child node. + :type name: str or None + """ + if name != "__class__": + # add __class__ node as a child will cause infinite recursion later! + self._append_node(child_node) + self.set_local(name or child_node.name, child_node) + + def __getitem__(self, item): + """The first node the defines the given local. + + :param item: The name of the locally defined object. + :type item: str + + :raises KeyError: If the name is not defined. + """ + return self.locals[item][0] + + def __iter__(self): + """Iterate over the names of locals defined in this scoped node. + + :returns: The names of the defined locals. + :rtype: iterable(str) + """ + return iter(self.keys()) + + def keys(self): + """The names of locals defined in this scoped node. + + :returns: The names of the defined locals. + :rtype: list(str) + """ + return list(self.locals.keys()) + + def values(self): + """The nodes that define the locals in this scoped node. + + :returns: The nodes that define locals. + :rtype: list(NodeNG) + """ + return [self[key] for key in self.keys()] + + def items(self): + """Get the names of the locals and the node that defines the local. + + :returns: The names of locals and their associated node. + :rtype: list(tuple(str, NodeNG)) + """ + return list(zip(self.keys(), self.values())) + + def __contains__(self, name): + """Check if a local is defined in this scope. + + :param name: The name of the local to check for. + :type name: str + + :returns: True if this node has a local of the given name, + False otherwise. + :rtype: bool + """ + return name in self.locals + + +class Module(LocalsDictNodeNG): + """Class representing an :class:`ast.Module` node. + + >>> node = astroid.extract_node('import astroid') + >>> node + + >>> node.parent + + """ + + _astroid_fields = ("body",) + + fromlineno = 0 + """The first line that this node appears on in the source code. + + :type: int or None + """ + lineno = 0 + """The line that this node appears on in the source code. + + :type: int or None + """ + + # attributes below are set by the builder module or by raw factories + + file = None + """The path to the file that this ast has been extracted from. + + This will be ``None`` when the representation has been built from a + built-in module. + + :type: str or None + """ + file_bytes = None + """The string/bytes that this ast was built from. + + :type: str or bytes or None + """ + file_encoding = None + """The encoding of the source file. + + This is used to get unicode out of a source file. + Python 2 only. + + :type: str or None + """ + name = None + """The name of the module. + + :type: str or None + """ + pure_python = None + """Whether the ast was built from source. + + :type: bool or None + """ + package = None + """Whether the node represents a package or a module. + + :type: bool or None + """ + globals = None + """A map of the name of a global variable to the node defining the global. + + :type: dict(str, NodeNG) + """ + + # Future imports + future_imports = None + """The imports from ``__future__``. + + :type: set(str) or None + """ + special_attributes = objectmodel.ModuleModel() + """The names of special attributes that this module has. + + :type: objectmodel.ModuleModel + """ + + # names of module attributes available through the global scope + scope_attrs = {"__name__", "__doc__", "__file__", "__path__", "__package__"} + """The names of module attributes available through the global scope. + + :type: str(str) + """ + + _other_fields = ( + "name", + "doc", + "file", + "path", + "package", + "pure_python", + "future_imports", + ) + _other_other_fields = ("locals", "globals") + + def __init__( + self, + name, + doc, + file=None, + path: Optional[List[str]] = None, + package=None, + parent=None, + pure_python=True, + ): + """ + :param name: The name of the module. + :type name: str + + :param doc: The module docstring. + :type doc: str + + :param file: The path to the file that this ast has been extracted from. + :type file: str or None + + :param path: + :type path: Optional[List[str]] + + :param package: Whether the node represents a package or a module. + :type package: bool or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + + :param pure_python: Whether the ast was built from source. + :type pure_python: bool or None + """ + self.name = name + self.doc = doc + self.file = file + self.path = path + self.package = package + self.parent = parent + self.pure_python = pure_python + self.locals = self.globals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + self.body = [] + """The contents of the module. + + :type: list(NodeNG) or None + """ + self.future_imports = set() + + # pylint: enable=redefined-builtin + + def postinit(self, body=None): + """Do some setup after initialisation. + + :param body: The contents of the module. + :type body: list(NodeNG) or None + """ + self.body = body + + def _get_stream(self): + if self.file_bytes is not None: + return io.BytesIO(self.file_bytes) + if self.file is not None: + stream = open(self.file, "rb") + return stream + return None + + def stream(self): + """Get a stream to the underlying file or bytes. + + :type: file or io.BytesIO or None + """ + return self._get_stream() + + def block_range(self, lineno): + """Get a range from where this node starts to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to. + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given variable is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name of the variable to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + if name in self.scope_attrs and name not in self.locals: + try: + return self, self.getattr(name) + except exceptions.AttributeInferenceError: + return self, () + return self._scope_lookup(node, name, offset) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.module" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + return "Module" + + def getattr(self, name, context=None, ignore_locals=False): + result = [] + name_in_locals = name in self.locals + + if name in self.special_attributes and not ignore_locals and not name_in_locals: + result = [self.special_attributes.lookup(name)] + elif not ignore_locals and name_in_locals: + result = self.locals[name] + elif self.package: + try: + result = [self.import_module(name, relative_only=True)] + except (exceptions.AstroidBuildingError, SyntaxError) as exc: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) from exc + result = [n for n in result if not isinstance(n, node_classes.DelName)] + if result: + return result + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def igetattr(self, name, context=None): + """Infer the possible values of the given variable. + + :param name: The name of the variable to infer. + :type name: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG) or None + """ + # set lookup name since this is necessary to infer on import nodes for + # instance + context = contextmod.copy_context(context) + context.lookupname = name + try: + return bases._infer_stmts(self.getattr(name, context), context, frame=self) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + def fully_defined(self): + """Check if this module has been build from a .py file. + + If so, the module contains a complete representation, + including the code. + + :returns: True if the module has been built from a .py file. + :rtype: bool + """ + return self.file is not None and self.file.endswith(".py") + + def statement(self): + """The first parent node, including self, marked as statement node. + + :returns: The first parent statement. + :rtype: NodeNG + """ + return self + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + + _absolute_import_activated = True + + def absolute_import_activated(self): + """Whether :pep:`328` absolute import behaviour has been enabled. + + :returns: True if :pep:`328` has been enabled, False otherwise. + :rtype: bool + """ + return self._absolute_import_activated + + def import_module(self, modname, relative_only=False, level=None): + """Get the ast for a given module as if imported from this module. + + :param modname: The name of the module to "import". + :type modname: str + + :param relative_only: Whether to only consider relative imports. + :type relative_only: bool + + :param level: The level of relative import. + :type level: int or None + + :returns: The imported module ast. + :rtype: NodeNG + """ + if relative_only and level is None: + level = 0 + absmodname = self.relative_to_absolute_name(modname, level) + + try: + return MANAGER.ast_from_module_name(absmodname) + except exceptions.AstroidBuildingError: + # we only want to import a sub module or package of this module, + # skip here + if relative_only: + raise + return MANAGER.ast_from_module_name(modname) + + def relative_to_absolute_name(self, modname, level): + """Get the absolute module name for a relative import. + + The relative import can be implicit or explicit. + + :param modname: The module name to convert. + :type modname: str + + :param level: The level of relative import. + :type level: int + + :returns: The absolute module name. + :rtype: str + + :raises TooManyLevelsError: When the relative import refers to a + module too far above this one. + """ + # XXX this returns non sens when called on an absolute import + # like 'pylint.checkers.astroid.utils' + # XXX doesn't return absolute name if self.name isn't absolute name + if self.absolute_import_activated() and level is None: + return modname + if level: + if self.package: + level = level - 1 + if level and self.name.count(".") < level: + raise exceptions.TooManyLevelsError(level=level, name=self.name) + + package_name = self.name.rsplit(".", level)[0] + elif self.package: + package_name = self.name + else: + package_name = self.name.rsplit(".", 1)[0] + + if package_name: + if not modname: + return package_name + return "%s.%s" % (package_name, modname) + return modname + + def wildcard_import_names(self): + """The list of imported names when this module is 'wildcard imported'. + + It doesn't include the '__builtins__' name which is added by the + current CPython implementation of wildcard imports. + + :returns: The list of imported names. + :rtype: list(str) + """ + # We separate the different steps of lookup in try/excepts + # to avoid catching too many Exceptions + default = [name for name in self.keys() if not name.startswith("_")] + try: + all_values = self["__all__"] + except KeyError: + return default + + try: + explicit = next(all_values.assigned_stmts()) + except exceptions.InferenceError: + return default + except AttributeError: + # not an assignment node + # XXX infer? + return default + + # Try our best to detect the exported name. + inferred = [] + try: + explicit = next(explicit.infer()) + except exceptions.InferenceError: + return default + if not isinstance(explicit, (node_classes.Tuple, node_classes.List)): + return default + + str_const = lambda node: ( + isinstance(node, node_classes.Const) and isinstance(node.value, str) + ) + for node in explicit.elts: + if str_const(node): + inferred.append(node.value) + else: + try: + inferred_node = next(node.infer()) + except exceptions.InferenceError: + continue + if str_const(inferred_node): + inferred.append(inferred_node.value) + return inferred + + def public_names(self): + """The list of the names that are publicly available in this module. + + :returns: The list of publc names. + :rtype: list(str) + """ + return [name for name in self.keys() if not name.startswith("_")] + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`Module` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield from self.body + + +class ComprehensionScope(LocalsDictNodeNG): + """Scoping for different types of comprehensions.""" + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self.parent.frame() + + scope_lookup = LocalsDictNodeNG._scope_lookup + + +class GeneratorExp(ComprehensionScope): + """Class representing an :class:`ast.GeneratorExp` node. + + >>> node = astroid.extract_node('(thing for thing in things if thing)') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + _other_other_fields = ("locals",) + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(GeneratorExp, self).__init__(lineno, col_offset, parent) + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`GeneratorExp` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield self.elt + + yield from self.generators + + +class DictComp(ComprehensionScope): + """Class representing an :class:`ast.DictComp` node. + + >>> node = astroid.extract_node('{k:v for k, v in things if k > v}') + >>> node + + """ + + _astroid_fields = ("key", "value", "generators") + _other_other_fields = ("locals",) + key = None + """What produces the keys. + + :type: NodeNG or None + """ + value = None + """What produces the values. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(DictComp, self).__init__(lineno, col_offset, parent) + + def postinit(self, key=None, value=None, generators=None): + """Do some setup after initialisation. + + :param key: What produces the keys. + :type key: NodeNG or None + + :param value: What produces the values. + :type value: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.key = key + self.value = value + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`DictComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.key + yield self.value + + yield from self.generators + + +class SetComp(ComprehensionScope): + """Class representing an :class:`ast.SetComp` node. + + >>> node = astroid.extract_node('{thing for thing in things if thing}') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + _other_other_fields = ("locals",) + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(SetComp, self).__init__(lineno, col_offset, parent) + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`SetComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.elt + + yield from self.generators + + +class _ListComp(node_classes.NodeNG): + """Class representing an :class:`ast.ListComp` node. + + >>> node = astroid.extract_node('[thing for thing in things if thing]') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`ListComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.elt + + yield from self.generators + + +class ListComp(_ListComp, ComprehensionScope): + """Class representing an :class:`ast.ListComp` node. + + >>> node = astroid.extract_node('[thing for thing in things if thing]') + >>> node + + """ + + _other_other_fields = ("locals",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + super(ListComp, self).__init__(lineno, col_offset, parent) + + +def _infer_decorator_callchain(node): + """Detect decorator call chaining and see if the end result is a + static or a classmethod. + """ + if not isinstance(node, FunctionDef): + return None + if not node.parent: + return None + try: + result = next(node.infer_call_result(node.parent)) + except exceptions.InferenceError: + return None + if isinstance(result, bases.Instance): + result = result._proxied + if isinstance(result, ClassDef): + if result.is_subtype_of("%s.classmethod" % BUILTINS): + return "classmethod" + if result.is_subtype_of("%s.staticmethod" % BUILTINS): + return "staticmethod" + return None + + +class Lambda(mixins.FilterStmtsMixin, LocalsDictNodeNG): + """Class representing an :class:`ast.Lambda` node. + + >>> node = astroid.extract_node('lambda arg: arg + 1') + >>> node + l.1 at 0x7f23b2e41518> + """ + + _astroid_fields = ("args", "body") + _other_other_fields = ("locals",) + name = "" + is_lambda = True + + def implicit_parameters(self): + return 0 + + # function's type, 'function' | 'method' | 'staticmethod' | 'classmethod' + @property + def type(self): + """Whether this is a method or function. + + :returns: 'method' if this is a method, 'function' otherwise. + :rtype: str + """ + # pylint: disable=no-member + if self.args.args and self.args.args[0].name == "self": + if isinstance(self.parent.scope(), ClassDef): + return "method" + return "function" + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + self.args = [] + """The arguments that the function takes. + + :type: Arguments or list + """ + + self.body = [] + """The contents of the function body. + + :type: list(NodeNG) + """ + + super(Lambda, self).__init__(lineno, col_offset, parent) + + def postinit(self, args, body): + """Do some setup after initialisation. + + :param args: The arguments that the function takes. + :type args: Arguments + + :param body: The contents of the function body. + :type body: list(NodeNG) + """ + self.args = args + self.body = body + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + if "method" in self.type: + return "%s.instancemethod" % BUILTINS + return "%s.function" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + if "method" in self.type: + return "Method" + return "Function" + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + For a :class:`Lambda` this is always ``True``. + :rtype: bool + """ + return True + + def argnames(self): + """Get the names of each of the arguments. + + :returns: The names of the arguments. + :rtype: list(str) + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + + if self.args.args: # maybe None with builtin functions + names = _rec_get_names(self.args.args) + else: + names = [] + if self.args.vararg: + names.append(self.args.vararg) + if self.args.kwarg: + names.append(self.args.kwarg) + return names + + def infer_call_result(self, caller, context=None): + """Infer what the function returns when called. + + :param caller: Unused + :type caller: object + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + return self.body.infer(context) + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given names is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + + if node in self.args.defaults or node in self.args.kw_defaults: + frame = self.parent.frame() + # line offset to avoid that def func(f=func) resolve the default + # value to the defined function + offset = -1 + else: + # check this is not used in function decorators + frame = self + return frame._scope_lookup(node, name, offset) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`Lambda` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield self.args + yield self.body + + +class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda): + """Class representing an :class:`ast.FunctionDef`. + + >>> node = astroid.extract_node(''' + ... def my_func(arg): + ... return arg + 1 + ... ''') + >>> node + + """ + + _astroid_fields = ("decorators", "args", "returns", "body") + _multi_line_block_fields = ("body",) + returns = None + decorators = None + """The decorators that are applied to this method or function. + + :type: Decorators or None + """ + special_attributes = objectmodel.FunctionModel() + """The names of special attributes that this function has. + + :type: objectmodel.FunctionModel + """ + is_function = True + """Whether this node indicates a function. + + For a :class:`FunctionDef` this is always ``True``. + + :type: bool + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + type_comment_args = None + """ + If present, this will contain the type annotation for arguments + passed by a type comment + """ + type_comment_returns = None + """If present, this will contain the return type annotation, passed by a type comment""" + # attributes below are set by the builder module or by raw factories + _other_fields = ("name", "doc") + _other_other_fields = ( + "locals", + "_type", + "type_comment_returns", + "type_comment_args", + ) + _type = None + + def __init__(self, name=None, doc=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name of the function. + :type name: str or None + + :param doc: The function's docstring. + :type doc: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name of the function. + + :type name: str or None + """ + + self.doc = doc + """The function's docstring. + + :type doc: str or None + """ + + self.instance_attrs = {} + super(FunctionDef, self).__init__(lineno, col_offset, parent) + if parent: + frame = parent.frame() + frame.set_local(name, self) + + # pylint: disable=arguments-differ; different than Lambdas + def postinit( + self, + args, + body, + decorators=None, + returns=None, + type_comment_returns=None, + type_comment_args=None, + ): + """Do some setup after initialisation. + + :param args: The arguments that the function takes. + :type args: Arguments or list + + :param body: The contents of the function body. + :type body: list(NodeNG) + + :param decorators: The decorators that are applied to this + method or function. + :type decorators: Decorators or None + :params type_comment_returns: + The return type annotation passed via a type comment. + :params type_comment_args: + The args type annotation passed via a type comment. + """ + self.args = args + self.body = body + self.decorators = decorators + self.returns = returns + self.type_comment_returns = type_comment_returns + self.type_comment_args = type_comment_args + + if isinstance(self.parent.frame(), ClassDef): + self.set_local("__class__", self.parent.frame()) + + @decorators_mod.cachedproperty + def extra_decorators(self): + """The extra decorators that this function can have. + + Additional decorators are considered when they are used as + assignments, as in ``method = staticmethod(method)``. + The property will return all the callables that are used for + decoration. + + :type: list(NodeNG) + """ + frame = self.parent.frame() + if not isinstance(frame, ClassDef): + return [] + + decorators = [] + for assign in frame._get_assign_nodes(): + if isinstance(assign.value, node_classes.Call) and isinstance( + assign.value.func, node_classes.Name + ): + for assign_node in assign.targets: + if not isinstance(assign_node, node_classes.AssignName): + # Support only `name = callable(name)` + continue + + if assign_node.name != self.name: + # Interested only in the assignment nodes that + # decorates the current method. + continue + try: + meth = frame[self.name] + except KeyError: + continue + else: + # Must be a function and in the same frame as the + # original method. + if ( + isinstance(meth, FunctionDef) + and assign_node.frame() == frame + ): + decorators.append(assign.value) + return decorators + + @decorators_mod.cachedproperty + def type(self): + """The function type for this node. + + Possible values are: method, function, staticmethod, classmethod. + + :type: str + """ + builtin_descriptors = {"classmethod", "staticmethod"} + + for decorator in self.extra_decorators: + if decorator.func.name in builtin_descriptors: + return decorator.func.name + + frame = self.parent.frame() + type_name = "function" + if isinstance(frame, ClassDef): + if self.name == "__new__": + return "classmethod" + if sys.version_info >= (3, 6) and self.name == "__init_subclass__": + return "classmethod" + + type_name = "method" + + if not self.decorators: + return type_name + + for node in self.decorators.nodes: + if isinstance(node, node_classes.Name): + if node.name in builtin_descriptors: + return node.name + + if isinstance(node, node_classes.Call): + # Handle the following case: + # @some_decorator(arg1, arg2) + # def func(...) + # + try: + current = next(node.func.infer()) + except exceptions.InferenceError: + continue + _type = _infer_decorator_callchain(current) + if _type is not None: + return _type + + try: + for inferred in node.infer(): + # Check to see if this returns a static or a class method. + _type = _infer_decorator_callchain(inferred) + if _type is not None: + return _type + + if not isinstance(inferred, ClassDef): + continue + for ancestor in inferred.ancestors(): + if not isinstance(ancestor, ClassDef): + continue + if ancestor.is_subtype_of("%s.classmethod" % BUILTINS): + return "classmethod" + if ancestor.is_subtype_of("%s.staticmethod" % BUILTINS): + return "staticmethod" + except exceptions.InferenceError: + pass + return type_name + + @decorators_mod.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + # lineno is the line number of the first decorator, we want the def + # statement lineno + lineno = self.lineno + if self.decorators is not None: + lineno += sum( + node.tolineno - node.lineno + 1 for node in self.decorators.nodes + ) + + return lineno + + @decorators_mod.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.args.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def getattr(self, name, context=None): + """this method doesn't look in the instance_attrs dictionary since it's + done by an Instance proxy at inference time. + """ + if name in self.instance_attrs: + return self.instance_attrs[name] + if name in self.special_attributes: + return [self.special_attributes.lookup(name)] + raise exceptions.AttributeInferenceError(target=self, attribute=name) + + def igetattr(self, name, context=None): + """Inferred getattr, which returns an iterator of inferred statements.""" + try: + return bases._infer_stmts(self.getattr(name, context), context, frame=self) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + def is_method(self): + """Check if this function node represents a method. + + :returns: True if this is a method, False otherwise. + :rtype: bool + """ + # check we are defined in a ClassDef, because this is usually expected + # (e.g. pylint...) when is_method() return True + return self.type != "function" and isinstance(self.parent.frame(), ClassDef) + + @decorators_mod.cached + def decoratornames(self): + """Get the qualified names of each of the decorators on this function. + + :returns: The names of the decorators. + :rtype: set(str) + """ + result = set() + decoratornodes = [] + if self.decorators is not None: + decoratornodes += self.decorators.nodes + decoratornodes += self.extra_decorators + for decnode in decoratornodes: + try: + for infnode in decnode.infer(): + result.add(infnode.qname()) + except exceptions.InferenceError: + continue + return result + + def is_bound(self): + """Check if the function is bound to an instance or class. + + :returns: True if the function is bound to an instance or class, + False otherwise. + :rtype: bool + """ + return self.type == "classmethod" + + def is_abstract(self, pass_is_abstract=True): + """Check if the method is abstract. + + A method is considered abstract if any of the following is true: + * The only statement is 'raise NotImplementedError' + * The only statement is 'pass' and pass_is_abstract is True + * The method is annotated with abc.astractproperty/abc.abstractmethod + + :returns: True if the method is abstract, False otherwise. + :rtype: bool + """ + if self.decorators: + for node in self.decorators.nodes: + try: + inferred = next(node.infer()) + except exceptions.InferenceError: + continue + if inferred and inferred.qname() in ( + "abc.abstractproperty", + "abc.abstractmethod", + ): + return True + + for child_node in self.body: + if isinstance(child_node, node_classes.Raise): + if child_node.raises_not_implemented(): + return True + return pass_is_abstract and isinstance(child_node, node_classes.Pass) + # empty function is the same as function with a single "pass" statement + if pass_is_abstract: + return True + + def is_generator(self): + """Check if this is a generator function. + + :returns: True is this is a generator function, False otherwise. + :rtype: bool + """ + return next(self._get_yield_nodes_skip_lambdas(), False) + + def infer_call_result(self, caller=None, context=None): + """Infer what the function returns when called. + + :returns: What the function returns. + :rtype: iterable(NodeNG or Uninferable) or None + """ + if self.is_generator(): + if isinstance(self, AsyncFunctionDef): + generator_cls = bases.AsyncGenerator + else: + generator_cls = bases.Generator + result = generator_cls(self) + yield result + return + # This is really a gigantic hack to work around metaclass generators + # that return transient class-generating functions. Pylint's AST structure + # cannot handle a base class object that is only used for calling __new__, + # but does not contribute to the inheritance structure itself. We inject + # a fake class into the hierarchy here for several well-known metaclass + # generators, and filter it out later. + if ( + self.name == "with_metaclass" + and len(self.args.args) == 1 + and self.args.vararg is not None + ): + metaclass = next(caller.args[0].infer(context)) + if isinstance(metaclass, ClassDef): + class_bases = [next(arg.infer(context)) for arg in caller.args[1:]] + new_class = ClassDef(name="temporary_class") + new_class.hide = True + new_class.parent = self + new_class.postinit( + bases=[base for base in class_bases if base != util.Uninferable], + body=[], + decorators=[], + metaclass=metaclass, + ) + yield new_class + return + returns = self._get_return_nodes_skip_functions() + + first_return = next(returns, None) + if not first_return: + raise exceptions.InferenceError("Empty return iterator") + + for returnnode in itertools.chain((first_return,), returns): + if returnnode.value is None: + yield node_classes.Const(None) + else: + try: + yield from returnnode.value.infer(context) + except exceptions.InferenceError: + yield util.Uninferable + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`FunctionDef` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + if self.decorators is not None: + yield self.decorators + + yield self.args + + if self.returns is not None: + yield self.returns + + yield from self.body + + +class AsyncFunctionDef(FunctionDef): + """Class representing an :class:`ast.FunctionDef` node. + + A :class:`AsyncFunctionDef` is an asynchronous function + created with the `async` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + async for thing in things: + print(thing) + ''') + >>> node + + >>> node.body[0] + + """ + + +def _rec_get_names(args, names=None): + """return a list of all argument names""" + if names is None: + names = [] + for arg in args: + if isinstance(arg, node_classes.Tuple): + _rec_get_names(arg.elts, names) + else: + names.append(arg.name) + return names + + +def _is_metaclass(klass, seen=None): + """ Return if the given class can be + used as a metaclass. + """ + if klass.name == "type": + return True + if seen is None: + seen = set() + for base in klass.bases: + try: + for baseobj in base.infer(): + baseobj_name = baseobj.qname() + if baseobj_name in seen: + continue + else: + seen.add(baseobj_name) + if isinstance(baseobj, bases.Instance): + # not abstract + return False + if baseobj is util.Uninferable: + continue + if baseobj is klass: + continue + if not isinstance(baseobj, ClassDef): + continue + if baseobj._type == "metaclass": + return True + if _is_metaclass(baseobj, seen): + return True + except exceptions.InferenceError: + continue + return False + + +def _class_type(klass, ancestors=None): + """return a ClassDef node type to differ metaclass and exception + from 'regular' classes + """ + # XXX we have to store ancestors in case we have an ancestor loop + if klass._type is not None: + return klass._type + if _is_metaclass(klass): + klass._type = "metaclass" + elif klass.name.endswith("Exception"): + klass._type = "exception" + else: + if ancestors is None: + ancestors = set() + klass_name = klass.qname() + if klass_name in ancestors: + # XXX we are in loop ancestors, and have found no type + klass._type = "class" + return "class" + ancestors.add(klass_name) + for base in klass.ancestors(recurs=False): + name = _class_type(base, ancestors) + if name != "class": + if name == "metaclass" and not _is_metaclass(klass): + # don't propagate it if the current class + # can't be a metaclass + continue + klass._type = base.type + break + if klass._type is None: + klass._type = "class" + return klass._type + + +def get_wrapping_class(node): + """Get the class that wraps the given node. + + We consider that a class wraps a node if the class + is a parent for the said node. + + :returns: The class that wraps the given node + :rtype: ClassDef or None + """ + + klass = node.frame() + while klass is not None and not isinstance(klass, ClassDef): + if klass.parent is None: + klass = None + else: + klass = klass.parent.frame() + return klass + + +class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, node_classes.Statement): + """Class representing an :class:`ast.ClassDef` node. + + >>> node = astroid.extract_node(''' + class Thing: + def my_meth(self, arg): + return arg + self.offset + ''') + >>> node + + """ + + # some of the attributes below are set by the builder module or + # by a raw factories + + # a dictionary of class instances attributes + _astroid_fields = ("decorators", "bases", "body") # name + + decorators = None + """The decorators that are applied to this class. + + :type: Decorators or None + """ + special_attributes = objectmodel.ClassModel() + """The names of special attributes that this class has. + + :type: objectmodel.ClassModel + """ + + _type = None + _metaclass_hack = False + hide = False + type = property( + _class_type, + doc=( + "The class type for this node.\n\n" + "Possible values are: class, metaclass, exception.\n\n" + ":type: str" + ), + ) + _other_fields = ("name", "doc") + _other_other_fields = ("locals", "_newstyle") + _newstyle = None + + def __init__(self, name=None, doc=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name of the class. + :type name: str or None + + :param doc: The function's docstring. + :type doc: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.instance_attrs = {} + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + self.keywords = [] + """The keywords given to the class definition. + + This is usually for :pep:`3115` style metaclass declaration. + + :type: list(Keyword) or None + """ + + self.bases = [] + """What the class inherits from. + + :type: list(NodeNG) + """ + + self.body = [] + """The contents of the class body. + + :type: list(NodeNG) + """ + + self.name = name + """The name of the class. + + :type name: str or None + """ + + self.doc = doc + """The class' docstring. + + :type doc: str or None + """ + + super(ClassDef, self).__init__(lineno, col_offset, parent) + if parent is not None: + parent.frame().set_local(name, self) + + for local_name, node in self.implicit_locals(): + self.add_local_node(node, local_name) + + def implicit_parameters(self): + return 1 + + def implicit_locals(self): + """Get implicitly defined class definition locals. + + :returns: the the name and Const pair for each local + :rtype: tuple(tuple(str, node_classes.Const), ...) + """ + locals_ = (("__module__", self.special_attributes.attr___module__),) + if sys.version_info >= (3, 3): + # __qualname__ is defined in PEP3155 + locals_ += (("__qualname__", self.special_attributes.attr___qualname__),) + return locals_ + + # pylint: disable=redefined-outer-name + def postinit( + self, bases, body, decorators, newstyle=None, metaclass=None, keywords=None + ): + """Do some setup after initialisation. + + :param bases: What the class inherits from. + :type bases: list(NodeNG) + + :param body: The contents of the class body. + :type body: list(NodeNG) + + :param decorators: The decorators that are applied to this class. + :type decorators: Decorators or None + + :param newstyle: Whether this is a new style class or not. + :type newstyle: bool or None + + :param metaclass: The metaclass of this class. + :type metaclass: NodeNG or None + + :param keywords: The keywords given to the class definition. + :type keywords: list(Keyword) or None + """ + self.keywords = keywords + self.bases = bases + self.body = body + self.decorators = decorators + if newstyle is not None: + self._newstyle = newstyle + if metaclass is not None: + self._metaclass = metaclass + + def _newstyle_impl(self, context=None): + if context is None: + context = contextmod.InferenceContext() + if self._newstyle is not None: + return self._newstyle + for base in self.ancestors(recurs=False, context=context): + if base._newstyle_impl(context): + self._newstyle = True + break + klass = self.declared_metaclass() + # could be any callable, we'd need to infer the result of klass(name, + # bases, dict). punt if it's not a class node. + if klass is not None and isinstance(klass, ClassDef): + self._newstyle = klass._newstyle_impl(context) + if self._newstyle is None: + self._newstyle = False + return self._newstyle + + _newstyle = None + newstyle = property( + _newstyle_impl, + doc=("Whether this is a new style class or not\n\n" ":type: bool or None"), + ) + + @decorators_mod.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + if self.bases: + return self.bases[-1].tolineno + + return self.fromlineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + if self.newstyle: + return "%s.type" % BUILTINS + return "%s.classobj" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + return "Class" + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + For a :class:`ClassDef` this is always ``True``. + :rtype: bool + """ + return True + + def is_subtype_of(self, type_name, context=None): + """Whether this class is a subtype of the given type. + + :param type_name: The name of the type of check against. + :type type_name: str + + :returns: True if this class is a subtype of the given type, + False otherwise. + :rtype: bool + """ + if self.qname() == type_name: + return True + for anc in self.ancestors(context=context): + if anc.qname() == type_name: + return True + return False + + def _infer_type_call(self, caller, context): + name_node = next(caller.args[0].infer(context)) + if isinstance(name_node, node_classes.Const) and isinstance( + name_node.value, str + ): + name = name_node.value + else: + return util.Uninferable + + result = ClassDef(name, None) + + # Get the bases of the class. + class_bases = next(caller.args[1].infer(context)) + if isinstance(class_bases, (node_classes.Tuple, node_classes.List)): + result.bases = class_bases.itered() + else: + # There is currently no AST node that can represent an 'unknown' + # node (Uninferable is not an AST node), therefore we simply return Uninferable here + # although we know at least the name of the class. + return util.Uninferable + + # Get the members of the class + try: + members = next(caller.args[2].infer(context)) + except exceptions.InferenceError: + members = None + + if members and isinstance(members, node_classes.Dict): + for attr, value in members.items: + if isinstance(attr, node_classes.Const) and isinstance(attr.value, str): + result.locals[attr.value] = [value] + + result.parent = caller.parent + return result + + def infer_call_result(self, caller, context=None): + """infer what a class is returning when called""" + if ( + self.is_subtype_of("%s.type" % (BUILTINS,), context) + and len(caller.args) == 3 + ): + result = self._infer_type_call(caller, context) + yield result + return + + dunder_call = None + try: + metaclass = self.metaclass(context=context) + if metaclass is not None: + dunder_call = next(metaclass.igetattr("__call__", context)) + except exceptions.AttributeInferenceError: + pass + if dunder_call and dunder_call.qname() != "builtins.type.__call__": + context = contextmod.bind_context_to_node(context, self) + yield from dunder_call.infer_call_result(caller, context) + else: + # Call type.__call__ if not set metaclass + # (since type is the default metaclass) + yield bases.Instance(self) + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given name is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + # If the name looks like a builtin name, just try to look + # into the upper scope of this class. We might have a + # decorator that it's poorly named after a builtin object + # inside this class. + lookup_upper_frame = ( + isinstance(node.parent, node_classes.Decorators) + and name in MANAGER.builtins_module + ) + if ( + any(node == base or base.parent_of(node) for base in self.bases) + or lookup_upper_frame + ): + # Handle the case where we have either a name + # in the bases of a class, which exists before + # the actual definition or the case where we have + # a Getattr node, with that name. + # + # name = ... + # class A(name): + # def name(self): ... + # + # import name + # class A(name.Name): + # def name(self): ... + + frame = self.parent.frame() + # line offset to avoid that class A(A) resolve the ancestor to + # the defined class + offset = -1 + else: + frame = self + return frame._scope_lookup(node, name, offset) + + @property + def basenames(self): + """The names of the parent classes + + Names are given in the order they appear in the class definition. + + :type: list(str) + """ + return [bnode.as_string() for bnode in self.bases] + + def ancestors(self, recurs=True, context=None): + """Iterate over the base classes in prefixed depth first order. + + :param recurs: Whether to recurse or return direct ancestors only. + :type recurs: bool + + :returns: The base classes + :rtype: iterable(NodeNG) + """ + # FIXME: should be possible to choose the resolution order + # FIXME: inference make infinite loops possible here + yielded = {self} + if context is None: + context = contextmod.InferenceContext() + if not self.bases and self.qname() != "builtins.object": + yield builtin_lookup("object")[1][0] + return + + for stmt in self.bases: + with context.restore_path(): + try: + for baseobj in stmt.infer(context): + if not isinstance(baseobj, ClassDef): + if isinstance(baseobj, bases.Instance): + baseobj = baseobj._proxied + else: + continue + if not baseobj.hide: + if baseobj in yielded: + continue + yielded.add(baseobj) + yield baseobj + if not recurs: + continue + for grandpa in baseobj.ancestors(recurs=True, context=context): + if grandpa is self: + # This class is the ancestor of itself. + break + if grandpa in yielded: + continue + yielded.add(grandpa) + yield grandpa + except exceptions.InferenceError: + continue + + def local_attr_ancestors(self, name, context=None): + """Iterate over the parents that define the given name. + + :param name: The name to find definitions for. + :type name: str + + :returns: The parents that define the given name. + :rtype: iterable(NodeNG) + """ + # Look up in the mro if we can. This will result in the + # attribute being looked up just as Python does it. + try: + ancestors = self.mro(context)[1:] + except exceptions.MroError: + # Fallback to use ancestors, we can't determine + # a sane MRO. + ancestors = self.ancestors(context=context) + for astroid in ancestors: + if name in astroid: + yield astroid + + def instance_attr_ancestors(self, name, context=None): + """Iterate over the parents that define the given name as an attribute. + + :param name: The name to find definitions for. + :type name: str + + :returns: The parents that define the given name as + an instance attribute. + :rtype: iterable(NodeNG) + """ + for astroid in self.ancestors(context=context): + if name in astroid.instance_attrs: + yield astroid + + def has_base(self, node): + """Whether this class directly inherits from the given node. + + :param node: The node to check for. + :type node: NodeNG + + :returns: True if this class directly inherits from the given node. + :rtype: bool + """ + return node in self.bases + + def local_attr(self, name, context=None): + """Get the list of assign nodes associated to the given name. + + Assignments are looked for in both this class and in parents. + + :returns: The list of assignments to the given name. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If no attribute with this name + can be found in this class or parent classes. + """ + result = [] + if name in self.locals: + result = self.locals[name] + else: + class_node = next(self.local_attr_ancestors(name, context), None) + if class_node: + result = class_node.locals[name] + result = [n for n in result if not isinstance(n, node_classes.DelAttr)] + if result: + return result + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def instance_attr(self, name, context=None): + """Get the list of nodes associated to the given attribute name. + + Assignments are looked for in both this class and in parents. + + :returns: The list of assignments to the given name. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If no attribute with this name + can be found in this class or parent classes. + """ + # Return a copy, so we don't modify self.instance_attrs, + # which could lead to infinite loop. + values = list(self.instance_attrs.get(name, [])) + # get all values from parents + for class_node in self.instance_attr_ancestors(name, context): + values += class_node.instance_attrs[name] + values = [n for n in values if not isinstance(n, node_classes.DelAttr)] + if values: + return values + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def instantiate_class(self): + """Get an :class:`Instance` of the :class:`ClassDef` node. + + :returns: An :class:`Instance` of the :class:`ClassDef` node, + or self if this is not possible. + :rtype: Instance or ClassDef + """ + return bases.Instance(self) + + def getattr(self, name, context=None, class_context=True): + """Get an attribute from this class, using Python's attribute semantic. + + This method doesn't look in the :attr:`instance_attrs` dictionary + since it is done by an :class:`Instance` proxy at inference time. + It may return an :class:`Uninferable` object if + the attribute has not been + found, but a ``__getattr__`` or ``__getattribute__`` method is defined. + If ``class_context`` is given, then it is considered that the + attribute is accessed from a class context, + e.g. ClassDef.attribute, otherwise it might have been accessed + from an instance as well. If ``class_context`` is used in that + case, then a lookup in the implicit metaclass and the explicit + metaclass will be done. + + :param name: The attribute to look for. + :type name: str + + :param class_context: Whether the attribute can be accessed statically. + :type class_context: bool + + :returns: The attribute. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If the attribute cannot be inferred. + """ + values = self.locals.get(name, []) + if name in self.special_attributes and class_context and not values: + result = [self.special_attributes.lookup(name)] + if name == "__bases__": + # Need special treatment, since they are mutable + # and we need to return all the values. + result += values + return result + + # don't modify the list in self.locals! + values = list(values) + for classnode in self.ancestors(recurs=True, context=context): + values += classnode.locals.get(name, []) + + if class_context: + values += self._metaclass_lookup_attribute(name, context) + + if not values: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + return values + + def _metaclass_lookup_attribute(self, name, context): + """Search the given name in the implicit and the explicit metaclass.""" + attrs = set() + implicit_meta = self.implicit_metaclass() + metaclass = self.metaclass() + for cls in {implicit_meta, metaclass}: + if cls and cls != self and isinstance(cls, ClassDef): + cls_attributes = self._get_attribute_from_metaclass(cls, name, context) + attrs.update(set(cls_attributes)) + return attrs + + def _get_attribute_from_metaclass(self, cls, name, context): + try: + attrs = cls.getattr(name, context=context, class_context=True) + except exceptions.AttributeInferenceError: + return + + for attr in bases._infer_stmts(attrs, context, frame=cls): + if not isinstance(attr, FunctionDef): + yield attr + continue + + if bases._is_property(attr): + yield from attr.infer_call_result(self, context) + continue + if attr.type == "classmethod": + # If the method is a classmethod, then it will + # be bound to the metaclass, not to the class + # from where the attribute is retrieved. + # get_wrapping_class could return None, so just + # default to the current class. + frame = get_wrapping_class(attr) or self + yield bases.BoundMethod(attr, frame) + elif attr.type == "staticmethod": + yield attr + else: + yield bases.BoundMethod(attr, self) + + def igetattr(self, name, context=None, class_context=True): + """Infer the possible values of the given variable. + + :param name: The name of the variable to infer. + :type name: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG or Uninferable) + """ + # set lookup name since this is necessary to infer on import nodes for + # instance + context = contextmod.copy_context(context) + context.lookupname = name + try: + attr = self.getattr(name, context, class_context=class_context)[0] + for inferred in bases._infer_stmts([attr], context, frame=self): + # yield Uninferable object instead of descriptors when necessary + if not isinstance(inferred, node_classes.Const) and isinstance( + inferred, bases.Instance + ): + try: + inferred._proxied.getattr("__get__", context) + except exceptions.AttributeInferenceError: + yield inferred + else: + yield util.Uninferable + else: + yield function_to_method(inferred, self) + except exceptions.AttributeInferenceError as error: + if not name.startswith("__") and self.has_dynamic_getattr(context): + # class handle some dynamic attributes, return a Uninferable object + yield util.Uninferable + else: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) + + def has_dynamic_getattr(self, context=None): + """Check if the class has a custom __getattr__ or __getattribute__. + + If any such method is found and it is not from + builtins, nor from an extension module, then the function + will return True. + + :returns: True if the class has a custom + __getattr__ or __getattribute__, False otherwise. + :rtype: bool + """ + + def _valid_getattr(node): + root = node.root() + return root.name != BUILTINS and getattr(root, "pure_python", None) + + try: + return _valid_getattr(self.getattr("__getattr__", context)[0]) + except exceptions.AttributeInferenceError: + # if self.newstyle: XXX cause an infinite recursion error + try: + getattribute = self.getattr("__getattribute__", context)[0] + return _valid_getattr(getattribute) + except exceptions.AttributeInferenceError: + pass + return False + + def getitem(self, index, context=None): + """Return the inference of a subscript. + + This is basically looking up the method in the metaclass and calling it. + + :returns: The inferred value of a subscript to this class. + :rtype: NodeNG + + :raises AstroidTypeError: If this class does not define a + ``__getitem__`` method. + """ + try: + methods = dunder_lookup.lookup(self, "__getitem__") + except exceptions.AttributeInferenceError as exc: + raise exceptions.AstroidTypeError(node=self, context=context) from exc + + method = methods[0] + + # Create a new callcontext for providing index as an argument. + new_context = contextmod.bind_context_to_node(context, self) + new_context.callcontext = contextmod.CallContext(args=[index]) + + try: + return next(method.infer_call_result(self, new_context)) + except exceptions.InferenceError: + return util.Uninferable + + def methods(self): + """Iterate over all of the method defined in this class and its parents. + + :returns: The methods defined on the class. + :rtype: iterable(FunctionDef) + """ + done = {} + for astroid in itertools.chain(iter((self,)), self.ancestors()): + for meth in astroid.mymethods(): + if meth.name in done: + continue + done[meth.name] = None + yield meth + + def mymethods(self): + """Iterate over all of the method defined in this class only. + + :returns: The methods defined on the class. + :rtype: iterable(FunctionDef) + """ + for member in self.values(): + if isinstance(member, FunctionDef): + yield member + + def implicit_metaclass(self): + """Get the implicit metaclass of the current class. + + For newstyle classes, this will return an instance of builtins.type. + For oldstyle classes, it will simply return None, since there's + no implicit metaclass there. + + :returns: The metaclass. + :rtype: builtins.type or None + """ + if self.newstyle: + return builtin_lookup("type")[1][0] + return None + + _metaclass = None + + def declared_metaclass(self, context=None): + """Return the explicit declared metaclass for the current class. + + An explicit declared metaclass is defined + either by passing the ``metaclass`` keyword argument + in the class definition line (Python 3) or (Python 2) by + having a ``__metaclass__`` class attribute, or if there are + no explicit bases but there is a global ``__metaclass__`` variable. + + :returns: The metaclass of this class, + or None if one could not be found. + :rtype: NodeNG or None + """ + for base in self.bases: + try: + for baseobj in base.infer(context=context): + if isinstance(baseobj, ClassDef) and baseobj.hide: + self._metaclass = baseobj._metaclass + self._metaclass_hack = True + break + except exceptions.InferenceError: + pass + + if self._metaclass: + # Expects this from Py3k TreeRebuilder + try: + return next( + node + for node in self._metaclass.infer(context=context) + if node is not util.Uninferable + ) + except (exceptions.InferenceError, StopIteration): + return None + + return None + + def _find_metaclass(self, seen=None, context=None): + if seen is None: + seen = set() + seen.add(self) + + klass = self.declared_metaclass(context=context) + if klass is None: + for parent in self.ancestors(context=context): + if parent not in seen: + klass = parent._find_metaclass(seen) + if klass is not None: + break + return klass + + def metaclass(self, context=None): + """Get the metaclass of this class. + + If this class does not define explicitly a metaclass, + then the first defined metaclass in ancestors will be used + instead. + + :returns: The metaclass of this class. + :rtype: NodeNG or None + """ + return self._find_metaclass(context=context) + + def has_metaclass_hack(self): + return self._metaclass_hack + + def _islots(self): + """ Return an iterator with the inferred slots. """ + if "__slots__" not in self.locals: + return None + for slots in self.igetattr("__slots__"): + # check if __slots__ is a valid type + for meth in ITER_METHODS: + try: + slots.getattr(meth) + break + except exceptions.AttributeInferenceError: + continue + else: + continue + + if isinstance(slots, node_classes.Const): + # a string. Ignore the following checks, + # but yield the node, only if it has a value + if slots.value: + yield slots + continue + if not hasattr(slots, "itered"): + # we can't obtain the values, maybe a .deque? + continue + + if isinstance(slots, node_classes.Dict): + values = [item[0] for item in slots.items] + else: + values = slots.itered() + if values is util.Uninferable: + continue + if not values: + # Stop the iteration, because the class + # has an empty list of slots. + return values + + for elt in values: + try: + for inferred in elt.infer(): + if inferred is util.Uninferable: + continue + if not isinstance( + inferred, node_classes.Const + ) or not isinstance(inferred.value, str): + continue + if not inferred.value: + continue + yield inferred + except exceptions.InferenceError: + continue + + return None + + def _slots(self): + if not self.newstyle: + raise NotImplementedError( + "The concept of slots is undefined for old-style classes." + ) + + slots = self._islots() + try: + first = next(slots) + except StopIteration as exc: + # The class doesn't have a __slots__ definition or empty slots. + if exc.args and exc.args[0] not in ("", None): + return exc.args[0] + return None + return [first] + list(slots) + + # Cached, because inferring them all the time is expensive + @decorators_mod.cached + def slots(self): + """Get all the slots for this node. + + :returns: The names of slots for this class. + If the class doesn't define any slot, through the ``__slots__`` + variable, then this function will return a None. + Also, it will return None in the case the slots were not inferred. + :rtype: list(str) or None + """ + + def grouped_slots(): + # Not interested in object, since it can't have slots. + for cls in self.mro()[:-1]: + try: + cls_slots = cls._slots() + except NotImplementedError: + continue + if cls_slots is not None: + yield from cls_slots + else: + yield None + + if not self.newstyle: + raise NotImplementedError( + "The concept of slots is undefined for old-style classes." + ) + + slots = list(grouped_slots()) + if not all(slot is not None for slot in slots): + return None + + return sorted(slots, key=lambda item: item.value) + + def _inferred_bases(self, context=None): + # Similar with .ancestors, but the difference is when one base is inferred, + # only the first object is wanted. That's because + # we aren't interested in superclasses, as in the following + # example: + # + # class SomeSuperClass(object): pass + # class SomeClass(SomeSuperClass): pass + # class Test(SomeClass): pass + # + # Inferring SomeClass from the Test's bases will give + # us both SomeClass and SomeSuperClass, but we are interested + # only in SomeClass. + + if context is None: + context = contextmod.InferenceContext() + if not self.bases and self.qname() != "builtins.object": + yield builtin_lookup("object")[1][0] + return + + for stmt in self.bases: + try: + baseobj = next(stmt.infer(context=context)) + except exceptions.InferenceError: + continue + if isinstance(baseobj, bases.Instance): + baseobj = baseobj._proxied + if not isinstance(baseobj, ClassDef): + continue + if not baseobj.hide: + yield baseobj + else: + yield from baseobj.bases + + def _compute_mro(self, context=None): + inferred_bases = list(self._inferred_bases(context=context)) + bases_mro = [] + for base in inferred_bases: + if base is self: + continue + + try: + mro = base._compute_mro(context=context) + bases_mro.append(mro) + except NotImplementedError: + # Some classes have in their ancestors both newstyle and + # old style classes. For these we can't retrieve the .mro, + # although in Python it's possible, since the class we are + # currently working is in fact new style. + # So, we fallback to ancestors here. + ancestors = list(base.ancestors(context=context)) + bases_mro.append(ancestors) + + unmerged_mro = [[self]] + bases_mro + [inferred_bases] + _verify_duplicates_mro(unmerged_mro, self, context) + return _c3_merge(unmerged_mro, self, context) + + def mro(self, context=None) -> List["ClassDef"]: + """Get the method resolution order, using C3 linearization. + + :returns: The list of ancestors, sorted by the mro. + :rtype: list(NodeNG) + :raises DuplicateBasesError: Duplicate bases in the same class base + :raises InconsistentMroError: A class' MRO is inconsistent + """ + return self._compute_mro(context=context) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`ClassDef` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + if self.decorators is not None: + yield self.decorators + + yield from self.bases + yield from self.body + + @decorators_mod.cached + def _get_assign_nodes(self): + children_assign_nodes = ( + child_node._get_assign_nodes() for child_node in self.body + ) + return list(itertools.chain.from_iterable(children_assign_nodes)) diff --git a/venv/lib/python3.7/site-packages/astroid/test_utils.py b/venv/lib/python3.7/site-packages/astroid/test_utils.py new file mode 100644 index 0000000..55b7e84 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/test_utils.py @@ -0,0 +1,71 @@ +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Utility functions for test code that uses astroid ASTs as input.""" +import contextlib +import functools +import sys +import warnings + +from astroid import nodes + + +def require_version(minver=None, maxver=None): + """ Compare version of python interpreter to the given one. Skip the test + if older. + """ + + def parse(string, default=None): + string = string or default + try: + return tuple(int(v) for v in string.split(".")) + except ValueError as exc: + raise ValueError( + "{string} is not a correct version : should be X.Y[.Z].".format( + string=string + ) + ) from exc + + def check_require_version(f): + current = sys.version_info[:3] + if parse(minver, "0") < current <= parse(maxver, "4"): + return f + + str_version = ".".join(str(v) for v in sys.version_info) + + @functools.wraps(f) + def new_f(self, *args, **kwargs): + if minver is not None: + self.skipTest( + "Needs Python > %s. Current version is %s." % (minver, str_version) + ) + elif maxver is not None: + self.skipTest( + "Needs Python <= %s. Current version is %s." % (maxver, str_version) + ) + + return new_f + + return check_require_version + + +def get_name_node(start_from, name, index=0): + return [n for n in start_from.nodes_of_class(nodes.Name) if n.name == name][index] + + +@contextlib.contextmanager +def enable_warning(warning): + warnings.simplefilter("always", warning) + try: + yield + finally: + # Reset it to default value, so it will take + # into account the values from the -W flag. + warnings.simplefilter("default", warning) diff --git a/venv/lib/python3.7/site-packages/astroid/transforms.py b/venv/lib/python3.7/site-packages/astroid/transforms.py new file mode 100644 index 0000000..e5506cc --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/transforms.py @@ -0,0 +1,90 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +import collections +from functools import lru_cache + + +class TransformVisitor: + """A visitor for handling transforms. + + The standard approach of using it is to call + :meth:`~visit` with an *astroid* module and the class + will take care of the rest, walking the tree and running the + transforms for each encountered node. + """ + + TRANSFORM_MAX_CACHE_SIZE = 10000 + + def __init__(self): + self.transforms = collections.defaultdict(list) + + @lru_cache(maxsize=TRANSFORM_MAX_CACHE_SIZE) + def _transform(self, node): + """Call matching transforms for the given node if any and return the + transformed node. + """ + cls = node.__class__ + if cls not in self.transforms: + # no transform registered for this class of node + return node + + transforms = self.transforms[cls] + for transform_func, predicate in transforms: + if predicate is None or predicate(node): + ret = transform_func(node) + # if the transformation function returns something, it's + # expected to be a replacement for the node + if ret is not None: + node = ret + if ret.__class__ != cls: + # Can no longer apply the rest of the transforms. + break + return node + + def _visit(self, node): + if hasattr(node, "_astroid_fields"): + for name in node._astroid_fields: + value = getattr(node, name) + visited = self._visit_generic(value) + if visited != value: + setattr(node, name, visited) + return self._transform(node) + + def _visit_generic(self, node): + if isinstance(node, list): + return [self._visit_generic(child) for child in node] + if isinstance(node, tuple): + return tuple(self._visit_generic(child) for child in node) + if not node or isinstance(node, str): + return node + + return self._visit(node) + + def register_transform(self, node_class, transform, predicate=None): + """Register `transform(node)` function to be applied on the given + astroid's `node_class` if `predicate` is None or returns true + when called with the node as argument. + + The transform function may return a value which is then used to + substitute the original node in the tree. + """ + self.transforms[node_class].append((transform, predicate)) + + def unregister_transform(self, node_class, transform, predicate=None): + """Unregister the given transform.""" + self.transforms[node_class].remove((transform, predicate)) + + def visit(self, module): + """Walk the given astroid *tree* and transform each encountered node + + Only the nodes which have transforms registered will actually + be replaced or changed. + """ + module.body = [self._visit(child) for child in module.body] + return self._transform(module) diff --git a/venv/lib/python3.7/site-packages/astroid/util.py b/venv/lib/python3.7/site-packages/astroid/util.py new file mode 100644 index 0000000..3ab7561 --- /dev/null +++ b/venv/lib/python3.7/site-packages/astroid/util.py @@ -0,0 +1,164 @@ +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import warnings +from itertools import islice + +import importlib +import lazy_object_proxy + + +def lazy_descriptor(obj): + class DescriptorProxy(lazy_object_proxy.Proxy): + def __get__(self, instance, owner=None): + return self.__class__.__get__(self, instance) + + return DescriptorProxy(obj) + + +def lazy_import(module_name): + return lazy_object_proxy.Proxy( + lambda: importlib.import_module("." + module_name, "astroid") + ) + + +@object.__new__ +class Uninferable: + """Special inference object, which is returned when inference fails.""" + + def __repr__(self): + return "Uninferable" + + __str__ = __repr__ + + def __getattribute__(self, name): + if name == "next": + raise AttributeError("next method should not be called") + if name.startswith("__") and name.endswith("__"): + return object.__getattribute__(self, name) + if name == "accept": + return object.__getattribute__(self, name) + return self + + def __call__(self, *args, **kwargs): + return self + + def __bool__(self): + return False + + __nonzero__ = __bool__ + + def accept(self, visitor): + func = getattr(visitor, "visit_uninferable") + return func(self) + + +class BadOperationMessage: + """Object which describes a TypeError occurred somewhere in the inference chain + + This is not an exception, but a container object which holds the types and + the error which occurred. + """ + + +class BadUnaryOperationMessage(BadOperationMessage): + """Object which describes operational failures on UnaryOps.""" + + def __init__(self, operand, op, error): + self.operand = operand + self.op = op + self.error = error + + @property + def _object_type_helper(self): + helpers = lazy_import("helpers") + return helpers.object_type + + def _object_type(self, obj): + # pylint: disable=not-callable; can't infer lazy_import + objtype = self._object_type_helper(obj) + if objtype is Uninferable: + return None + + return objtype + + def __str__(self): + if hasattr(self.operand, "name"): + operand_type = self.operand.name + else: + object_type = self._object_type(self.operand) + if hasattr(object_type, "name"): + operand_type = object_type.name + else: + # Just fallback to as_string + operand_type = object_type.as_string() + + msg = "bad operand type for unary {}: {}" + return msg.format(self.op, operand_type) + + +class BadBinaryOperationMessage(BadOperationMessage): + """Object which describes type errors for BinOps.""" + + def __init__(self, left_type, op, right_type): + self.left_type = left_type + self.right_type = right_type + self.op = op + + def __str__(self): + msg = "unsupported operand type(s) for {}: {!r} and {!r}" + return msg.format(self.op, self.left_type.name, self.right_type.name) + + +def _instancecheck(cls, other): + wrapped = cls.__wrapped__ + other_cls = other.__class__ + is_instance_of = wrapped is other_cls or issubclass(other_cls, wrapped) + warnings.warn( + "%r is deprecated and slated for removal in astroid " + "2.0, use %r instead" % (cls.__class__.__name__, wrapped.__name__), + PendingDeprecationWarning, + stacklevel=2, + ) + return is_instance_of + + +def proxy_alias(alias_name, node_type): + """Get a Proxy from the given name to the given node type.""" + proxy = type( + alias_name, + (lazy_object_proxy.Proxy,), + { + "__class__": object.__dict__["__class__"], + "__instancecheck__": _instancecheck, + }, + ) + return proxy(lambda: node_type) + + +def limit_inference(iterator, size): + """Limit inference amount. + + Limit inference amount to help with performance issues with + exponentially exploding possible results. + + :param iterator: Inference generator to limit + :type iterator: Iterator(NodeNG) + + :param size: Maximum mount of nodes yielded plus an + Uninferable at the end if limit reached + :type size: int + + :yields: A possibly modified generator + :rtype param: Iterable + """ + yield from islice(iterator, size) + has_more = next(iterator, False) + if has_more is not False: + yield Uninferable + return diff --git a/venv/lib/python3.7/site-packages/click/__init__.py b/venv/lib/python3.7/site-packages/click/__init__.py new file mode 100644 index 0000000..d3c3366 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/__init__.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +""" +click +~~~~~ + +Click is a simple Python module inspired by the stdlib 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. + +:copyright: © 2014 by the Pallets team. +:license: BSD, see LICENSE.rst 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, \ + DateTime, STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED, FloatRange + +# 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', + 'DateTime', 'STRING', 'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED', + 'FloatRange', + + # 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__ = '7.0' diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a99093966fcd74295dcb73a5f7684d6fc087fcc0 GIT binary patch literal 2676 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%0AW0;nWTcTxzpo#32}B{> z5U-(BI!X%@uOY-$Mnt1dHqJN6;y5l0WhWHWQb&UWb&@QT9g{G!JA9zOxP7PA+up-GLv$ziH zb8;03OUym!Cb0yh>hQmo_VoQsVjbwM%$~MyBk}|9mvBlkptIU%dNj1BCuFVulv|(a zFf#0R3xBtLuW7Ak*B$WRk3KV!fjuM1L0@d`8S8`b)~DL1#)`o++ct>|iXQ1lZ@S`5K_n^O<0RgD+D0}W-vcZ43%H&-RXT_~ zGzU6y33zJ|`9DBAX+};}31C;+pWsVZ+IL@&+Co_b-$+742a<#sGIEp?G|GKYyE42m zQoUn(b(oWsQfd)jwwWl^YsisRB;KRsC>ec)R~>2?ORY)`QCo-mew}hMrX;;mfdgy} zA!pJ_@&wlQ>UClbQfM+X=T&3HEF`evHYKkjar3bcbDDc%huqd!+@UYzWl9r78vRn} zQ(K*7z-zupU&(ekH0YE*9qabr zq`eG;+X6AY(#pb>&hiYk2vRe|NAeleCLZHG?vcSk1W?Q$K{02E5a!aHJkpbg+wHtO zwN|k=5*8^tVi>t4C=8O8)TqU276;>j!1=q0@M@a7L*a*8LcqDDRS;x+^lqO!2AK>S z+&^+?nc5W@1VSv8?uUDvT0!Dh6+XKlO$T|cqq%+j-v$-s(O?464$!dy_QM#%-7?OD z#W94g`XKqCOYX)3GEH+I1}bD{8f$NW^v5|)hd54$5_pxQP7um7X|;F;fee$|8%BH` z_bkfJ;dp^mj(mDVAqxkqIWR}SZHS8R=G2`IHwB$;q!t~AEV)h_pT2u|PJ=QO!zN*s z%O=l0m7D~wB~wvB#Uc~)RR04c zse!|&Oaqa&SPnwUF?=qy;ot({OA|pxu!M{nWXQ3Jm1hIF3q!=t$t_bcguy%2I;=GX z31SREp=UuHCgbS!AoK;PeKlQ*SSxmsd~l5(Z&5;~tt177tDn*%4ZdgAhX8TjsMdHR y^sf`a$HX}fWY~cu55c4uG7L-}Xfdn_>jlfmnNH5R=s3=}Glpx}Ips_{qyGaSWnW?d literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/_compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8ee00b05921787c9771426b1117a15ad868c9c9 GIT binary patch literal 16803 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 HuUrQa9z$Zb22Q00H8V3l&9HVdQvbvre3ecgESx zM$T!=|B<~Qap4b|D;M_8i3_}!WFb-+Yo6b{Uw;1HXMcYCb`x;@@ynmDe+vM9r^C&{ zGrYj<9->g7SOE#$dBG+;;S9b8B~AfEzkL-em1KIQsvT;0HnNjmp;23DtISxn7Po=>fEKB6X#@}iuU z-8~;TT^##&tUlA$X(h9hnHf7DXEQ5{+-ToeYufnmJXh6;Z@Mzgv@G;-<%1%1RU)!k z<%QMmSFjyy;IHFeY4fwR(!I0P_Kv58!rHy^ajzIXtE$B(Po9q5@aW_6qB=U2$_}1A z#x*p(m%TDCALYhXX;C~X7xTfBd1`uDk!Rzrlr*_>1p2VN@OR}&YE*&E+`L|cpr#&x zwRyy1*21faSHKqU@671%t;~#57A~4tjGK7jzCwX>f+eSEEk%v)5!CDmI7sy1iEU48 z(Nyp~FnER2s4*V>7%$lmo9VEAm-}{Z@+waYnH!}|RVGcuta_zZ6cBm zqKB^CtmHn~-pX8KzY+JSLJN_y>9#Cc+#M8vutcnl7iUe>7YDnr?56ySNQ7C$={1kP zMP-P1%s)jovlY97OZFxF`0zDfie-Q(5wr1=8wd6fPXbST71UuJ?5~-6+ChBy3awZ4 zS&F_T&U)7DMt)D5*+g3;4zaArD}`E%tYz*op6V8$OoOq!TTrZ%R3tsu|Kw z`j(WZv$WWF?7Q?x;*mWd@ga%-+E{Be2TOk$0@M+*F^^lV*4l<2ZA|Y&{PxZ5Z>q=# Xo0^pMf8~7qeACZogrr;Zm$k${Zp&Dg literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/_unicodefun.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/_unicodefun.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90273feb5df03bac169b59d8952ff05cd9a87a81 GIT binary patch literal 3340 zcma)9OOM;e9p{h~MRC{b_xh1EAdJSv7G5b$ntE#_g`KV4x-i^D?AEo=hM+hji4sL} zXNJ34LAqpn4UlsWg#-izdTu{J&i)9z_R^f&Q%?EKklMJ(rPOjb^Pidj`?VjPJLegA z{{6TA{&Dl7Vf;%i)=vYI`*_9gF;Ih&#OPLE(j|Irc1>zhE3qba*CqxdqXu)9O=?qf zWm4k?eqEO~sPku|+oDbC;_J~C_3+)Gx3l0a{?N`IIZ(%2qI7vd_Z_ zL6Bk*1f?-^q9l&S?VZii3xa+j3$EbJVJJc=d1;9g!Id)0RzDadSuadPX#rj72^n%J zj$=72oqo^@qp|u%8D*s#WkEj)2co=Cq_F}8Nh}#xm(NAnB##ru^@$yey9&G2=abTk z>GbagzY4(D!%oiQqfoNWQOG;}ETN2xPX10O8SP0q`}zAn8;il+pX4X;kb(hwy9IJ+rz}@R`-`V<8RhNis6|7BygP>l7X^hkeF``w9ZDFcW*y zSP){&iFBxSO0aK#W)e6otk|fm2oJN5L!O3j!KVAlXg+0D7 z-&)p>CwazY+xMRjW8vd($ikyIIq_*MqO9QI0Qh<=3KhOs`catraVmL6i-`H6=*fin zy<&j7seghCzA`WHz03+<46`Dk*b$P2RI|jUId}!4;?^yH?F4>5iIhbW zf*gXZF*la>%2*+BEyxQay>1)Q8GHN#VyGXo33+Lx<{#iy)EZm-Hwpu_7p82E8niJs zKPUVPjn7?JCqJB9qZV~&b6{fTsh7H+S<8);LCqV+!mcT7g2G>G3ay1*QIO~0)eY(` z9Jw{O<@r;Se>u087pO%yR_4N<-pA_V%J`-6r=KpG^XBr>N=L!+^2%6Vp_|BUujY;A z)j6a=6c`Fl&y5}aif%2O!&fg1y~>ut;~(aXzi zd2QY}B`dORC^#hxclv9{eSLX@URjZPc6CMiCV0A|A`*D!73GSfYQ1oEthTWF9x6e%{V2W5}kdo&pv#Z3glCPpbVvsOqL$SJWD4ml`8fI zSw?j%tiu4VexRM$f3IC9??x!1IOa|GL)pkP5l>4e$)Ye}GjliGF-u2CniW!i8R!4O zLE}-`DjEQzq@4ICL}_C%#dX`J1kk=cCBxXfw}Se1ujAqwQR6Ce2sxN9~%)SVSmegf`h|M0xJsHi%i?FaqBZ572z zKoo|sX0O8S^@_@^YvtGWfh;HjX(oNmWsz$}RWYgSiiau9-~{Rnn?eP(6lZj5gs|hS zx5X{g8-$DWuv9l{-7q@)vSRr-P7;_EcJuoMhgWc5Wl^C^$GVoShSlQ^ENCwKFulhGnplHh^ zP62DE(wvtK!~x@_i-@XvJ}acOv`1N-BJ)7?jF!z>ReV#4v-xq6%6P&w$(@##vFr3j z08z>Yn@S$?U3JjpN8L@83WM5ZyB^xlAPQ8vDs9C^*HcBe+Wv0Ay&S+>=H_a_T)fw!XE{Zd5*?Mf6#I!Eq z-dnh#T0qqb0%p6W+TkC8&dw&kgAZ5#lJFm4D4XboCwVBV?xQ(D2ZfZu9ku6htzoV@ qOWkki20$ZvO+3{IbKO+9A5_kRTR(^kadXit5N< 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�gjUfpq~mYYMhS;3;W-#R5q)?)_AV0B;9&6 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 CPR{HA literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/decorators.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/decorators.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ff4d5f6ff905fe3c51febcc0696b3f1497659fc GIT binary patch literal 11604 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 z zX!=EUEb<+c z&7RpaaUnd*s<)JVdIKy_k_sE+G+=f3uTY(-)@s+P&(<#2W>7v=Jy*R_JzHC;KKK8U C$_gg{ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/exceptions.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6d0238a2b6ac8568439bab559044b48364805c9 GIT binary patch literal 8630 zcmbtZOOPE`dG6PJ%++XgHIhdUgK30?Js{604#tWwW{fZ?r^rNw4FwlcS3TW5Gd=3t zeRaC8G;`~Ujl2XFUbB!$Dpe^cR#X;Qv0(>`RI=*If+|?V*<_OyE57eP-F+XUp@iMH z&bfU~_j&z~?|<}HPoM4>xc=u~{{Q>`_esO}JsZ{K;ARUY`wgnV2+Y_Rm_2h~^{j#2 zvrYC{u`_7&8o0Lu=Y6Bs{97Yv1kLx2pc%Fv*}XQ}t)Pu|J8Yx9g!WR>Y_N*PlcfwgW4$-$(D)j7R1Z^IhCw zS!a7}yPIx3kAJlwqRsmol?SYy-aHi*! z!rIWH+G}bN?X|+Tx)HW|OAt|rY_A1Tq;Q(OPS61#R*IEdq|VzFS;jZsO5B=AZocp3 zuDs#;UgGY1Nf3uFYB$?YAGmpnH$r!mg=#}lhJ2Ec7dKlA)O9o_=0htt)a8j47*A)pqig|5e$2Ky!5tGsk-T2&4^?KyLDS}E=4U;7f`KR znhT`!A}bsU?^Qe~^{s6-&GESfitrsW^%SK{u(V%v`u#x~jN%Xyx7_dF8+md01T+p( zAKgpgAq0|wDncfE5gKSAKGpA!l8BG{eRX+$Zvucs2Sw35#r=`4ZPT$GtKDwfZ5x7W zwQYIs<57K)Ra+?8%czcFLpyMS26Vmw6aX^dt{K>1W2fkRi%KKZ^ga)%hVldNLX~*& zA_`>D9(ps^gSumk3p0|c4cC2dKg!(vXcz$?hE~>m`AXm zls$p84jlF!Gy?mQv1_dvGRBrMhw`Kegm3Zgar=o8I1_u#xPaAQ2O2-JO(SmwO{n>j zR`aS?6uq@w7~{3~)R7Bc0lI$01u(k%VLaUEe26U@W4i+cuoQK?X!vQIs#$30Xh@)< z_rwF@(7qNPp<-{jBrVD%|h|S8k(&41|256M7jGi_fYw8*RW9J z@5?;(ZunM|t(UO1vEkl_D~bucAP9q-H{Dk^uFoNw4Agiwog>{j2>m~UPXeLvuVm>8 zne_io=*Ho0PHJ8gzw7u31?qSF-C>$#(M}xBp{Z<9T-=+&D+PqsFiJ55 z1BM{%lr=7mUCE!PtRg$6n}|&d2xF`li#5rk`ypw5M^?N;Q1!hm)J&T{v9!Q)6}tW? z0}{LUy*LU4dg*nJ;sDlUI1Cf)bLx5AkQ#<=k zBJ3j*MImLh? z*pAt?fVI~6`8jfEIH){wY63E)BHA)G^mhyv2- zuH1`o3)G*aw(ns?5bk=TnCL5Dod6MV3eHuJ*R#?joHP+%-vjm}74iTxzD+pM@(6qa z%-p&2Qa$BMckWy}X)?U0od>)`3Zq>S89fyQP%L=ypIL=lC>d?|6at|B&J$#qCJn+s z1pu~4j0S)*b3m#=B2NT>O-wr@krF#lRFAkOT|C2DHOH40rRX>g%;D9)V;r=29tU2a z_6ssB;sC;RL~D*l0KC4LG-j{+{zF5#zFh>69175a3+rWU}CEu zPi&xzbHR8W4rPMghsbhFfG+B%fz4df@So{Qs-Fku@E1X2Vh?{AIJ<&H>rLdOz~*tK zJir|NL#pa(rap_)73RizX9_mz74&I@A-E`#wRc8jLPT4fK?!sVhb-xxBRCDTZr1Qo z0<}OAXDDnW9(qft`iM@Hx5y~M$q!I6MhjD%LMFm$!armU+!B9r#d0hQ9^(pn#-BRI z&IKH60LMNel5Joo1MW#Y$BrPGqu4u#WHcFDeC^pi$L;i8Slxe+$Zfp42w`y6!oiSc z6;48(Wvb9jvQR+^D5(GpL3Z}%L5g>)+U!#r8$?!$)7ssN;wX>8tg_)>z`{CT!dOiUoLCX5YVG|eQdW}K zRvQ6=w&Sz(JFdTE2q(G4p*>X4Cu0v5nR=ye=hQn`=)k;dsaGeG&1DaRwl(94X&T83 z&|rB7I?Cs8{U0~rt$;dw9yHOCyzhEzTT*@F?$-dLN9hP5JAA&Y*;mv{Sa`hl^6k>q zEGeaJ``EhXjxE;(oQV}D1qvHk>Y^#mTu?MKWDUYV(QKCiZ{h5~r&U6&1wv7Keuh$7 zc}7+%<{GU0d2{^y9I+O(<0D)7zs71m;fkUg4bhF3Vy}-@iN~l{?XJrUU-1n!Me1EXAIWC_-KA>#fq!6CoP^ z=M-AOw2G6@E<@Fbk1s{y@z04+H8*$jEJE}}IGY;BsZ_l9U&mEUj!vB_GQVQGHI1d7 zDRuT+%v2@gFD;Vv<1qV6nE2P6oKo9vg4yhOII6u>n zv8j2OWAZ!)Jx$=!sR7>Ugw z{A9^Y^77Ou>T@I1@1kAZReJX(U#7pKzRYT>AGPuOFZ7pRWoY~ye3L;KyILQ)=7tZn zl#Bn|gdB_ho5ZEGfMywo!g^o6C5Z!)hIG-iD#K1oZ-!>+gl`x$Hvf%M$;id&b{4D) z@Zh6FkZ)k}|KI|o2u^Kv+KPQXN`3L5TPPV1IcHgDPwb-c7W3}oFTXXD#MfE-n83R5 zRjx2^AF3H+&Y=c!#OFK?kHHEUTU?0EZhAdQVQ?Wg_W3pun<+v@x2Z+)ZHn8_r z;k=E{CgUGs>kHeQ4I}X_l7cv{inawoNQstA5b*HG#pd0XM6oz(ZW}#0TSEt;Yq70wZFhu)hN#NmoiF{I>(Bi zoHS}OZy_$f_%>pl1hqsUi{)>Qk~|t{{1J}Jf-|aI%SX|ELw_xMlaebb@bl)f-EMZ> S?hD-)yPMt1-80=~6z5MbU$)u+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/formatting.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/formatting.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d738271f788bfb31c8f42a2aee377cc48d5bc91 GIT binary patch literal 8566 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 TKijrk*L83S{N05=5tsfOC60&B literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/globals.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/globals.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc0ac3fdbd1c5eb9d9b5d900b91ed44d3344a090 GIT binary patch literal 1897 zcmZuy&yO256t-uQY&M%+M4=TNkW2+CL2a@iEnOmnfQm|ciO@C&SRp0O*vWX~j0fA3 zO`>q=_R9azy&xg}qq%aSoH=oUXU|N#i)twz`}z63&)@rzZ}#_F2*#hk{{7=$b%g$K zn`(rx_zHfe4--QSOSHge7$c4^(OJOSEM&E3_$*{~)_8`_YHWu!;ag|>ti|@=q``Kd zpw7VyxQ{wGuS*qC`8dLE55s+T;r9rB<`|~+fkhTGd>OFdUGxOikPU1&4dyNVDF$_n zw#amCjfI!^DgFT^!S{&Oz(t)t4G=ozHq(hAHs&PCwC0H=krdIKL@Kd-WxIq7V_`@{ z6Efi>Gn^4>2qhPEO{{7W7&MBw`JavAHc^vv9$7NgYC&kSzKFTzl}WHl$wFyP#3BWs z!WPz~g%(sDudP4W(Kvs1|bVP){>S zrb?5T%am(FOcurNA*E>^#cE70Vgb^Hn8g+z>x~FtL33l_*&-oPOp}>NW<*#68Zli8 zusNZQ6>xlm#gf04H#1Zu%}o3{jr*j(;5P1$AC)&uq*6Y<&Um*l((RHZV23AC#yIQu z$x-*PIO?ZV(*-d?LInH305RM;`o=?@fiZ_n`&g4Dl^IZO$atU*aN0X*7TF zFO1FmLzf^996+KFO~`?p={V@r^PL&D)LNZ4M!r1qgRfyHCYdcP=dF{3@s;4owVTh6KAW4_!%xz+efZOe>B;dS zj9Jnf_EM2P5D9>n@3Oi_JdY{4GE{D(kDt;2l@OzLmTY-~)UM z*Rb9P*^OGSfxy@LJFu|m96t{jo}sJYdALPa7$X)yEr*+rzk}@JuAmZrQ3bOqpQ^Au z(On&asX?cv8}QAWqY)F49gXr9WK0>?yg}2HCk*HcBfIiU6;s>YX}eUep79As+35+@dh3Rcr4_9(6J;E8}GWx_;*R zioIvb;)ESEG1p``yH6C5pf6lWc@?SD+$p4r7F5r!}bS*VFzoMT%EutRbKa4 zV0RmY`b{@^?p_gi8`_+bOAaIg>QVWid!SilX}t*<+QLn&?>M{oaR(1NJNd4SHKz=k sqITpKp>lcbvq3xh{e^4pUioZ(u~00N{7d)0=H0ZzM%cR3tT*fb0noA#3IG5A literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/parser.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ba6ce5556bbd5093638a32d3c7d18f51437c5b0 GIT binary patch literal 11474 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 acRsG1!oBO2x#~&$eXjacu~2=YQu;r>NQnvn literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/testing.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/testing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0124e7b84c335d8e944dea2a1d8067c0f009bc10 GIT binary patch literal 11639 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/types.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/types.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..020cf3202caf0a5ebbf2f3324bcd70e0f98fbc6a GIT binary patch literal 21817 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 QIe*TsyjsNWVfoAbALr&;Hvj+t literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/__pycache__/utils.cpython-37.pyc b/venv/lib/python3.7/site-packages/click/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96f6d87dacefbade374bf3f233cdada426c00d7c GIT binary patch literal 15262 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 z zd?t*CP9=Dlm`D!kpx$KgU0xYk<_!i?&7nZt26tg{-QV*!{xi%9ZRW zfNNj9v9f&q?e;r2zIAPP27|STKs~P5Y4@REvYN4wb;9K(kS6cH%s<(pIpORrTKXYeg~oINlG{fEtlu9_v|ZL`JsxcK~Jk zNpYK4Q+Uc&Kf(JBJLMlnx8J}wxqxO|VubP{{9%`r7oosN%8OWE&U*4XwAD;@;-=R@ z!fu&i{oDGlI=sII2&=RuOyM2FBG^8XNikR`McR(c#N$FSed4~U;;kUM8JdtPLnJJ* zw|Md+0U$sAm0!lzgds8N`h!JHuEb(z4$AKE|*4*9oFLQl!&5G4rP(IWo3$m?Bt z`>GJ5i6$HOVj{V?z$#N1_dC;z0d^BCDHfD@w5Ov(Kt)8E20tF*qyeyd3+yVEE=_+F zyhbP>=&_aoj*DSH4HB6do-}F-U??$JeNiw(*6P4If~-L(UiP%FSd*BgTt!G$a3IqW z510TJBO%smhLzDFLS!Zm2C;WPWR!|bH02VI4#ZwMtO(5f-HxA^WBm-B_tByh=ll(6 zkTanQ?1_T}GOh(fKlzlNqy~y7HX97Z_obF&TEvV>dIM>zYA$rlmOht{OSgptb&7z;;eG*=JlJ` z5Vv@nZ*H;q12)s)2*q)K$DPqo0mLn!?KEroG&BR+pO>6$PV~ceRaPybd=;5fxbt z#S6?p=|mxob@|IDDVA1TR6D_>3nhVU;!W~{I$bDe<=B8i!4Y|Zj72O*(Z zcp{#&_Myd_ri{yGn0SN#?(L|66F<%7Je!Mbej5$aI_oT<&;hMAK4wZ#r)(q&&H$A7 z)#7=GSQQja99x0Wtp2)A(p@ImCktqhfpq4acPeF((5K3CrFyyEs5cttj=g*Abi=D3 RYaB;`s9QhXINo^qe*k86S6l!9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/click/_bashcomplete.py b/venv/lib/python3.7/site-packages/click/_bashcomplete.py new file mode 100644 index 0000000..a5f1084 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/_bashcomplete.py @@ -0,0 +1,293 @@ +import copy +import os +import re + +from .utils import echo +from .parser import split_arg_string +from .core import MultiCommand, Option, Argument +from .types import Choice + +try: + from collections import abc +except ImportError: + import collections as abc + +WORDBREAK = '=' + +# Note, only BASH version 4.4 and later have the nosort option. +COMPLETION_SCRIPT_BASH = ''' +%(complete_func)s() { + local IFS=$'\n' + COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + %(autocomplete_var)s=complete $1 ) ) + return 0 +} + +%(complete_func)setup() { + local COMPLETION_OPTIONS="" + local BASH_VERSION_ARR=(${BASH_VERSION//./ }) + # Only BASH version 4.4 and later have the nosort option. + if [ ${BASH_VERSION_ARR[0]} -gt 4 ] || ([ ${BASH_VERSION_ARR[0]} -eq 4 ] && [ ${BASH_VERSION_ARR[1]} -ge 4 ]); then + COMPLETION_OPTIONS="-o nosort" + fi + + complete $COMPLETION_OPTIONS -F %(complete_func)s %(script_names)s +} + +%(complete_func)setup +''' + +COMPLETION_SCRIPT_ZSH = ''' +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + response=("${(@f)$( env COMP_WORDS=\"${words[*]}\" \\ + COMP_CWORD=$((CURRENT-1)) \\ + %(autocomplete_var)s=\"complete_zsh\" \\ + %(script_names)s )}") + + for key descr in ${(kv)response}; do + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U -Q + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -Q -a completions + fi + compstate[insert]="automenu" +} + +compdef %(complete_func)s %(script_names)s +''' + +_invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]') + + +def get_completion_script(prog_name, complete_var, shell): + cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_')) + script = COMPLETION_SCRIPT_ZSH if shell == 'zsh' else COMPLETION_SCRIPT_BASH + return (script % { + 'complete_func': '_%s_completion' % cf_name, + 'script_names': prog_name, + 'autocomplete_var': complete_var, + }).strip() + ';' + + +def resolve_ctx(cli, prog_name, args): + """ + Parse into a hierarchy of contexts. Contexts are connected through the parent variable. + :param cli: command definition + :param prog_name: the program that is running + :param args: full list of args + :return: the final context/command parsed + """ + ctx = cli.make_context(prog_name, args, resilient_parsing=True) + args = ctx.protected_args + ctx.args + while args: + if isinstance(ctx.command, MultiCommand): + if not ctx.command.chain: + cmd_name, cmd, args = ctx.command.resolve_command(ctx, args) + if cmd is None: + return ctx + ctx = cmd.make_context(cmd_name, args, parent=ctx, + resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + # Walk chained subcommand contexts saving the last one. + while args: + cmd_name, cmd, args = ctx.command.resolve_command(ctx, args) + if cmd is None: + return ctx + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True) + args = sub_ctx.args + ctx = sub_ctx + args = sub_ctx.protected_args + sub_ctx.args + else: + break + return ctx + + +def start_of_option(param_str): + """ + :param param_str: param_str to check + :return: whether or not this is the start of an option declaration (i.e. starts "-" or "--") + """ + return param_str and param_str[:1] == '-' + + +def is_incomplete_option(all_args, cmd_param): + """ + :param all_args: the full original list of args supplied + :param cmd_param: the current command paramter + :return: whether or not the last option declaration (i.e. starts "-" or "--") is incomplete and + corresponds to this cmd_param. In other words whether this cmd_param option can still accept + values + """ + if not isinstance(cmd_param, Option): + return False + if cmd_param.is_flag: + return False + last_option = None + for index, arg_str in enumerate(reversed([arg for arg in all_args if arg != WORDBREAK])): + if index + 1 > cmd_param.nargs: + break + if start_of_option(arg_str): + last_option = arg_str + + return True if last_option and last_option in cmd_param.opts else False + + +def is_incomplete_argument(current_params, cmd_param): + """ + :param current_params: the current params and values for this argument as already entered + :param cmd_param: the current command parameter + :return: whether or not the last argument is incomplete and corresponds to this cmd_param. In + other words whether or not the this cmd_param argument can still accept values + """ + if not isinstance(cmd_param, Argument): + return False + current_param_values = current_params[cmd_param.name] + if current_param_values is None: + return True + if cmd_param.nargs == -1: + return True + if isinstance(current_param_values, abc.Iterable) \ + and cmd_param.nargs > 1 and len(current_param_values) < cmd_param.nargs: + return True + return False + + +def get_user_autocompletions(ctx, args, incomplete, cmd_param): + """ + :param ctx: context associated with the parsed command + :param args: full list of args + :param incomplete: the incomplete text to autocomplete + :param cmd_param: command definition + :return: all the possible user-specified completions for the param + """ + results = [] + if isinstance(cmd_param.type, Choice): + # Choices don't support descriptions. + results = [(c, None) + for c in cmd_param.type.choices if str(c).startswith(incomplete)] + elif cmd_param.autocompletion is not None: + dynamic_completions = cmd_param.autocompletion(ctx=ctx, + args=args, + incomplete=incomplete) + results = [c if isinstance(c, tuple) else (c, None) + for c in dynamic_completions] + return results + + +def get_visible_commands_starting_with(ctx, starts_with): + """ + :param ctx: context associated with the parsed command + :starts_with: string that visible commands must start with. + :return: all visible (not hidden) commands that start with starts_with. + """ + for c in ctx.command.list_commands(ctx): + if c.startswith(starts_with): + command = ctx.command.get_command(ctx, c) + if not command.hidden: + yield command + + +def add_subcommand_completions(ctx, incomplete, completions_out): + # Add subcommand completions. + if isinstance(ctx.command, MultiCommand): + completions_out.extend( + [(c.name, c.get_short_help_str()) for c in get_visible_commands_starting_with(ctx, incomplete)]) + + # Walk up the context list and add any other completion possibilities from chained commands + while ctx.parent is not None: + ctx = ctx.parent + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + remaining_commands = [c for c in get_visible_commands_starting_with(ctx, incomplete) + if c.name not in ctx.protected_args] + completions_out.extend([(c.name, c.get_short_help_str()) for c in remaining_commands]) + + +def get_choices(cli, prog_name, args, incomplete): + """ + :param cli: command definition + :param prog_name: the program that is running + :param args: full list of args + :param incomplete: the incomplete text to autocomplete + :return: all the possible completions for the incomplete + """ + all_args = copy.deepcopy(args) + + ctx = resolve_ctx(cli, prog_name, args) + if ctx is None: + return [] + + # In newer versions of bash long opts with '='s are partitioned, but it's easier to parse + # without the '=' + if start_of_option(incomplete) and WORDBREAK in incomplete: + partition_incomplete = incomplete.partition(WORDBREAK) + all_args.append(partition_incomplete[0]) + incomplete = partition_incomplete[2] + elif incomplete == WORDBREAK: + incomplete = '' + + completions = [] + if start_of_option(incomplete): + # completions for partial options + for param in ctx.command.params: + if isinstance(param, Option) and not param.hidden: + param_opts = [param_opt for param_opt in param.opts + + param.secondary_opts if param_opt not in all_args or param.multiple] + completions.extend([(o, param.help) for o in param_opts if o.startswith(incomplete)]) + return completions + # completion for option values from user supplied values + for param in ctx.command.params: + if is_incomplete_option(all_args, param): + return get_user_autocompletions(ctx, all_args, incomplete, param) + # completion for argument values from user supplied values + for param in ctx.command.params: + if is_incomplete_argument(ctx.params, param): + return get_user_autocompletions(ctx, all_args, incomplete, param) + + add_subcommand_completions(ctx, incomplete, completions) + # Sort before returning so that proper ordering can be enforced in custom types. + return sorted(completions) + + +def do_complete(cli, prog_name, include_descriptions): + 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[0]) + if include_descriptions: + # ZSH has trouble dealing with empty array parameters when returned from commands, so use a well defined character '_' to indicate no description is present. + echo(item[1] if item[1] else '_') + + return True + + +def bashcomplete(cli, prog_name, complete_var, complete_instr): + if complete_instr.startswith('source'): + shell = 'zsh' if complete_instr == 'source_zsh' else 'bash' + echo(get_completion_script(prog_name, complete_var, shell)) + return True + elif complete_instr == 'complete' or complete_instr == 'complete_zsh': + return do_complete(cli, prog_name, complete_instr == 'complete_zsh') + return False diff --git a/venv/lib/python3.7/site-packages/click/_compat.py b/venv/lib/python3.7/site-packages/click/_compat.py new file mode 100644 index 0000000..937e230 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/_compat.py @@ -0,0 +1,703 @@ +import re +import io +import os +import sys +import codecs +from weakref import WeakKeyDictionary + + +PY2 = sys.version_info[0] == 2 +CYGWIN = sys.platform.startswith('cygwin') +# Determine local App Engine environment, per Google's own suggestion +APP_ENGINE = ('APPENGINE_RUNTIME' in os.environ and + 'Development/' in os.environ['SERVER_SOFTWARE']) +WIN = sys.platform.startswith('win') and not APP_ENGINE +DEFAULT_COLUMNS = 80 + + +_ansi_re = re.compile(r'\033\[((?:\d|;)*)([a-zA-Z])') + + +def get_filesystem_encoding(): + return sys.getfilesystemencoding() or sys.getdefaultencoding() + + +def _make_text_stream(stream, encoding, errors, + force_readable=False, force_writable=False): + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = 'replace' + return _NonClosingTextIOWrapper(stream, encoding, errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable) + + +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, + force_readable=False, force_writable=False, **extra): + self._stream = stream = _FixupStream(stream, force_readable, + force_writable) + 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. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__(self, stream, force_readable=False, force_writable=False): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + 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): + if self._force_readable: + return True + 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): + if self._force_writable: + return True + 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) + int_types = (int, long) + 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. + def set_binary_mode(f): + return f + + try: + import msvcrt + except ImportError: + pass + else: + def set_binary_mode(f): + try: + fileno = f.fileno() + except Exception: + pass + else: + msvcrt.setmode(fileno, os.O_BINARY) + return f + + try: + import fcntl + except ImportError: + pass + else: + def set_binary_mode(f): + try: + fileno = f.fileno() + except Exception: + pass + else: + flags = fcntl.fcntl(fileno, fcntl.F_GETFL) + fcntl.fcntl(fileno, fcntl.F_SETFL, flags & ~os.O_NONBLOCK) + 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(): + _wrap_std_stream('stdout') + return set_binary_mode(sys.stdout) + + def get_binary_stderr(): + _wrap_std_stream('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, + force_readable=True) + + def get_text_stdout(encoding=None, errors=None): + _wrap_std_stream('stdout') + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stdout, encoding, errors, + force_writable=True) + + def get_text_stderr(encoding=None, errors=None): + _wrap_std_stream('stderr') + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _make_text_stream(sys.stderr, encoding, errors, + force_writable=True) + + 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,) + int_types = (int,) + 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, + force_readable=False): + 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, + force_readable=force_readable) + + def _force_correct_text_writer(text_writer, encoding, errors, + force_writable=False): + 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, + force_writable=force_writable) + + 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, + force_readable=True) + + 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, + force_writable=True) + + 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, + force_writable=True) + + 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 any(m in mode for m in ['w', 'a', 'x']): + 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, os.path.realpath(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, _wrap_std_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 + _wrap_std_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: + stream = src_func() # In case wrapper_func() modified the stream + 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/venv/lib/python3.7/site-packages/click/_termui_impl.py b/venv/lib/python3.7/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..00a8e5e --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/_termui_impl.py @@ -0,0 +1,621 @@ +# -*- coding: utf-8 -*- +""" +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: © 2014 by the Pallets team. +:license: BSD, see LICENSE.rst for more details. +""" + +import os +import sys +import time +import math +import contextlib +from ._compat import _default_text_stdout, range_type, PY2, isatty, \ + open_stream, strip_ansi, term_len, get_best_encoding, WIN, int_types, \ + CYGWIN +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_types) 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 + self.short_limit = 0.5 + + 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.generator() + + def is_fast(self): + return time.time() - self.start <= self.short_limit + + def render_finish(self): + if self.is_hidden or self.is_fast(): + 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 = int(self.eta) + 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_bar(self): + 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) + elif 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) + return bar + + def format_progress_line(self): + show_percent = self.show_percent + + info_bits = [] + if self.length_known and show_percent is None: + show_percent = not self.show_pos + + 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': self.format_bar(), + 'info': self.info_sep.join(info_bits) + }).rstrip() + + def render_progress(self): + from .termui import get_terminal_size + + if self.is_hidden: + return + + 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 and not self.is_fast(): + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + 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 is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + 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 generator(self): + """ + Returns a generator which yields the items added to the bar during + construction, and updates the progress bar *after* the yielded block + returns. + """ + if not self.entered: + raise RuntimeError('You need to use progress bars in a with block.') + + if self.is_hidden: + for rv in self.iter: + yield rv + else: + for rv in self.iter: + self.current_item = rv + yield rv + self.update(1) + self.finish() + self.render_progress() + + +def pager(generator, 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, generator, color) + pager_cmd = (os.environ.get('PAGER', None) or '').strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get('TERM') in ('dumb', 'emacs'): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith('os2'): + return _tempfilepager(generator, 'more <', color) + if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0: + return _pipepager(generator, '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(generator, 'more', color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator, 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 + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + env=env) + encoding = get_best_encoding(c.stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + c.stdin.write(text.encode(encoding, 'replace')) + except (IOError, KeyboardInterrupt): + pass + else: + c.stdin.close() + + # 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(generator, cmd, color): + """Page through text by invoking a program on a temporary file.""" + import tempfile + filename = tempfile.mktemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + 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, generator, color): + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + 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) + elif CYGWIN: + if locate: + url = _unquote_file(url) + args = 'cygstart "%s"' % (os.path.dirname(url).replace('"', '')) + else: + args = 'cygstart %s "%s"' % ( + wait and '-w' 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 == u'\x03': + raise KeyboardInterrupt() + if ch == u'\x04' and not WIN: # Unix-like, Ctrl+D + raise EOFError() + if ch == u'\x1a' and WIN: # Windows, Ctrl+Z + raise EOFError() + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal(): + yield + + def getchar(echo): + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + if echo: + func = msvcrt.getwche + else: + func = msvcrt.getwch + + rv = func() + if rv in (u'\x00', u'\xe0'): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + _translate_ch_to_exc(rv) + return rv +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal(): + 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) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo): + with raw_terminal() as fd: + ch = os.read(fd, 32) + ch = ch.decode(get_best_encoding(sys.stdin), 'replace') + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + _translate_ch_to_exc(ch) + return ch diff --git a/venv/lib/python3.7/site-packages/click/_textwrap.py b/venv/lib/python3.7/site-packages/click/_textwrap.py new file mode 100644 index 0000000..7e77603 --- /dev/null +++ b/venv/lib/python3.7/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/venv/lib/python3.7/site-packages/click/_unicodefun.py b/venv/lib/python3.7/site-packages/click/_unicodefun.py new file mode 100644 index 0000000..620edff --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/_unicodefun.py @@ -0,0 +1,125 @@ +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__ + if not hasattr(sys, '_getframe'): # not all Python implementations have it + return 0 + 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 ' + 'https://click.palletsprojects.com/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 + try: + rv = subprocess.Popen(['locale', '-a'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate()[0] + except OSError: + rv = b'' + 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 were\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 https://click.palletsprojects.com/en/7.x/python3/ for' + ' mitigation steps.' + extra + ) diff --git a/venv/lib/python3.7/site-packages/click/_winconsole.py b/venv/lib/python3.7/site-packages/click/_winconsole.py new file mode 100644 index 0000000..bbb080d --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/_winconsole.py @@ -0,0 +1,307 @@ +# -*- 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 ._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, + ) + + +class WindowsChunkedWriter(object): + """ + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()' which we wrap to write in + limited chunks due to a Windows limitation on binary console streams. + """ + def __init__(self, wrapped): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + total_to_write = len(text) + written = 0 + + while written < total_to_write: + to_write = min(total_to_write - written, MAX_BYTES_WRITTEN) + self.__wrapped.write(text[written:written+to_write]) + written += to_write + + +_wrapped_std_streams = set() + + +def _wrap_std_stream(name): + # Python 2 & Windows 7 and below + if PY2 and sys.getwindowsversion()[:2] <= (6, 1) and name not in _wrapped_std_streams: + setattr(sys, name, WindowsChunkedWriter(getattr(sys, name))) + _wrapped_std_streams.add(name) + + +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( + io.BufferedWriter(_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( + io.BufferedWriter(_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', None) + 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/venv/lib/python3.7/site-packages/click/core.py b/venv/lib/python3.7/site-packages/click/core.py new file mode 100644 index 0000000..7a1e342 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/core.py @@ -0,0 +1,1856 @@ +import errno +import inspect +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 PacifyFlushWrapper, make_str, make_default_short_help, \ + echo, get_os_args +from .exceptions import ClickException, UsageError, BadParameter, Abort, \ + MissingParameter, Exit +from .termui import prompt, confirm, style +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, string_types +from ._unicodefun import _check_for_unicode_literals, _verify_python3_env + + +_missing = object() + + +SUBCOMMAND_METAVAR = 'COMMAND [ARGS]...' +SUBCOMMANDS_METAVAR = 'COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...' + +DEPRECATED_HELP_NOTICE = ' (DEPRECATED)' +DEPRECATED_INVOKE_NOTICE = 'DeprecationWarning: ' + \ + 'The command %(name)s is deprecated.' + + +def _maybe_show_deprecated_notice(cmd): + if cmd.deprecated: + echo(style(DEPRECATED_INVOKE_NOTICE % {'name': cmd.name}, fg='red'), err=True) + + +def fast_exit(code): + """Exit without garbage collection, this speeds up exit by about 10ms for + things like bash completion. + """ + sys.stdout.flush() + sys.stderr.flush() + os._exit(code) + + +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): + fast_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").' % ( + 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. Default values will also be + ignored. 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 and default values + #: will be ignored. Useful for completion. + 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: + 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 utilities 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.""" + raise 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 or 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 + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + 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.stdout = PacifyFlushWrapper(sys.stdout) + sys.stderr = PacifyFlushWrapper(sys.stderr) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + 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. + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + """ + + 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, + hidden=False, deprecated=False): + 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 [] + # if a form feed (page break) is found in the help text, truncate help + # text to the content preceding the first form feed + if help and '\f' in help: + help = help.split('\f', 1)[0] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.hidden = hidden + self.deprecated = deprecated + + 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) + 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 get_short_help_str(self, limit=45): + """Gets short help for the command or makes it by shortening the long help string.""" + return self.short_help or self.help and make_default_short_help(self.help, limit) or '' + + 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(): + help_text = self.help + if self.deprecated: + help_text += DEPRECATED_HELP_NOTICE + formatter.write_text(help_text) + elif self.deprecated: + formatter.write_paragraph() + with formatter.indentation(): + formatter.write_text(DEPRECATED_HELP_NOTICE) + + 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. + """ + _maybe_show_deprecated_notice(self) + 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. + """ + commands = [] + 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 + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + 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 and not ctx.resilient_parsing: + 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): + r"""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, + autocompletion=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 + self.autocompletion = autocompletion + + @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 = self.value_from_envvar(ctx) + if value is None: + value = ctx.lookup_default(self.name) + 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 and not ctx.resilient_parsing: + 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 [] + + def get_error_hint(self, ctx): + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return ' / '.join('"%s"' % x for x in hint_list) + + +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. If this + value is a string, it shows the string instead of the + value. This is particularly useful for dynamic options. + :param show_envvar: controls if an environment variable should be shown on + the help page. Normally, environment variables + are not shown. + :param prompt: if set to `True` or a non empty string then the user will be + prompted for input. 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 hidden: hide this option from help outputs. + """ + 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, hidden=False, show_choices=True, + show_envvar=False, **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 + self.hidden = hidden + + # 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 + self.show_choices = show_choices + self.show_envvar = show_envvar + + # 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])) # group long options first + name = possible_names[0][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): + if self.hidden: + return + 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.show_envvar: + envvar = self.envvar + if envvar is None: + if self.allow_from_autoenv and \ + ctx.auto_envvar_prefix is not None: + envvar = '%s_%s' % (ctx.auto_envvar_prefix, self.name.upper()) + if envvar is not None: + extra.append('env var: %s' % ( + ', '.join('%s' % d for d in envvar) + if isinstance(envvar, (list, tuple)) + else envvar, )) + if self.default is not None and self.show_default: + if isinstance(self.show_default, string_types): + default_string = '({})'.format(self.show_default) + elif isinstance(self.default, (list, tuple)): + default_string = ', '.join('%s' % d for d in self.default) + elif inspect.isfunction(self.default): + default_string = "(dynamic)" + else: + default_string = self.default + extra.append('default: {}'.format(default_string)) + + 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, type=self.type, + hide_input=self.hide_input, show_choices=self.show_choices, + 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.type.get_metavar(self) + if not var: + 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() + else: + raise TypeError('Arguments take exactly one ' + 'parameter declaration, got %d' % len(decls)) + return name, [arg], [] + + def get_usage_pieces(self, ctx): + return [self.make_metavar()] + + def get_error_hint(self, ctx): + return '"%s"' % 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/venv/lib/python3.7/site-packages/click/decorators.py b/venv/lib/python3.7/site-packages/click/decorators.py new file mode 100644 index 0000000..c57c530 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/decorators.py @@ -0,0 +1,311 @@ +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, **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().replace('_', '-'), + callback=f, params=params, **attrs) + + +def command(name=None, cls=None, **attrs): + r"""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 with underscores replaced by dashes. + :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): + # Issue 926, copy attrs, so pre-defined options can re-use the same cls= + option_attrs = attrs.copy() + + if 'help' in option_attrs: + option_attrs['help'] = inspect.cleandoc(option_attrs['help']) + OptionClass = option_attrs.pop('cls', Option) + _param_memo(f, OptionClass(param_decls, **option_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: + if hasattr(sys, '_getframe'): + module = sys._getframe(1).f_globals.get('__name__') + else: + module = '' + + 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/venv/lib/python3.7/site-packages/click/exceptions.py b/venv/lib/python3.7/site-packages/click/exceptions.py new file mode 100644 index 0000000..6fa1765 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/exceptions.py @@ -0,0 +1,235 @@ +from ._compat import PY2, filename_to_ui, get_text_stderr +from .utils import echo + + +def _join_param_hints(param_hint): + if isinstance(param_hint, (tuple, list)): + return ' / '.join('"%s"' % x for x in param_hint) + return param_hint + + +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): + ctor_msg = message + if PY2: + if ctor_msg is not None: + ctor_msg = ctor_msg.encode('utf-8') + Exception.__init__(self, ctor_msg) + self.message = message + + def format_message(self): + return self.message + + def __str__(self): + return self.message + + if PY2: + __unicode__ = __str__ + + def __str__(self): + return self.message.encode('utf-8') + + 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 + self.cmd = self.ctx and self.ctx.command or None + + def show(self, file=None): + if file is None: + file = get_text_stderr() + color = None + hint = '' + if (self.cmd is not None and + self.cmd.get_help_option(self.ctx) is not None): + hint = ('Try "%s %s" for help.\n' + % (self.ctx.command_path, self.ctx.help_option_names[0])) + if self.ctx is not None: + color = self.ctx.color + echo(self.ctx.get_usage() + '\n%s' % hint, 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.get_error_hint(self.ctx) + else: + return 'Invalid value: %s' % self.message + param_hint = _join_param_hints(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.get_error_hint(self.ctx) + else: + param_hint = None + param_hint = _join_param_hints(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 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__(self, option_name, message, ctx=None): + UsageError.__init__(self, message, ctx) + self.option_name = option_name + + +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.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + def __init__(self, code=0): + self.exit_code = code diff --git a/venv/lib/python3.7/site-packages/click/formatting.py b/venv/lib/python3.7/site-packages/click/formatting.py new file mode 100644 index 0000000..a3d6a4d --- /dev/null +++ b/venv/lib/python3.7/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/venv/lib/python3.7/site-packages/click/globals.py b/venv/lib/python3.7/site-packages/click/globals.py new file mode 100644 index 0000000..843b594 --- /dev/null +++ b/venv/lib/python3.7/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 its 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/venv/lib/python3.7/site-packages/click/parser.py b/venv/lib/python3.7/site-packages/click/parser.py new file mode 100644 index 0000000..1c3ae9c --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/parser.py @@ -0,0 +1,427 @@ +# -*- 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(opt, '%s option requires an argument' % opt) + raise BadOptionUsage(opt, '%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, ctx=self.ctx) + + 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(opt, '%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, ctx=self.ctx) + 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/venv/lib/python3.7/site-packages/click/termui.py b/venv/lib/python3.7/site-packages/click/termui.py new file mode 100644 index 0000000..bf9a3aa --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/termui.py @@ -0,0 +1,606 @@ +import os +import sys +import struct +import inspect +import itertools + +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, Choice, Path +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': 30, + 'red': 31, + 'green': 32, + 'yellow': 33, + 'blue': 34, + 'magenta': 35, + 'cyan': 36, + 'white': 37, + 'reset': 39, + 'bright_black': 90, + 'bright_red': 91, + 'bright_green': 92, + 'bright_yellow': 93, + 'bright_blue': 94, + 'bright_magenta': 95, + 'bright_cyan': 96, + 'bright_white': 97, +} +_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, show_choices=True, type=None): + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += ' (' + ", ".join(map(str, type.choices)) + ')' + 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, show_choices=True): + """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:: 7.0 + Added the show_choices parameter. + + .. 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. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + """ + 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, show_choices, type) + + while 1: + while 1: + value = prompt_func(prompt) + if value: + break + elif default is not None: + if isinstance(value_proc, Path): + # validate Path default value(exists, dir_okay etc.) + value = default + break + 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 + + # We provide a sensible default for get_winterm_size() when being invoked + # inside a subprocess. Without this, it would not provide a useful input. + if get_winterm_size is not None: + size = get_winterm_size() + if size == (0, 0): + return (79, 24) + else: + return 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_or_generator, 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_or_generator: the text to page, or alternatively, a + generator emitting 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 inspect.isgeneratorfunction(text_or_generator): + i = text_or_generator() + elif isinstance(text_or_generator, string_types): + i = [text_or_generator] + else: + i = iter(text_or_generator) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, string_types) else text_type(el) + for el in i) + + from ._termui_impl import pager + return pager(itertools.chain(text_generator, "\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) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + .. versionadded:: 2.0 + + .. versionadded:: 7.0 + Added support for bright colors. + + :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[fg])) + except KeyError: + raise TypeError('Unknown color %r' % fg) + if bg: + try: + bits.append('\033[%dm' % (_ansi_colors[bg] + 10)) + except KeyError: + 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(message=None, 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 + """ + if message is not None: + message = style(message, **styles) + return echo(message, 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('https://click.palletsprojects.com/') + 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. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. 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 raw_terminal(): + from ._termui_impl import raw_terminal as f + return f() + + +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/venv/lib/python3.7/site-packages/click/testing.py b/venv/lib/python3.7/site-packages/click/testing.py new file mode 100644 index 0000000..1b2924e --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/testing.py @@ -0,0 +1,374 @@ +import os +import sys +import shutil +import tempfile +import contextlib +import shlex + +from ._compat import iteritems, PY2, string_types + + +# 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, stdout_bytes, stderr_bytes, exit_code, + exception, exc_info=None): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or False(y) if not available + self.stderr_bytes = stderr_bytes + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self): + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self): + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, 'replace') \ + .replace('\r\n', '\n') + + @property + def stderr(self): + """The standard error as unicode string.""" + if not self.stderr_bytes: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, 'replace') \ + .replace('\r\n', '\n') + + + def __repr__(self): + return '<%s %s>' % ( + type(self).__name__, + 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. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__(self, charset=None, env=None, echo_stdin=False, + mix_stderr=True): + if charset is None: + charset = 'utf-8' + self.charset = charset + self.env = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + 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: + bytes_output = StringIO() + if self.echo_stdin: + input = EchoingStdin(input, bytes_output) + sys.stdout = bytes_output + if not self.mix_stderr: + bytes_error = StringIO() + sys.stderr = bytes_error + else: + bytes_output = io.BytesIO() + if self.echo_stdin: + input = EchoingStdin(input, bytes_output) + input = io.TextIOWrapper(input, encoding=self.charset) + sys.stdout = io.TextIOWrapper( + bytes_output, encoding=self.charset) + if not self.mix_stderr: + bytes_error = io.BytesIO() + sys.stderr = io.TextIOWrapper( + bytes_error, encoding=self.charset) + + if self.mix_stderr: + sys.stderr = sys.stdout + + 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, not self.mix_stderr and bytes_error) + 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, mix_stderr=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. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :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 outstreams: + exception = None + exit_code = 0 + + if isinstance(args, string_types): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + exit_code = e.code + if exit_code is None: + exit_code = 0 + + if exit_code != 0: + exception = e + + 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() + stdout = outstreams[0].getvalue() + stderr = outstreams[1] and outstreams[1].getvalue() + + return Result(runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + 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/venv/lib/python3.7/site-packages/click/types.py b/venv/lib/python3.7/site-packages/click/types.py new file mode 100644 index 0000000..1f88032 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/types.py @@ -0,0 +1,668 @@ +import os +import stat +from datetime import datetime + +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. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = 'choice' + + def __init__(self, choices, case_sensitive=True): + self.choices = choices + self.case_sensitive = case_sensitive + + def get_metavar(self, param): + return '[%s]' % '|'.join(self.choices) + + def get_missing_message(self, param): + return 'Choose from:\n\t%s.' % ',\n\t'.join(self.choices) + + def convert(self, value, param, ctx): + # Exact match + if value in self.choices: + return value + + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = self.choices + + if ctx is not None and \ + ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = [ctx.token_normalize_func(choice) for choice in + self.choices] + + if not self.case_sensitive: + normed_value = normed_value.lower() + normed_choices = [choice.lower() for choice in normed_choices] + + if normed_value in normed_choices: + return normed_value + + self.fail('invalid choice: %s. (choose from %s)' % + (value, ', '.join(self.choices)), param, ctx) + + def __repr__(self): + return 'Choice(%r)' % list(self.choices) + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + name = 'datetime' + + def __init__(self, formats=None): + self.formats = formats or [ + '%Y-%m-%d', + '%Y-%m-%dT%H:%M:%S', + '%Y-%m-%d %H:%M:%S' + ] + + def get_metavar(self, param): + return '[{}]'.format('|'.join(self.formats)) + + def _try_to_convert_date(self, value, format): + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert(self, value, param, ctx): + # Exact match + for format in self.formats: + dtime = self._try_to_convert_date(value, format) + if dtime: + return dtime + + self.fail( + 'invalid datetime format: {}. (choose from {})'.format( + value, ', '.join(self.formats))) + + def __repr__(self): + return 'DateTime' + + +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 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 FloatRange(FloatParamType): + """A parameter that works similar to :data:`click.FLOAT` 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 = 'float 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 = FloatParamType.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 'FloatRange(%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', 't', '1', 'yes', 'y'): + return True + elif value in ('false', 'f', '0', 'no', 'n'): + return False + self.fail('%s is not a valid boolean' % value, param, ctx) + + def __repr__(self): + return 'BOOL' + + +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. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + 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. It + will not expand a tilde-prefix, as this is + supposed to be done by the shell only. + :param allow_dash: If this is set to `True`, a single dash to indicate + standard streams is permitted. + :param path_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' + elif 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/venv/lib/python3.7/site-packages/click/utils.py b/venv/lib/python3.7/site-packages/click/utils.py new file mode 100644 index 0000000..fc84369 --- /dev/null +++ b/venv/lib/python3.7/site-packages/click/utils.py @@ -0,0 +1,440 @@ +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): + """Return a condensed version of help string.""" + 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 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: https://pypi.org/project/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)) + + +class PacifyFlushWrapper(object): + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped): + self.wrapped = wrapped + + def flush(self): + try: + self.wrapped.flush() + except IOError as e: + import errno + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr): + return getattr(self.wrapped, attr) diff --git a/venv/lib/python3.7/site-packages/easy_install.py b/venv/lib/python3.7/site-packages/easy_install.py new file mode 100644 index 0000000..d87e984 --- /dev/null +++ b/venv/lib/python3.7/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/venv/lib/python3.7/site-packages/flask/__init__.py b/venv/lib/python3.7/site-packages/flask/__init__.py new file mode 100644 index 0000000..59f0fff --- /dev/null +++ b/venv/lib/python3.7/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.3' + +# 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/venv/lib/python3.7/site-packages/flask/__main__.py b/venv/lib/python3.7/site-packages/flask/__main__.py new file mode 100644 index 0000000..4aee654 --- /dev/null +++ b/venv/lib/python3.7/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/venv/lib/python3.7/site-packages/flask/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3ebb8ec4e6785e0c0b491cb829816c24b5ab571 GIT binary patch literal 1850 zcmZ8hTW=Fb6!v``$8q8~Hz2@p$B@`gAS9%;qEIR!wWuOUl}43DYwy_Jc+T!JGtTXy z@BJf{_#6Eh^Vq(W_dfNh=WOf%9m${1ZO?t?#oSyagXizx|M}&&QYP~kG1HSn;yM1z zgKQ=fWOydX@@$X`@+t>;p3i2GE~o+&c`>DnsstYQpv=q2mjX}CK!sOemd`?!S5sM8 z%|VUVQhG+s!vbG`Il+!cIAT9bJvx)) zL5s21_MTz##LCEoM^c@#AnuJpMpg!?6F&-AKUOL}Hmoa+Wr_BCHtb23_|{4tnbvu< z{a&1$>Toc$`|OVoY`e47Vck<^hm!r|Dknd(buDK;!4u= z{6v1lP0BR$uJ}DQ#(8h$`!Oc(%5SAfVhoI*mtMwEKO8h?oHy1=U|d(EJ`UZCkx?M} zp^~m~PU;xMd8}BUx}|}%A~ltP0BMXrkjAZ$)JjN{Z>7NI=&(Ds(#?TCl0r`cqjSG6 z#bF#q=-g^-i8v1JQ1oK#`H5|o+-z^GHBLbIN#e2t=jloIp21jQ9Jxhwmlh;?_Cy%# z_eQQp=AZax!8L}y`DA$R-p!LRwVVhR{XULS*kO2K?AB?PVw%Q9tVxDhH}gV`Wun7~ zT0f7u2IOH91A1HpL%6?bu5dWl5K1S2eJ=vt-Rs~PMD2I&BuqBL2v=39&E)K)yK~}4?ey7c(-Sdj3xQi} tg=i(1+B1lQv6A1=91KG!i0FEtK-r?0=XcKS%%o literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/__main__.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a74d10b3d64cc682b218046609878c978c709461 GIT binary patch literal 477 zcmY*WO-chX6izy|twrw;6oi6Ks-Ue!#J>uHh)`EW21nBrVp3H}D!l58wqn zMz?Ns@5+^#(JuTTFYi6RmwfqhvbtJD9v?4Xx9b?8_pDeT@X3*1cEbmOx(Kkqqk>rz z1rex19CQPWAP_~d^o%hQr4Fi<$FH7TB_4gn?I>g{=2A13x1Ro?n)i;C+}3_c4YB~9kn44Jau^6(8bHFClo&)G(dSD+j;Y4zsVcB_E1~ H3SPlKtO$x+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/_compat.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..046833733d82fa38d54cf584f90297ca61d7ecfa GIT binary patch literal 3330 zcmbVOTW=h<6((n9uew>bELpy^bkZbU)ZSGbICg}@NUbV{(PpDsYGMxp3}%Pi)kw25 z6Oxj(3$+hk1Ib(a6D*)8kiU_i!PmYt&+Sv6dJbo`k{l;S$^kj#;qc?(cP^a!Gc$Dp z zQ~#py{KfQ3v4q%Ssp}xRxCHMSpBdxNj`8Ov_~!tBZi2sj3jeadAg=KF5rsX@^9!K+ zB46Ma;eC}a`q#uS1m#O3=WkSY9}s?tFFz-IS^RS3`fRW=xGLC){B@cVaeYLd(Ju&h z{zx8?$K(r=&QgNUGxCI_j+Hb$BHq}o1J*_{$1nTWV0IDY*R7lv@?r&dHc8{^9-N-k z8I*1ks@-M~W&J$VR`QqArEW!=SzoYxaI2LM-ebk5aVJh<=un9dj%xk!%zauLPdIAY^<76aDC zx>@M68fE!F#=UL5%D(%S-CB8fg>?o@Zws~&CW+9BX%Y6DcHwFgMa@nC|lhu;c)O)zS2r|?rJ^!;P(5ws(0tze4y`q6>!d-z#|3}M0dgsrPEIHWt|(AllY zg+uy+9y&+#89ju`3#$WrGeMwb7>Q08?FNCFeH!cS6G_80j?PWVk^tS#O9YsT6f%sJ zxDJ~sv>c&zc;o`~&Tx%hXpM-hf(gmdSOqu-8n7_mkCJ>7R{hX`KLJ`t(AV0o`Ey}w z2>Uv-wT@B2NOdsV*kr@oTy)u(uwU!^2DAFzV7l{BJ4;1lwazS=?9AM&XJ*W^BZu`s>jE!T?r1V{{|qfg0EZhm zCPy9|zBGJmO$x|xEVL<~MUbNu!w3LLAM9oY%?KbT1vkT@Fzf~KA(VXQ^mcH?y8!MD zuiH>Mfte685k<%?7JOs9099d@`v#))8*=E55Q?@fM-5M6NEH)K>%SRAS6D=O>uXy&MX3h0mf64 zEpQswK7gt)0cfHjl1Gj_ujvct2yS+p*qyeiiGv8(6rqF^UfB*+sI@e%8Yqc5ui?lW z@G>5zrk9lhbBlvm2f<_9$NDI(JHwe{t?XR8QIc=My!;h5Z((C|^eyb!1D-T!8~Gb( z{sh$mR%z9-k}dG=#+&G)Jc}SPtiTs$`m}kByYb|fUkhRmbiiL490E>K)8aq}=pbgg zNH}(&j2oxg%s?Z0Kr4Qr(k}U0+TC_R7l+DyBDC3C(5m^`Xm+n9M?Dy;KVB^Wg zlVEM@@uv?S1?!I=Zb`g0OgZc9pl(Q)nfokg}zfQR~J3_;#|d{4$LpWN*F=!9Q_|x Cw(7G0 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/app.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/app.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af9ab2cb6af681df38b9bd086e9a1f4a2ee4c839 GIT binary patch literal 71414 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/blueprints.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/blueprints.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b17c76e4c1ac8d61ee97b1191b78a6d800cabae7 GIT binary patch literal 20472 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/cli.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/cli.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4dcffb4a050fe70b80ae3b1aed230e17e7d8c4c GIT binary patch literal 25067 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 L8@3yU?$G@Q@&NR| literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/helpers.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f079fc380eebdcae7cd354950b3c72348a4668a GIT binary patch literal 33264 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 Ta;4mTxfkajod1S1o16asVW&TV literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/logging.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/logging.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a67d30f3f272939be993492d9e8c9d5dedc7ae6 GIT binary patch literal 2406 zcmZuzO>f&a7$)U!#YsP~Zry1du%a=L+G&S=%m{*^`DhCSU4djP;H|J|k&>0jl0(u- z9HhOpz_uT-%TCE|Z|-~RsL z_bMTO;$+%NF!&lSt)LU6Lj)C0Ob1TKp*SwYg-*fVi=86ei*adC?v&wONtENtpxUWY zBFmy8s&B|^+Np_}aNm%QD+{M{vUWy0by+{1huMOdJELb5cGkr_thgi!+oZ8DGT_(^ zVy^d^aTp*`JP{{jX!qeR$v z2dOrU4~Hrps)!rOq*4%>HVP83L1I?005ahwN|Ppg5-`pt&RqsA(v15iI*>~Y0AnU) zo_DCjsA+9!&s$F=>9z!QZ7MB=f2 z&I1-D_M9gnGr!O66K>dH6vvZgxWr-|0$mfNYbe!C&DsNL`fX1J0URs5VzE4sFl5r=|>W@ z19ZakZszq0ns?LlCKN#_n27@r57Z!FiIhT$iF`fp1E1R57}fS(Sw+#7$yEJHM9)k`F~;t%0#iHu$vW(5xVZu+)g_I#+4ksZwAmgL&g}R_S&{>UX=D+wBG; z1D~XBS7GHTENfMPuCs6`)!wljh48BYb*HfMvq~7JJt#se;8q#)nCH(yt3JcEb;xeh uVq~PsYO|pY;)CF=+}jMQD|vaW!k-h-A46AkFz_n$^+J8Vdd;OUEB*`n0=@?T literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/sessions.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/sessions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef093a26952bbfae0c17d1987378903aa7187899 GIT binary patch literal 12272 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/templating.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/templating.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4beaf25c8aa373aa7b29fb82a47521f5397fdfe GIT binary patch literal 4987 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/testing.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/testing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa890cb7fccb6b22353de85c646bbab439c037cd GIT binary patch literal 7860 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 E0rg13@Bjb+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/__pycache__/views.cpython-37.pyc b/venv/lib/python3.7/site-packages/flask/__pycache__/views.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ff78346f2b5e3d3e5a834c1565dd9d0c0c36015 GIT binary patch literal 4800 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 Di{np$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/flask/_compat.py b/venv/lib/python3.7/site-packages/flask/_compat.py new file mode 100644 index 0000000..dfbaae9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/flask/_compat.py @@ -0,0 +1,101 @@ +# -*- 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 + import collections.abc as collections_abc + + 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 + import collections as collections_abc + + 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/venv/lib/python3.7/site-packages/flask/app.py b/venv/lib/python3.7/site-packages/flask/app.py new file mode 100644 index 0000000..c570a95 --- /dev/null +++ b/venv/lib/python3.7/site-packages/flask/app.py @@ -0,0 +1,2334 @@ +# -*- 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, \ + RoutingException, 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. + + .. versionchanged:: 1.0.3 + ``RoutingException``, used internally for actions such as + slash redirects during routing, is not passed to error + handlers. + + .. versionchanged:: 1.0 + Exceptions are looked up by code *and* by MRO, so + ``HTTPExcpetion`` subclasses can be handled with a catch-all + handler for the base ``HTTPException``. + + .. 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 + + # RoutingExceptions are used internally to trigger routing + # actions, such as slash redirects raising RequestRedirect. They + # are not raised or handled in user code. + if isinstance(e, RoutingException): + 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 is :class:`~werkzeug + .exceptions.HTTPException` which is forwarded 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 + 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. + + if isinstance(e, BadRequestKeyError): + if self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]: + # Werkzeug < 0.15 doesn't add the KeyError to the 400 + # message, add it in manually. + description = e.get_description() + + if e.args[0] not in description: + e.description = "KeyError: '{}'".format(*e.args) + else: + # Werkzeug >= 0.15 does add it, remove it in production + 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/venv/lib/python3.7/site-packages/flask/blueprints.py b/venv/lib/python3.7/site-packages/flask/blueprints.py new file mode 100644 index 0000000..c2158fe --- /dev/null +++ b/venv/lib/python3.7/site-packages/flask/blueprints.py @@ -0,0 +1,447 @@ +# -*- 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 .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/venv/lib/python3.7/site-packages/flask/cli.py b/venv/lib/python3.7/site-packages/flask/cli.py new file mode 100644 index 0000000..3eb93b3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/flask/cli.py @@ -0,0 +1,910 @@ +# -*- 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 platform +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 + import werkzeug + message = ( + 'Python %(python)s\n' + 'Flask %(flask)s\n' + 'Werkzeug %(werkzeug)s' + ) + click.echo(message % { + 'python': platform.python_version(), + 'flask': __version__, + 'werkzeug': werkzeug.__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): + """Helper 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, + set_debug_flag=True): + #: 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.set_debug_flag = set_debug_flag + 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 = (re.split(r':(?![\\/])', self.app_import_path, 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.' + ) + + if self.set_debug_flag: + # Update the app's debug flag through the descriptor so that + # other values repopulate as well. + app.debug = get_debug_flag() + + 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. + :param set_debug_flag: Set the app's debug flag based on the active + environment + + .. 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, + set_debug_flag=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 + self.set_debug_flag = set_debug_flag + + 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, + set_debug_flag=self.set_debug_flag) + + 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: This is a development server. ' + 'Do not use it in a production deployment.', 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, 9): + 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, 9): + 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='Run 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='Run a shell in the app context.') +@with_appcontext +def shell_command(): + """Run 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/venv/lib/python3.7/site-packages/flask/config.py b/venv/lib/python3.7/site-packages/flask/config.py new file mode 100644 index 0000000..a5475ed --- /dev/null +++ b/venv/lib/python3.7/site-packages/flask/config.py @@ -0,0 +1,269 @@ +# -*- 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) + + Nothing is done to the object before loading. If the object is a + class and has ``@property`` attributes, it needs to be + instantiated before being passed to this method. + + 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/venv/lib/python3.7/site-packages/flask/ctx.py b/venv/lib/python3.7/site-packages/flask/ctx.py new file mode 100644 index 0000000..ec8e787 --- /dev/null +++ b/venv/lib/python3.7/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/venv/lib/python3.7/site-packages/flask/debughelpers.py b/venv/lib/python3.7/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..e9765f2 --- /dev/null +++ b/venv/lib/python3.7/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/venv/lib/python3.7/site-packages/flask/globals.py b/venv/lib/python3.7/site-packages/flask/globals.py new file mode 100644 index 0000000..7d50a6f --- /dev/null +++ b/venv/lib/python3.7/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/venv/lib/python3.7/site-packages/flask/helpers.py b/venv/lib/python3.7/site-packages/flask/helpers.py new file mode 100644 index 0000000..158edc5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/flask/helpers.py @@ -0,0 +1,1051 @@ +# -*- 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 + falls back to the `Host` header, then to the IP and port of the request. + :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 + + .. versionchanged:: 1.0.3 + Filenames are encoded with ASCII instead of Latin-1 for broader + compatibility with WSGI servers. + + :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') + + if not isinstance(attachment_filename, text_type): + attachment_filename = attachment_filename.decode('utf-8') + + try: + attachment_filename = attachment_filename.encode('ascii') + except UnicodeEncodeError: + filenames = { + 'filename': unicodedata.normalize( + 'NFKD', attachment_filename).encode('ascii', '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/venv/lib/python3.7/site-packages/flask/json/__init__.py b/venv/lib/python3.7/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..c24286c --- /dev/null +++ b/venv/lib/python3.7/site-packages/flask/json/__init__.py @@ -0,0 +1,357 @@ +# -*- 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, app=None): + """Inject default arguments for dump functions.""" + if app is None: + app = current_app + + if app: + bp = app.blueprints.get(request.blueprint) if request else None + kwargs.setdefault( + 'cls', bp.json_encoder if bp and bp.json_encoder else app.json_encoder + ) + + if not app.config['JSON_AS_ASCII']: + kwargs.setdefault('ensure_ascii', False) + + kwargs.setdefault('sort_keys', app.config['JSON_SORT_KEYS']) + else: + kwargs.setdefault('sort_keys', True) + kwargs.setdefault('cls', JSONEncoder) + + +def _load_arg_defaults(kwargs, app=None): + """Inject default arguments for load functions.""" + if app is None: + app = current_app + + if app: + bp = app.blueprints.get(request.blueprint) if request else None + kwargs.setdefault( + 'cls', + bp.json_decoder if bp and bp.json_decoder + else 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, app=None, **kwargs): + """Serialize ``obj`` to a JSON-formatted string. If there is an + app context pushed, use the current app's configured encoder + (:attr:`~flask.Flask.json_encoder`), or fall back to the default + :class:`JSONEncoder`. + + Takes the same arguments as the built-in :func:`json.dumps`, and + does some extra configuration based on the application. If the + simplejson package is installed, it is preferred. + + :param obj: Object to serialize to JSON. + :param app: App instance to use to configure the JSON encoder. + Uses ``current_app`` if not given, and falls back to the default + encoder when not in an app context. + :param kwargs: Extra arguments passed to :func:`json.dumps`. + + .. versionchanged:: 1.0.3 + + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + _dump_arg_defaults(kwargs, app=app) + 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, app=None, **kwargs): + """Like :func:`dumps` but writes into a file object.""" + _dump_arg_defaults(kwargs, app=app) + 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, app=None, **kwargs): + """Deserialize an object from a JSON-formatted string ``s``. If + there is an app context pushed, use the current app's configured + decoder (:attr:`~flask.Flask.json_decoder`), or fall back to the + default :class:`JSONDecoder`. + + Takes the same arguments as the built-in :func:`json.loads`, and + does some extra configuration based on the application. If the + simplejson package is installed, it is preferred. + + :param s: JSON string to deserialize. + :param app: App instance to use to configure the JSON decoder. + Uses ``current_app`` if not given, and falls back to the default + encoder when not in an app context. + :param kwargs: Extra arguments passed to :func:`json.dumps`. + + .. versionchanged:: 1.0.3 + + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + _load_arg_defaults(kwargs, app=app) + 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, app=None, **kwargs): + """Like :func:`loads` but reads from a file object.""" + _load_arg_defaults(kwargs, app=app) + 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 ``') + # => <script> do_nasty_stuff() </script> + # sanitize_html('Click here for $100') + # => Click here for $100 + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..ae41a13 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2791 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import with_metaclass, viewkeys + +import types +from collections import OrderedDict + +from . import _inputstream +from . import _tokenizer + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('

This is a doc

') + + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('this is a fragment') + + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = dict([(name, cls(self, self.tree)) for name, cls in + getPhases(debug).items()]) + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.normalizedTokens(): + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def normalizedTokens(self): + for token in self.tokenizer: + yield self.normalizeToken(token) + + def parse(self, stream, *args, **kwargs): + """Parse a HTML document into a well-formed tree + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('

This is a doc

') + + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('this is a fragment') + + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def normalizeToken(self, token): + # HTML5 specific normalizations to the token stream + if token["type"] == tokenTypes["StartTag"]: + raw = token["data"] + token["data"] = OrderedDict(raw) + if len(raw) > len(token["data"]): + # we had some duplicated attribute, fix so first wins + token["data"].update(raw[::-1]) + + return token + + def adjustMathMLAttributes(self, token): + adjust_attributes(token, adjustMathMLAttributes) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = dict((value, key) for key, value in + tokenTypes.items()) + + def wrapped(self, *args, **kwargs): + if function.__name__.startswith("process") and len(args) > 0: + token = args[0] + try: + info = {"type": type_names[token['type']]} + except: + raise + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + return self.startTagHandler[token["name"]](token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + return self.endTagHandler[token["name"]](token) + + class InitialPhase(Phase): + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("head", "body", "html", "br"), self.endTagImplyHead) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + class InHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("title", self.startTagTitle), + (("noframes", "style"), self.startTagNoFramesStyle), + ("noscript", self.startTagNoscript), + ("script", self.startTagScript), + (("base", "basefont", "bgsound", "command", "link"), + self.startTagBaseLinkCommand), + ("meta", self.startTagMeta), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("head", self.endTagHead), + (("br", "html", "body"), self.endTagHtmlBodyBr) + ]) + self.endTagHandler.default = self.endTagOther + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + class InHeadNoscriptPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), self.startTagBaseLinkCommand), + (("head", "noscript"), self.startTagHeadNoscript), + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("noscript", self.endTagNoscript), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + class AfterHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", + "style", "title"), + self.startTagFromHead), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), + self.endTagHtmlBodyBr)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + class InBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody + # the really-really-really-very crazy mode + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + # Set this to the default handler + self.processSpaceCharacters = self.processSpaceCharactersNonPre + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("base", "basefont", "bgsound", "command", "link", "meta", + "script", "style", "title"), + self.startTagProcessInHead), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("address", "article", "aside", "blockquote", "center", "details", + "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", + "section", "summary", "ul"), + self.startTagCloseP), + (headingElements, self.startTagHeading), + (("pre", "listing"), self.startTagPreListing), + ("form", self.startTagForm), + (("li", "dd", "dt"), self.startTagListItem), + ("plaintext", self.startTagPlaintext), + ("a", self.startTagA), + (("b", "big", "code", "em", "font", "i", "s", "small", "strike", + "strong", "tt", "u"), self.startTagFormatting), + ("nobr", self.startTagNobr), + ("button", self.startTagButton), + (("applet", "marquee", "object"), self.startTagAppletMarqueeObject), + ("xmp", self.startTagXmp), + ("table", self.startTagTable), + (("area", "br", "embed", "img", "keygen", "wbr"), + self.startTagVoidFormatting), + (("param", "source", "track"), self.startTagParamSource), + ("input", self.startTagInput), + ("hr", self.startTagHr), + ("image", self.startTagImage), + ("isindex", self.startTagIsIndex), + ("textarea", self.startTagTextarea), + ("iframe", self.startTagIFrame), + ("noscript", self.startTagNoscript), + (("noembed", "noframes"), self.startTagRawtext), + ("select", self.startTagSelect), + (("rp", "rt"), self.startTagRpRt), + (("option", "optgroup"), self.startTagOpt), + (("math"), self.startTagMath), + (("svg"), self.startTagSvg), + (("caption", "col", "colgroup", "frame", "head", + "tbody", "td", "tfoot", "th", "thead", + "tr"), self.startTagMisplaced) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("body", self.endTagBody), + ("html", self.endTagHtml), + (("address", "article", "aside", "blockquote", "button", "center", + "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", + "section", "summary", "ul"), self.endTagBlock), + ("form", self.endTagForm), + ("p", self.endTagP), + (("dd", "dt", "li"), self.endTagListItem), + (headingElements, self.endTagHeading), + (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", + "strike", "strong", "tt", "u"), self.endTagFormatting), + (("applet", "marquee", "object"), self.endTagAppletMarqueeObject), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def isMatchingFormattingElement(self, node1, node2): + return (node1.name == node2.name and + node1.namespace == node2.namespace and + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of
, , and ",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("
+    
+    
+  
+  
+    
+""" +FOOTER = u"""\ + +
+ +
+
+

Console Locked

+

+ The console is locked and needs to be unlocked by entering the PIN. + You can find the PIN printed out on the standard output of your + shell that runs the server. +

+

PIN: + + +

+
+
+ + +""" + +PAGE_HTML = ( + HEADER + + u"""\ +

%(exception_type)s

+
+

%(exception)s

+
+

Traceback (most recent call last)

+%(summary)s +
+
+

+ + This is the Copy/Paste friendly version of the traceback. You can also paste this traceback into + a gist: + +

+ +
+
+
+ The debugger caught an exception in your WSGI application. You can now + look at the traceback which led to the error. + If you enable JavaScript you can also use additional features such as code + execution (if the evalex feature is enabled), automatic pasting of the + exceptions and much more. +
+""" + + FOOTER + + """ + +""" +) + +CONSOLE_HTML = ( + HEADER + + u"""\ +

Interactive Console

+
+In this console you can execute Python expressions in the context of the +application. The initial namespace was created by the debugger automatically. +
+
The Console requires JavaScript.
+""" + + FOOTER +) + +SUMMARY_HTML = u"""\ +
+ %(title)s +
    %(frames)s
+ %(description)s +
+""" + +FRAME_HTML = u"""\ +
+

File "%(filename)s", + line %(lineno)s, + in %(function_name)s

+
%(lines)s
+
+""" + +SOURCE_LINE_HTML = u"""\ + + %(lineno)s + %(code)s + +""" + + +def render_console_html(secret, evalex_trusted=True): + return CONSOLE_HTML % { + "evalex": "true", + "evalex_trusted": "true" if evalex_trusted else "false", + "console": "true", + "title": "Console", + "secret": secret, + "traceback_id": -1, + } + + +def get_current_traceback( + ignore_system_exceptions=False, show_hidden_frames=False, skip=0 +): + """Get the current exception info as `Traceback` object. Per default + calling this method will reraise system exceptions such as generator exit, + system exit or others. This behavior can be disabled by passing `False` + to the function as first parameter. + """ + exc_type, exc_value, tb = sys.exc_info() + if ignore_system_exceptions and exc_type in system_exceptions: + reraise(exc_type, exc_value, tb) + for _ in range_type(skip): + if tb.tb_next is None: + break + tb = tb.tb_next + tb = Traceback(exc_type, exc_value, tb) + if not show_hidden_frames: + tb.filter_hidden_frames() + return tb + + +class Line(object): + """Helper for the source renderer.""" + + __slots__ = ("lineno", "code", "in_frame", "current") + + def __init__(self, lineno, code): + self.lineno = lineno + self.code = code + self.in_frame = False + self.current = False + + @property + def classes(self): + rv = ["line"] + if self.in_frame: + rv.append("in-frame") + if self.current: + rv.append("current") + return rv + + def render(self): + return SOURCE_LINE_HTML % { + "classes": u" ".join(self.classes), + "lineno": self.lineno, + "code": escape(self.code), + } + + +class Traceback(object): + """Wraps a traceback.""" + + def __init__(self, exc_type, exc_value, tb): + self.exc_type = exc_type + self.exc_value = exc_value + self.tb = tb + + exception_type = exc_type.__name__ + if exc_type.__module__ not in {"builtins", "__builtin__", "exceptions"}: + exception_type = exc_type.__module__ + "." + exception_type + self.exception_type = exception_type + + self.groups = [] + memo = set() + while True: + self.groups.append(Group(exc_type, exc_value, tb)) + memo.add(id(exc_value)) + if PY2: + break + exc_value = exc_value.__cause__ or exc_value.__context__ + if exc_value is None or id(exc_value) in memo: + break + exc_type = type(exc_value) + tb = exc_value.__traceback__ + self.groups.reverse() + self.frames = [frame for group in self.groups for frame in group.frames] + + def filter_hidden_frames(self): + """Remove the frames according to the paste spec.""" + for group in self.groups: + group.filter_hidden_frames() + + self.frames[:] = [frame for group in self.groups for frame in group.frames] + + @property + def is_syntax_error(self): + """Is it a syntax error?""" + return isinstance(self.exc_value, SyntaxError) + + @property + def exception(self): + """String representation of the final exception.""" + return self.groups[-1].exception + + def log(self, logfile=None): + """Log the ASCII traceback into a file object.""" + if logfile is None: + logfile = sys.stderr + tb = self.plaintext.rstrip() + u"\n" + logfile.write(to_native(tb, "utf-8", "replace")) + + def paste(self): + """Create a paste and return the paste id.""" + data = json.dumps( + { + "description": "Werkzeug Internal Server Error", + "public": False, + "files": {"traceback.txt": {"content": self.plaintext}}, + } + ).encode("utf-8") + try: + from urllib2 import urlopen + except ImportError: + from urllib.request import urlopen + rv = urlopen("https://api.github.com/gists", data=data) + resp = json.loads(rv.read().decode("utf-8")) + rv.close() + return {"url": resp["html_url"], "id": resp["id"]} + + def render_summary(self, include_title=True): + """Render the traceback for the interactive console.""" + title = "" + classes = ["traceback"] + if not self.frames: + classes.append("noframe-traceback") + frames = [] + else: + library_frames = sum(frame.is_library for frame in self.frames) + mark_lib = 0 < library_frames < len(self.frames) + frames = [group.render(mark_lib=mark_lib) for group in self.groups] + + if include_title: + if self.is_syntax_error: + title = u"Syntax Error" + else: + title = u"Traceback (most recent call last):" + + if self.is_syntax_error: + description_wrapper = u"
%s
" + else: + description_wrapper = u"
%s
" + + return SUMMARY_HTML % { + "classes": u" ".join(classes), + "title": u"

%s

" % title if title else u"", + "frames": u"\n".join(frames), + "description": description_wrapper % escape(self.exception), + } + + def render_full(self, evalex=False, secret=None, evalex_trusted=True): + """Render the Full HTML page with the traceback info.""" + exc = escape(self.exception) + return PAGE_HTML % { + "evalex": "true" if evalex else "false", + "evalex_trusted": "true" if evalex_trusted else "false", + "console": "false", + "title": exc, + "exception": exc, + "exception_type": escape(self.exception_type), + "summary": self.render_summary(include_title=False), + "plaintext": escape(self.plaintext), + "plaintext_cs": re.sub("-{2,}", "-", self.plaintext), + "traceback_id": self.id, + "secret": secret, + } + + @cached_property + def plaintext(self): + return u"\n".join([group.render_text() for group in self.groups]) + + @property + def id(self): + return id(self) + + +class Group(object): + """A group of frames for an exception in a traceback. On Python 3, + if the exception has a ``__cause__`` or ``__context__``, there are + multiple exception groups. + """ + + def __init__(self, exc_type, exc_value, tb): + self.exc_type = exc_type + self.exc_value = exc_value + self.info = None + if not PY2: + if exc_value.__cause__ is not None: + self.info = ( + u"The above exception was the direct cause of the" + u" following exception" + ) + elif exc_value.__context__ is not None: + self.info = ( + u"During handling of the above exception, another" + u" exception occurred" + ) + + self.frames = [] + while tb is not None: + self.frames.append(Frame(exc_type, exc_value, tb)) + tb = tb.tb_next + + def filter_hidden_frames(self): + new_frames = [] + hidden = False + + for frame in self.frames: + hide = frame.hide + if hide in ("before", "before_and_this"): + new_frames = [] + hidden = False + if hide == "before_and_this": + continue + elif hide in ("reset", "reset_and_this"): + hidden = False + if hide == "reset_and_this": + continue + elif hide in ("after", "after_and_this"): + hidden = True + if hide == "after_and_this": + continue + elif hide or hidden: + continue + new_frames.append(frame) + + # if we only have one frame and that frame is from the codeop + # module, remove it. + if len(new_frames) == 1 and self.frames[0].module == "codeop": + del self.frames[:] + + # if the last frame is missing something went terrible wrong :( + elif self.frames[-1] in new_frames: + self.frames[:] = new_frames + + @property + def exception(self): + """String representation of the exception.""" + buf = traceback.format_exception_only(self.exc_type, self.exc_value) + rv = "".join(buf).strip() + return to_unicode(rv, "utf-8", "replace") + + def render(self, mark_lib=True): + out = [] + if self.info is not None: + out.append(u'
  • %s:
    ' % self.info) + for frame in self.frames: + out.append( + u"%s" + % ( + u' title="%s"' % escape(frame.info) if frame.info else u"", + frame.render(mark_lib=mark_lib), + ) + ) + return u"\n".join(out) + + def render_text(self): + out = [] + if self.info is not None: + out.append(u"\n%s:\n" % self.info) + out.append(u"Traceback (most recent call last):") + for frame in self.frames: + out.append(frame.render_text()) + out.append(self.exception) + return u"\n".join(out) + + +class Frame(object): + """A single frame in a traceback.""" + + def __init__(self, exc_type, exc_value, tb): + self.lineno = tb.tb_lineno + self.function_name = tb.tb_frame.f_code.co_name + self.locals = tb.tb_frame.f_locals + self.globals = tb.tb_frame.f_globals + + fn = inspect.getsourcefile(tb) or inspect.getfile(tb) + if fn[-4:] in (".pyo", ".pyc"): + fn = fn[:-1] + # if it's a file on the file system resolve the real filename. + if os.path.isfile(fn): + fn = os.path.realpath(fn) + self.filename = to_unicode(fn, get_filesystem_encoding()) + self.module = self.globals.get("__name__") + self.loader = self.globals.get("__loader__") + self.code = tb.tb_frame.f_code + + # support for paste's traceback extensions + self.hide = self.locals.get("__traceback_hide__", False) + info = self.locals.get("__traceback_info__") + if info is not None: + info = to_unicode(info, "utf-8", "replace") + self.info = info + + def render(self, mark_lib=True): + """Render a single frame in a traceback.""" + return FRAME_HTML % { + "id": self.id, + "filename": escape(self.filename), + "lineno": self.lineno, + "function_name": escape(self.function_name), + "lines": self.render_line_context(), + "library": "library" if mark_lib and self.is_library else "", + } + + @cached_property + def is_library(self): + return any( + self.filename.startswith(path) for path in sysconfig.get_paths().values() + ) + + def render_text(self): + return u' File "%s", line %s, in %s\n %s' % ( + self.filename, + self.lineno, + self.function_name, + self.current_line.strip(), + ) + + def render_line_context(self): + before, current, after = self.get_context_lines() + rv = [] + + def render_line(line, cls): + line = line.expandtabs().rstrip() + stripped_line = line.strip() + prefix = len(line) - len(stripped_line) + rv.append( + '
    %s%s
    ' + % (cls, " " * prefix, escape(stripped_line) or " ") + ) + + for line in before: + render_line(line, "before") + render_line(current, "current") + for line in after: + render_line(line, "after") + + return "\n".join(rv) + + def get_annotated_lines(self): + """Helper function that returns lines with extra information.""" + lines = [Line(idx + 1, x) for idx, x in enumerate(self.sourcelines)] + + # find function definition and mark lines + if hasattr(self.code, "co_firstlineno"): + lineno = self.code.co_firstlineno - 1 + while lineno > 0: + if _funcdef_re.match(lines[lineno].code): + break + lineno -= 1 + try: + offset = len(inspect.getblock([x.code + "\n" for x in lines[lineno:]])) + except TokenError: + offset = 0 + for line in lines[lineno : lineno + offset]: + line.in_frame = True + + # mark current line + try: + lines[self.lineno - 1].current = True + except IndexError: + pass + + return lines + + def eval(self, code, mode="single"): + """Evaluate code in the context of the frame.""" + if isinstance(code, string_types): + if PY2 and isinstance(code, text_type): # noqa + code = UTF8_COOKIE + code.encode("utf-8") + code = compile(code, "", mode) + return eval(code, self.globals, self.locals) + + @cached_property + def sourcelines(self): + """The sourcecode of the file as list of unicode strings.""" + # get sourcecode from loader or file + source = None + if self.loader is not None: + try: + if hasattr(self.loader, "get_source"): + source = self.loader.get_source(self.module) + elif hasattr(self.loader, "get_source_by_code"): + source = self.loader.get_source_by_code(self.code) + except Exception: + # we munch the exception so that we don't cause troubles + # if the loader is broken. + pass + + if source is None: + try: + f = open(to_native(self.filename, get_filesystem_encoding()), mode="rb") + except IOError: + return [] + try: + source = f.read() + finally: + f.close() + + # already unicode? return right away + if isinstance(source, text_type): + return source.splitlines() + + # yes. it should be ascii, but we don't want to reject too many + # characters in the debugger if something breaks + charset = "utf-8" + if source.startswith(UTF8_COOKIE): + source = source[3:] + else: + for idx, match in enumerate(_line_re.finditer(source)): + match = _coding_re.search(match.group()) + if match is not None: + charset = match.group(1) + break + if idx > 1: + break + + # on broken cookies we fall back to utf-8 too + charset = to_native(charset) + try: + codecs.lookup(charset) + except LookupError: + charset = "utf-8" + + return source.decode(charset, "replace").splitlines() + + def get_context_lines(self, context=5): + before = self.sourcelines[self.lineno - context - 1 : self.lineno - 1] + past = self.sourcelines[self.lineno : self.lineno + context] + return (before, self.current_line, past) + + @property + def current_line(self): + try: + return self.sourcelines[self.lineno - 1] + except IndexError: + return u"" + + @cached_property + def console(self): + return Console(self.globals, self.locals) + + @property + def id(self): + return id(self) diff --git a/venv/lib/python3.7/site-packages/werkzeug/exceptions.py b/venv/lib/python3.7/site-packages/werkzeug/exceptions.py new file mode 100644 index 0000000..fb6528d --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/exceptions.py @@ -0,0 +1,774 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.exceptions + ~~~~~~~~~~~~~~~~~~~ + + This module implements a number of Python exceptions you can raise from + within your views to trigger a standard non-200 response. + + + Usage Example + ------------- + + :: + + from werkzeug.wrappers import BaseRequest + from werkzeug.wsgi import responder + from werkzeug.exceptions import HTTPException, NotFound + + def view(request): + raise NotFound() + + @responder + def application(environ, start_response): + request = BaseRequest(environ) + try: + return view(request) + except HTTPException as e: + return e + + + As you can see from this example those exceptions are callable WSGI + applications. Because of Python 2.4 compatibility those do not extend + from the response objects but only from the python exception class. + + As a matter of fact they are not Werkzeug response objects. However you + can get a response object by calling ``get_response()`` on a HTTP + exception. + + Keep in mind that you have to pass an environment to ``get_response()`` + because some errors fetch additional information from the WSGI + environment. + + If you want to hook in a different exception page to say, a 404 status + code, you can add a second except for a specific subclass of an error:: + + @responder + def application(environ, start_response): + request = BaseRequest(environ) + try: + return view(request) + except NotFound, e: + return not_found(request) + except HTTPException, e: + return e + + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import sys + +import werkzeug + +# Because of bootstrapping reasons we need to manually patch ourselves +# onto our parent module. +werkzeug.exceptions = sys.modules[__name__] + +from ._compat import implements_to_string +from ._compat import integer_types +from ._compat import iteritems +from ._compat import text_type +from ._internal import _get_environ +from .wrappers import Response + + +@implements_to_string +class HTTPException(Exception): + """Baseclass for all HTTP exceptions. This exception can be called as WSGI + application to render a default error page or you can catch the subclasses + of it independently and render nicer error messages. + """ + + code = None + description = None + + def __init__(self, description=None, response=None): + super(Exception, self).__init__() + if description is not None: + self.description = description + self.response = response + + @classmethod + def wrap(cls, exception, name=None): + """Create an exception that is a subclass of the calling HTTP + exception and the ``exception`` argument. + + The first argument to the class will be passed to the + wrapped ``exception``, the rest to the HTTP exception. If + ``self.args`` is not empty, the wrapped exception message is + added to the HTTP exception description. + + .. versionchanged:: 0.15 + The description includes the wrapped exception message. + """ + + class newcls(cls, exception): + def __init__(self, arg=None, *args, **kwargs): + super(cls, self).__init__(*args, **kwargs) + + if arg is None: + exception.__init__(self) + else: + exception.__init__(self, arg) + + def get_description(self, environ=None): + out = super(cls, self).get_description(environ=environ) + + if self.args: + out += "

    {}: {}

    ".format( + exception.__name__, escape(exception.__str__(self)) + ) + + return out + + newcls.__module__ = sys._getframe(1).f_globals.get("__name__") + newcls.__name__ = name or cls.__name__ + exception.__name__ + return newcls + + @property + def name(self): + """The status name.""" + return HTTP_STATUS_CODES.get(self.code, "Unknown Error") + + def get_description(self, environ=None): + """Get the description.""" + return u"

    %s

    " % escape(self.description) + + def get_body(self, environ=None): + """Get the HTML body.""" + return text_type( + ( + u'\n' + u"%(code)s %(name)s\n" + u"

    %(name)s

    \n" + u"%(description)s\n" + ) + % { + "code": self.code, + "name": escape(self.name), + "description": self.get_description(environ), + } + ) + + def get_headers(self, environ=None): + """Get a list of headers.""" + return [("Content-Type", "text/html")] + + def get_response(self, environ=None): + """Get a response object. If one was passed to the exception + it's returned directly. + + :param environ: the optional environ for the request. This + can be used to modify the response depending + on how the request looked like. + :return: a :class:`Response` object or a subclass thereof. + """ + if self.response is not None: + return self.response + if environ is not None: + environ = _get_environ(environ) + headers = self.get_headers(environ) + return Response(self.get_body(environ), self.code, headers) + + def __call__(self, environ, start_response): + """Call the exception as WSGI application. + + :param environ: the WSGI environment. + :param start_response: the response callable provided by the WSGI + server. + """ + response = self.get_response(environ) + return response(environ, start_response) + + def __str__(self): + code = self.code if self.code is not None else "???" + return "%s %s: %s" % (code, self.name, self.description) + + def __repr__(self): + code = self.code if self.code is not None else "???" + return "<%s '%s: %s'>" % (self.__class__.__name__, code, self.name) + + +class BadRequest(HTTPException): + """*400* `Bad Request` + + Raise if the browser sends something to the application the application + or server cannot handle. + """ + + code = 400 + description = ( + "The browser (or proxy) sent a request that this server could " + "not understand." + ) + + +class ClientDisconnected(BadRequest): + """Internal exception that is raised if Werkzeug detects a disconnected + client. Since the client is already gone at that point attempting to + send the error message to the client might not work and might ultimately + result in another exception in the server. Mainly this is here so that + it is silenced by default as far as Werkzeug is concerned. + + Since disconnections cannot be reliably detected and are unspecified + by WSGI to a large extent this might or might not be raised if a client + is gone. + + .. versionadded:: 0.8 + """ + + +class SecurityError(BadRequest): + """Raised if something triggers a security error. This is otherwise + exactly like a bad request error. + + .. versionadded:: 0.9 + """ + + +class BadHost(BadRequest): + """Raised if the submitted host is badly formatted. + + .. versionadded:: 0.11.2 + """ + + +class Unauthorized(HTTPException): + """*401* ``Unauthorized`` + + Raise if the user is not authorized to access a resource. + + The ``www_authenticate`` argument should be used to set the + ``WWW-Authenticate`` header. This is used for HTTP basic auth and + other schemes. Use :class:`~werkzeug.datastructures.WWWAuthenticate` + to create correctly formatted values. Strictly speaking a 401 + response is invalid if it doesn't provide at least one value for + this header, although real clients typically don't care. + + :param description: Override the default message used for the body + of the response. + :param www-authenticate: A single value, or list of values, for the + WWW-Authenticate header. + + .. versionchanged:: 0.15.3 + If the ``www_authenticate`` argument is not set, the + ``WWW-Authenticate`` header is not set. + + .. versionchanged:: 0.15.3 + The ``response`` argument was restored. + + .. versionchanged:: 0.15.1 + ``description`` was moved back as the first argument, restoring + its previous position. + + .. versionchanged:: 0.15.0 + ``www_authenticate`` was added as the first argument, ahead of + ``description``. + """ + + code = 401 + description = ( + "The server could not verify that you are authorized to access" + " the URL requested. You either supplied the wrong credentials" + " (e.g. a bad password), or your browser doesn't understand" + " how to supply the credentials required." + ) + + def __init__(self, description=None, response=None, www_authenticate=None): + HTTPException.__init__(self, description, response) + + if www_authenticate is not None: + if not isinstance(www_authenticate, (tuple, list)): + www_authenticate = (www_authenticate,) + + self.www_authenticate = www_authenticate + + def get_headers(self, environ=None): + headers = HTTPException.get_headers(self, environ) + if self.www_authenticate: + headers.append( + ("WWW-Authenticate", ", ".join([str(x) for x in self.www_authenticate])) + ) + return headers + + +class Forbidden(HTTPException): + """*403* `Forbidden` + + Raise if the user doesn't have the permission for the requested resource + but was authenticated. + """ + + code = 403 + description = ( + "You don't have the permission to access the requested" + " resource. It is either read-protected or not readable by the" + " server." + ) + + +class NotFound(HTTPException): + """*404* `Not Found` + + Raise if a resource does not exist and never existed. + """ + + code = 404 + description = ( + "The requested URL was not found on the server. If you entered" + " the URL manually please check your spelling and try again." + ) + + +class MethodNotAllowed(HTTPException): + """*405* `Method Not Allowed` + + Raise if the server used a method the resource does not handle. For + example `POST` if the resource is view only. Especially useful for REST. + + The first argument for this exception should be a list of allowed methods. + Strictly speaking the response would be invalid if you don't provide valid + methods in the header which you can do with that list. + """ + + code = 405 + description = "The method is not allowed for the requested URL." + + def __init__(self, valid_methods=None, description=None): + """Takes an optional list of valid http methods + starting with werkzeug 0.3 the list will be mandatory.""" + HTTPException.__init__(self, description) + self.valid_methods = valid_methods + + def get_headers(self, environ=None): + headers = HTTPException.get_headers(self, environ) + if self.valid_methods: + headers.append(("Allow", ", ".join(self.valid_methods))) + return headers + + +class NotAcceptable(HTTPException): + """*406* `Not Acceptable` + + Raise if the server can't return any content conforming to the + `Accept` headers of the client. + """ + + code = 406 + + description = ( + "The resource identified by the request is only capable of" + " generating response entities which have content" + " characteristics not acceptable according to the accept" + " headers sent in the request." + ) + + +class RequestTimeout(HTTPException): + """*408* `Request Timeout` + + Raise to signalize a timeout. + """ + + code = 408 + description = ( + "The server closed the network connection because the browser" + " didn't finish the request within the specified time." + ) + + +class Conflict(HTTPException): + """*409* `Conflict` + + Raise to signal that a request cannot be completed because it conflicts + with the current state on the server. + + .. versionadded:: 0.7 + """ + + code = 409 + description = ( + "A conflict happened while processing the request. The" + " resource might have been modified while the request was being" + " processed." + ) + + +class Gone(HTTPException): + """*410* `Gone` + + Raise if a resource existed previously and went away without new location. + """ + + code = 410 + description = ( + "The requested URL is no longer available on this server and" + " there is no forwarding address. If you followed a link from a" + " foreign page, please contact the author of this page." + ) + + +class LengthRequired(HTTPException): + """*411* `Length Required` + + Raise if the browser submitted data but no ``Content-Length`` header which + is required for the kind of processing the server does. + """ + + code = 411 + description = ( + "A request with this method requires a valid Content-" + "Length header." + ) + + +class PreconditionFailed(HTTPException): + """*412* `Precondition Failed` + + Status code used in combination with ``If-Match``, ``If-None-Match``, or + ``If-Unmodified-Since``. + """ + + code = 412 + description = ( + "The precondition on the request for the URL failed positive evaluation." + ) + + +class RequestEntityTooLarge(HTTPException): + """*413* `Request Entity Too Large` + + The status code one should return if the data submitted exceeded a given + limit. + """ + + code = 413 + description = "The data value transmitted exceeds the capacity limit." + + +class RequestURITooLarge(HTTPException): + """*414* `Request URI Too Large` + + Like *413* but for too long URLs. + """ + + code = 414 + description = ( + "The length of the requested URL exceeds the capacity limit for" + " this server. The request cannot be processed." + ) + + +class UnsupportedMediaType(HTTPException): + """*415* `Unsupported Media Type` + + The status code returned if the server is unable to handle the media type + the client transmitted. + """ + + code = 415 + description = ( + "The server does not support the media type transmitted in the request." + ) + + +class RequestedRangeNotSatisfiable(HTTPException): + """*416* `Requested Range Not Satisfiable` + + The client asked for an invalid part of the file. + + .. versionadded:: 0.7 + """ + + code = 416 + description = "The server cannot provide the requested range." + + def __init__(self, length=None, units="bytes", description=None): + """Takes an optional `Content-Range` header value based on ``length`` + parameter. + """ + HTTPException.__init__(self, description) + self.length = length + self.units = units + + def get_headers(self, environ=None): + headers = HTTPException.get_headers(self, environ) + if self.length is not None: + headers.append(("Content-Range", "%s */%d" % (self.units, self.length))) + return headers + + +class ExpectationFailed(HTTPException): + """*417* `Expectation Failed` + + The server cannot meet the requirements of the Expect request-header. + + .. versionadded:: 0.7 + """ + + code = 417 + description = "The server could not meet the requirements of the Expect header" + + +class ImATeapot(HTTPException): + """*418* `I'm a teapot` + + The server should return this if it is a teapot and someone attempted + to brew coffee with it. + + .. versionadded:: 0.7 + """ + + code = 418 + description = "This server is a teapot, not a coffee machine" + + +class UnprocessableEntity(HTTPException): + """*422* `Unprocessable Entity` + + Used if the request is well formed, but the instructions are otherwise + incorrect. + """ + + code = 422 + description = ( + "The request was well-formed but was unable to be followed due" + " to semantic errors." + ) + + +class Locked(HTTPException): + """*423* `Locked` + + Used if the resource that is being accessed is locked. + """ + + code = 423 + description = "The resource that is being accessed is locked." + + +class FailedDependency(HTTPException): + """*424* `Failed Dependency` + + Used if the method could not be performed on the resource + because the requested action depended on another action and that action failed. + """ + + code = 424 + description = ( + "The method could not be performed on the resource because the" + " requested action depended on another action and that action" + " failed." + ) + + +class PreconditionRequired(HTTPException): + """*428* `Precondition Required` + + The server requires this request to be conditional, typically to prevent + the lost update problem, which is a race condition between two or more + clients attempting to update a resource through PUT or DELETE. By requiring + each client to include a conditional header ("If-Match" or "If-Unmodified- + Since") with the proper value retained from a recent GET request, the + server ensures that each client has at least seen the previous revision of + the resource. + """ + + code = 428 + description = ( + "This request is required to be conditional; try using" + ' "If-Match" or "If-Unmodified-Since".' + ) + + +class TooManyRequests(HTTPException): + """*429* `Too Many Requests` + + The server is limiting the rate at which this user receives responses, and + this request exceeds that rate. (The server may use any convenient method + to identify users and their request rates). The server may include a + "Retry-After" header to indicate how long the user should wait before + retrying. + """ + + code = 429 + description = "This user has exceeded an allotted request count. Try again later." + + +class RequestHeaderFieldsTooLarge(HTTPException): + """*431* `Request Header Fields Too Large` + + The server refuses to process the request because the header fields are too + large. One or more individual fields may be too large, or the set of all + headers is too large. + """ + + code = 431 + description = "One or more header fields exceeds the maximum size." + + +class UnavailableForLegalReasons(HTTPException): + """*451* `Unavailable For Legal Reasons` + + This status code indicates that the server is denying access to the + resource as a consequence of a legal demand. + """ + + code = 451 + description = "Unavailable for legal reasons." + + +class InternalServerError(HTTPException): + """*500* `Internal Server Error` + + Raise if an internal server error occurred. This is a good fallback if an + unknown error occurred in the dispatcher. + """ + + code = 500 + description = ( + "The server encountered an internal error and was unable to" + " complete your request. Either the server is overloaded or" + " there is an error in the application." + ) + + +class NotImplemented(HTTPException): + """*501* `Not Implemented` + + Raise if the application does not support the action requested by the + browser. + """ + + code = 501 + description = "The server does not support the action requested by the browser." + + +class BadGateway(HTTPException): + """*502* `Bad Gateway` + + If you do proxying in your application you should return this status code + if you received an invalid response from the upstream server it accessed + in attempting to fulfill the request. + """ + + code = 502 + description = ( + "The proxy server received an invalid response from an upstream server." + ) + + +class ServiceUnavailable(HTTPException): + """*503* `Service Unavailable` + + Status code you should return if a service is temporarily unavailable. + """ + + code = 503 + description = ( + "The server is temporarily unable to service your request due" + " to maintenance downtime or capacity problems. Please try" + " again later." + ) + + +class GatewayTimeout(HTTPException): + """*504* `Gateway Timeout` + + Status code you should return if a connection to an upstream server + times out. + """ + + code = 504 + description = "The connection to an upstream server timed out." + + +class HTTPVersionNotSupported(HTTPException): + """*505* `HTTP Version Not Supported` + + The server does not support the HTTP protocol version used in the request. + """ + + code = 505 + description = ( + "The server does not support the HTTP protocol version used in the request." + ) + + +default_exceptions = {} +__all__ = ["HTTPException"] + + +def _find_exceptions(): + for _name, obj in iteritems(globals()): + try: + is_http_exception = issubclass(obj, HTTPException) + except TypeError: + is_http_exception = False + if not is_http_exception or obj.code is None: + continue + __all__.append(obj.__name__) + old_obj = default_exceptions.get(obj.code, None) + if old_obj is not None and issubclass(obj, old_obj): + continue + default_exceptions[obj.code] = obj + + +_find_exceptions() +del _find_exceptions + + +class Aborter(object): + """When passed a dict of code -> exception items it can be used as + callable that raises exceptions. If the first argument to the + callable is an integer it will be looked up in the mapping, if it's + a WSGI application it will be raised in a proxy exception. + + The rest of the arguments are forwarded to the exception constructor. + """ + + def __init__(self, mapping=None, extra=None): + if mapping is None: + mapping = default_exceptions + self.mapping = dict(mapping) + if extra is not None: + self.mapping.update(extra) + + def __call__(self, code, *args, **kwargs): + if not args and not kwargs and not isinstance(code, integer_types): + raise HTTPException(response=code) + if code not in self.mapping: + raise LookupError("no exception for %r" % code) + raise self.mapping[code](*args, **kwargs) + + +def abort(status, *args, **kwargs): + """Raises an :py:exc:`HTTPException` for the given status code or WSGI + application:: + + abort(404) # 404 Not Found + abort(Response('Hello World')) + + Can be passed a WSGI application or a status code. If a status code is + given it's looked up in the list of exceptions and will raise that + exception, if passed a WSGI application it will wrap it in a proxy WSGI + exception and raise that:: + + abort(404) + abort(Response('Hello World')) + + """ + return _aborter(status, *args, **kwargs) + + +_aborter = Aborter() + + +#: an exception that is used internally to signal both a key error and a +#: bad request. Used by a lot of the datastructures. +BadRequestKeyError = BadRequest.wrap(KeyError) + +# imported here because of circular dependencies of werkzeug.utils +from .http import HTTP_STATUS_CODES +from .utils import escape diff --git a/venv/lib/python3.7/site-packages/werkzeug/filesystem.py b/venv/lib/python3.7/site-packages/werkzeug/filesystem.py new file mode 100644 index 0000000..d016cae --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/filesystem.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.filesystem + ~~~~~~~~~~~~~~~~~~~ + + Various utilities for the local filesystem. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import codecs +import sys +import warnings + +# We do not trust traditional unixes. +has_likely_buggy_unicode_filesystem = ( + sys.platform.startswith("linux") or "bsd" in sys.platform +) + + +def _is_ascii_encoding(encoding): + """Given an encoding this figures out if the encoding is actually ASCII (which + is something we don't actually want in most cases). This is necessary + because ASCII comes under many names such as ANSI_X3.4-1968. + """ + if encoding is None: + return False + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +class BrokenFilesystemWarning(RuntimeWarning, UnicodeWarning): + """The warning used by Werkzeug to signal a broken filesystem. Will only be + used once per runtime.""" + + +_warned_about_filesystem_encoding = False + + +def get_filesystem_encoding(): + """Returns the filesystem encoding that should be used. Note that this is + different from the Python understanding of the filesystem encoding which + might be deeply flawed. Do not use this value against Python's unicode APIs + because it might be different. See :ref:`filesystem-encoding` for the exact + behavior. + + The concept of a filesystem encoding in generally is not something you + should rely on. As such if you ever need to use this function except for + writing wrapper code reconsider. + """ + global _warned_about_filesystem_encoding + rv = sys.getfilesystemencoding() + if has_likely_buggy_unicode_filesystem and not rv or _is_ascii_encoding(rv): + if not _warned_about_filesystem_encoding: + warnings.warn( + "Detected a misconfigured UNIX filesystem: Will use" + " UTF-8 as filesystem encoding instead of {0!r}".format(rv), + BrokenFilesystemWarning, + ) + _warned_about_filesystem_encoding = True + return "utf-8" + return rv diff --git a/venv/lib/python3.7/site-packages/werkzeug/formparser.py b/venv/lib/python3.7/site-packages/werkzeug/formparser.py new file mode 100644 index 0000000..0ddc5c8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/formparser.py @@ -0,0 +1,586 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.formparser + ~~~~~~~~~~~~~~~~~~~ + + This module implements the form parsing. It supports url-encoded forms + as well as non-nested multipart uploads. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import codecs +import re +from functools import update_wrapper +from itertools import chain +from itertools import repeat +from itertools import tee + +from ._compat import BytesIO +from ._compat import text_type +from ._compat import to_native +from .datastructures import FileStorage +from .datastructures import Headers +from .datastructures import MultiDict +from .http import parse_options_header +from .urls import url_decode_stream +from .wsgi import get_content_length +from .wsgi import get_input_stream +from .wsgi import make_line_iter + +# there are some platforms where SpooledTemporaryFile is not available. +# In that case we need to provide a fallback. +try: + from tempfile import SpooledTemporaryFile +except ImportError: + from tempfile import TemporaryFile + + SpooledTemporaryFile = None + + +#: an iterator that yields empty strings +_empty_string_iter = repeat("") + +#: a regular expression for multipart boundaries +_multipart_boundary_re = re.compile("^[ -~]{0,200}[!-~]$") + +#: supported http encodings that are also available in python we support +#: for multipart messages. +_supported_multipart_encodings = frozenset(["base64", "quoted-printable"]) + + +def default_stream_factory( + total_content_length, filename, content_type, content_length=None +): + """The stream factory that is used per default.""" + max_size = 1024 * 500 + if SpooledTemporaryFile is not None: + return SpooledTemporaryFile(max_size=max_size, mode="wb+") + if total_content_length is None or total_content_length > max_size: + return TemporaryFile("wb+") + return BytesIO() + + +def parse_form_data( + environ, + stream_factory=None, + charset="utf-8", + errors="replace", + max_form_memory_size=None, + max_content_length=None, + cls=None, + silent=True, +): + """Parse the form data in the environ and return it as tuple in the form + ``(stream, form, files)``. You should only call this method if the + transport method is `POST`, `PUT`, or `PATCH`. + + If the mimetype of the data transmitted is `multipart/form-data` the + files multidict will be filled with `FileStorage` objects. If the + mimetype is unknown the input stream is wrapped and returned as first + argument, else the stream is empty. + + This is a shortcut for the common usage of :class:`FormDataParser`. + + Have a look at :ref:`dealing-with-request-data` for more details. + + .. versionadded:: 0.5 + The `max_form_memory_size`, `max_content_length` and + `cls` parameters were added. + + .. versionadded:: 0.5.1 + The optional `silent` flag was added. + + :param environ: the WSGI environment to be used for parsing. + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`~BaseResponse._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + :return: A tuple in the form ``(stream, form, files)``. + """ + return FormDataParser( + stream_factory, + charset, + errors, + max_form_memory_size, + max_content_length, + cls, + silent, + ).parse_from_environ(environ) + + +def exhaust_stream(f): + """Helper decorator for methods that exhausts the stream on return.""" + + def wrapper(self, stream, *args, **kwargs): + try: + return f(self, stream, *args, **kwargs) + finally: + exhaust = getattr(stream, "exhaust", None) + if exhaust is not None: + exhaust() + else: + while 1: + chunk = stream.read(1024 * 64) + if not chunk: + break + + return update_wrapper(wrapper, f) + + +class FormDataParser(object): + """This class implements parsing of form data for Werkzeug. By itself + it can parse multipart and url encoded form data. It can be subclassed + and extended but for most mimetypes it is a better idea to use the + untouched stream and expose it as separate attributes on a request + object. + + .. versionadded:: 0.8 + + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`~BaseResponse._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + """ + + def __init__( + self, + stream_factory=None, + charset="utf-8", + errors="replace", + max_form_memory_size=None, + max_content_length=None, + cls=None, + silent=True, + ): + if stream_factory is None: + stream_factory = default_stream_factory + self.stream_factory = stream_factory + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + self.max_content_length = max_content_length + if cls is None: + cls = MultiDict + self.cls = cls + self.silent = silent + + def get_parse_func(self, mimetype, options): + return self.parse_functions.get(mimetype) + + def parse_from_environ(self, environ): + """Parses the information from the environment as form data. + + :param environ: the WSGI environment to be used for parsing. + :return: A tuple in the form ``(stream, form, files)``. + """ + content_type = environ.get("CONTENT_TYPE", "") + content_length = get_content_length(environ) + mimetype, options = parse_options_header(content_type) + return self.parse(get_input_stream(environ), mimetype, content_length, options) + + def parse(self, stream, mimetype, content_length, options=None): + """Parses the information from the given stream, mimetype, + content length and mimetype parameters. + + :param stream: an input stream + :param mimetype: the mimetype of the data + :param content_length: the content length of the incoming data + :param options: optional mimetype parameters (used for + the multipart boundary for instance) + :return: A tuple in the form ``(stream, form, files)``. + """ + if ( + self.max_content_length is not None + and content_length is not None + and content_length > self.max_content_length + ): + raise exceptions.RequestEntityTooLarge() + if options is None: + options = {} + + parse_func = self.get_parse_func(mimetype, options) + if parse_func is not None: + try: + return parse_func(self, stream, mimetype, content_length, options) + except ValueError: + if not self.silent: + raise + + return stream, self.cls(), self.cls() + + @exhaust_stream + def _parse_multipart(self, stream, mimetype, content_length, options): + parser = MultiPartParser( + self.stream_factory, + self.charset, + self.errors, + max_form_memory_size=self.max_form_memory_size, + cls=self.cls, + ) + boundary = options.get("boundary") + if boundary is None: + raise ValueError("Missing boundary") + if isinstance(boundary, text_type): + boundary = boundary.encode("ascii") + form, files = parser.parse(stream, boundary, content_length) + return stream, form, files + + @exhaust_stream + def _parse_urlencoded(self, stream, mimetype, content_length, options): + if ( + self.max_form_memory_size is not None + and content_length is not None + and content_length > self.max_form_memory_size + ): + raise exceptions.RequestEntityTooLarge() + form = url_decode_stream(stream, self.charset, errors=self.errors, cls=self.cls) + return stream, form, self.cls() + + #: mapping of mimetypes to parsing functions + parse_functions = { + "multipart/form-data": _parse_multipart, + "application/x-www-form-urlencoded": _parse_urlencoded, + "application/x-url-encoded": _parse_urlencoded, + } + + +def is_valid_multipart_boundary(boundary): + """Checks if the string given is a valid multipart boundary.""" + return _multipart_boundary_re.match(boundary) is not None + + +def _line_parse(line): + """Removes line ending characters and returns a tuple (`stripped_line`, + `is_terminated`). + """ + if line[-2:] in ["\r\n", b"\r\n"]: + return line[:-2], True + elif line[-1:] in ["\r", "\n", b"\r", b"\n"]: + return line[:-1], True + return line, False + + +def parse_multipart_headers(iterable): + """Parses multipart headers from an iterable that yields lines (including + the trailing newline symbol). The iterable has to be newline terminated. + + The iterable will stop at the line where the headers ended so it can be + further consumed. + + :param iterable: iterable of strings that are newline terminated + """ + result = [] + for line in iterable: + line = to_native(line) + line, line_terminated = _line_parse(line) + if not line_terminated: + raise ValueError("unexpected end of line in multipart header") + if not line: + break + elif line[0] in " \t" and result: + key, value = result[-1] + result[-1] = (key, value + "\n " + line[1:]) + else: + parts = line.split(":", 1) + if len(parts) == 2: + result.append((parts[0].strip(), parts[1].strip())) + + # we link the list to the headers, no need to create a copy, the + # list was not shared anyways. + return Headers(result) + + +_begin_form = "begin_form" +_begin_file = "begin_file" +_cont = "cont" +_end = "end" + + +class MultiPartParser(object): + def __init__( + self, + stream_factory=None, + charset="utf-8", + errors="replace", + max_form_memory_size=None, + cls=None, + buffer_size=64 * 1024, + ): + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + self.stream_factory = ( + default_stream_factory if stream_factory is None else stream_factory + ) + self.cls = MultiDict if cls is None else cls + + # make sure the buffer size is divisible by four so that we can base64 + # decode chunk by chunk + assert buffer_size % 4 == 0, "buffer size has to be divisible by 4" + # also the buffer size has to be at least 1024 bytes long or long headers + # will freak out the system + assert buffer_size >= 1024, "buffer size has to be at least 1KB" + + self.buffer_size = buffer_size + + def _fix_ie_filename(self, filename): + """Internet Explorer 6 transmits the full file name if a file is + uploaded. This function strips the full path if it thinks the + filename is Windows-like absolute. + """ + if filename[1:3] == ":\\" or filename[:2] == "\\\\": + return filename.split("\\")[-1] + return filename + + def _find_terminator(self, iterator): + """The terminator might have some additional newlines before it. + There is at least one application that sends additional newlines + before headers (the python setuptools package). + """ + for line in iterator: + if not line: + break + line = line.strip() + if line: + return line + return b"" + + def fail(self, message): + raise ValueError(message) + + def get_part_encoding(self, headers): + transfer_encoding = headers.get("content-transfer-encoding") + if ( + transfer_encoding is not None + and transfer_encoding in _supported_multipart_encodings + ): + return transfer_encoding + + def get_part_charset(self, headers): + # Figure out input charset for current part + content_type = headers.get("content-type") + if content_type: + mimetype, ct_params = parse_options_header(content_type) + return ct_params.get("charset", self.charset) + return self.charset + + def start_file_streaming(self, filename, headers, total_content_length): + if isinstance(filename, bytes): + filename = filename.decode(self.charset, self.errors) + filename = self._fix_ie_filename(filename) + content_type = headers.get("content-type") + try: + content_length = int(headers["content-length"]) + except (KeyError, ValueError): + content_length = 0 + container = self.stream_factory( + total_content_length=total_content_length, + filename=filename, + content_type=content_type, + content_length=content_length, + ) + return filename, container + + def in_memory_threshold_reached(self, bytes): + raise exceptions.RequestEntityTooLarge() + + def validate_boundary(self, boundary): + if not boundary: + self.fail("Missing boundary") + if not is_valid_multipart_boundary(boundary): + self.fail("Invalid boundary: %s" % boundary) + if len(boundary) > self.buffer_size: # pragma: no cover + # this should never happen because we check for a minimum size + # of 1024 and boundaries may not be longer than 200. The only + # situation when this happens is for non debug builds where + # the assert is skipped. + self.fail("Boundary longer than buffer size") + + def parse_lines(self, file, boundary, content_length, cap_at_buffer=True): + """Generate parts of + ``('begin_form', (headers, name))`` + ``('begin_file', (headers, name, filename))`` + ``('cont', bytestring)`` + ``('end', None)`` + + Always obeys the grammar + parts = ( begin_form cont* end | + begin_file cont* end )* + """ + next_part = b"--" + boundary + last_part = next_part + b"--" + + iterator = chain( + make_line_iter( + file, + limit=content_length, + buffer_size=self.buffer_size, + cap_at_buffer=cap_at_buffer, + ), + _empty_string_iter, + ) + + terminator = self._find_terminator(iterator) + + if terminator == last_part: + return + elif terminator != next_part: + self.fail("Expected boundary at start of multipart data") + + while terminator != last_part: + headers = parse_multipart_headers(iterator) + + disposition = headers.get("content-disposition") + if disposition is None: + self.fail("Missing Content-Disposition header") + disposition, extra = parse_options_header(disposition) + transfer_encoding = self.get_part_encoding(headers) + name = extra.get("name") + filename = extra.get("filename") + + # if no content type is given we stream into memory. A list is + # used as a temporary container. + if filename is None: + yield _begin_form, (headers, name) + + # otherwise we parse the rest of the headers and ask the stream + # factory for something we can write in. + else: + yield _begin_file, (headers, name, filename) + + buf = b"" + for line in iterator: + if not line: + self.fail("unexpected end of stream") + + if line[:2] == b"--": + terminator = line.rstrip() + if terminator in (next_part, last_part): + break + + if transfer_encoding is not None: + if transfer_encoding == "base64": + transfer_encoding = "base64_codec" + try: + line = codecs.decode(line, transfer_encoding) + except Exception: + self.fail("could not decode transfer encoded chunk") + + # we have something in the buffer from the last iteration. + # this is usually a newline delimiter. + if buf: + yield _cont, buf + buf = b"" + + # If the line ends with windows CRLF we write everything except + # the last two bytes. In all other cases however we write + # everything except the last byte. If it was a newline, that's + # fine, otherwise it does not matter because we will write it + # the next iteration. this ensures we do not write the + # final newline into the stream. That way we do not have to + # truncate the stream. However we do have to make sure that + # if something else than a newline is in there we write it + # out. + if line[-2:] == b"\r\n": + buf = b"\r\n" + cutoff = -2 + else: + buf = line[-1:] + cutoff = -1 + yield _cont, line[:cutoff] + + else: # pragma: no cover + raise ValueError("unexpected end of part") + + # if we have a leftover in the buffer that is not a newline + # character we have to flush it, otherwise we will chop of + # certain values. + if buf not in (b"", b"\r", b"\n", b"\r\n"): + yield _cont, buf + + yield _end, None + + def parse_parts(self, file, boundary, content_length): + """Generate ``('file', (name, val))`` and + ``('form', (name, val))`` parts. + """ + in_memory = 0 + + for ellt, ell in self.parse_lines(file, boundary, content_length): + if ellt == _begin_file: + headers, name, filename = ell + is_file = True + guard_memory = False + filename, container = self.start_file_streaming( + filename, headers, content_length + ) + _write = container.write + + elif ellt == _begin_form: + headers, name = ell + is_file = False + container = [] + _write = container.append + guard_memory = self.max_form_memory_size is not None + + elif ellt == _cont: + _write(ell) + # if we write into memory and there is a memory size limit we + # count the number of bytes in memory and raise an exception if + # there is too much data in memory. + if guard_memory: + in_memory += len(ell) + if in_memory > self.max_form_memory_size: + self.in_memory_threshold_reached(in_memory) + + elif ellt == _end: + if is_file: + container.seek(0) + yield ( + "file", + (name, FileStorage(container, filename, name, headers=headers)), + ) + else: + part_charset = self.get_part_charset(headers) + yield ( + "form", + (name, b"".join(container).decode(part_charset, self.errors)), + ) + + def parse(self, file, boundary, content_length): + formstream, filestream = tee( + self.parse_parts(file, boundary, content_length), 2 + ) + form = (p[1] for p in formstream if p[0] == "form") + files = (p[1] for p in filestream if p[0] == "file") + return self.cls(form), self.cls(files) + + +from . import exceptions diff --git a/venv/lib/python3.7/site-packages/werkzeug/http.py b/venv/lib/python3.7/site-packages/werkzeug/http.py new file mode 100644 index 0000000..af32007 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/http.py @@ -0,0 +1,1303 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.http + ~~~~~~~~~~~~~ + + Werkzeug comes with a bunch of utilities that help Werkzeug to deal with + HTTP data. Most of the classes and functions provided by this module are + used by the wrappers, but they are useful on their own, too, especially if + the response and request objects are not used. + + This covers some of the more HTTP centric features of WSGI, some other + utilities such as cookie handling are documented in the `werkzeug.utils` + module. + + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import base64 +import re +import warnings +from datetime import datetime +from datetime import timedelta +from hashlib import md5 +from time import gmtime +from time import time + +from ._compat import integer_types +from ._compat import iteritems +from ._compat import PY2 +from ._compat import string_types +from ._compat import text_type +from ._compat import to_bytes +from ._compat import to_unicode +from ._compat import try_coerce_native +from ._internal import _cookie_parse_impl +from ._internal import _cookie_quote +from ._internal import _make_cookie_domain + +try: + from email.utils import parsedate_tz +except ImportError: + from email.Utils import parsedate_tz + +try: + from urllib.request import parse_http_list as _parse_list_header + from urllib.parse import unquote_to_bytes as _unquote +except ImportError: + from urllib2 import parse_http_list as _parse_list_header + from urllib2 import unquote as _unquote + +_cookie_charset = "latin1" +_basic_auth_charset = "utf-8" +# for explanation of "media-range", etc. see Sections 5.3.{1,2} of RFC 7231 +_accept_re = re.compile( + r""" + ( # media-range capturing-parenthesis + [^\s;,]+ # type/subtype + (?:[ \t]*;[ \t]* # ";" + (?: # parameter non-capturing-parenthesis + [^\s;,q][^\s;,]* # token that doesn't start with "q" + | # or + q[^\s;,=][^\s;,]* # token that is more than just "q" + ) + )* # zero or more parameters + ) # end of media-range + (?:[ \t]*;[ \t]*q= # weight is a "q" parameter + (\d*(?:\.\d+)?) # qvalue capturing-parentheses + [^,]* # "extension" accept params: who cares? + )? # accept params are optional + """, + re.VERBOSE, +) +_token_chars = frozenset( + "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~" +) +_etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)') +_unsafe_header_chars = set('()<>@,;:"/[]?={} \t') +_option_header_piece_re = re.compile( + r""" + ;\s*,?\s* # newlines were replaced with commas + (?P + "[^"\\]*(?:\\.[^"\\]*)*" # quoted string + | + [^\s;,=*]+ # token + ) + (?:\*(?P\d+))? # *1, optional continuation index + \s* + (?: # optionally followed by =value + (?: # equals sign, possibly with encoding + \*\s*=\s* # * indicates extended notation + (?: # optional encoding + (?P[^\s]+?) + '(?P[^\s]*?)' + )? + | + =\s* # basic notation + ) + (?P + "[^"\\]*(?:\\.[^"\\]*)*" # quoted string + | + [^;,]+ # token + )? + )? + \s* + """, + flags=re.VERBOSE, +) +_option_header_start_mime_type = re.compile(r",\s*([^;,\s]+)([;,]\s*.+)?") + +_entity_headers = frozenset( + [ + "allow", + "content-encoding", + "content-language", + "content-length", + "content-location", + "content-md5", + "content-range", + "content-type", + "expires", + "last-modified", + ] +) +_hop_by_hop_headers = frozenset( + [ + "connection", + "keep-alive", + "proxy-authenticate", + "proxy-authorization", + "te", + "trailer", + "transfer-encoding", + "upgrade", + ] +) + + +HTTP_STATUS_CODES = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi Status", + 226: "IM Used", # see RFC 3229 + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", # unused + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", # see RFC 2324 + 421: "Misdirected Request", # see RFC 7540 + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 426: "Upgrade Required", + 428: "Precondition Required", # see RFC 6585 + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 449: "Retry With", # proprietary MS extension + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 507: "Insufficient Storage", + 510: "Not Extended", +} + + +def wsgi_to_bytes(data): + """coerce wsgi unicode represented bytes to real ones""" + if isinstance(data, bytes): + return data + return data.encode("latin1") # XXX: utf8 fallback? + + +def bytes_to_wsgi(data): + assert isinstance(data, bytes), "data must be bytes" + if isinstance(data, str): + return data + else: + return data.decode("latin1") + + +def quote_header_value(value, extra_chars="", allow_token=True): + """Quote a header value if necessary. + + .. versionadded:: 0.5 + + :param value: the value to quote. + :param extra_chars: a list of extra characters to skip quoting. + :param allow_token: if this is enabled token values are returned + unchanged. + """ + if isinstance(value, bytes): + value = bytes_to_wsgi(value) + value = str(value) + if allow_token: + token_chars = _token_chars | set(extra_chars) + if set(value).issubset(token_chars): + return value + return '"%s"' % value.replace("\\", "\\\\").replace('"', '\\"') + + +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + .. versionadded:: 0.5 + + :param value: the header value to unquote. + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != "\\\\": + return value.replace("\\\\", "\\").replace('\\"', '"') + return value + + +def dump_options_header(header, options): + """The reverse function to :func:`parse_options_header`. + + :param header: the header to dump + :param options: a dict of options to append. + """ + segments = [] + if header is not None: + segments.append(header) + for key, value in iteritems(options): + if value is None: + segments.append(key) + else: + segments.append("%s=%s" % (key, quote_header_value(value))) + return "; ".join(segments) + + +def dump_header(iterable, allow_token=True): + """Dump an HTTP header again. This is the reversal of + :func:`parse_list_header`, :func:`parse_set_header` and + :func:`parse_dict_header`. This also quotes strings that include an + equals sign unless you pass it as dict of key, value pairs. + + >>> dump_header({'foo': 'bar baz'}) + 'foo="bar baz"' + >>> dump_header(('foo', 'bar baz')) + 'foo, "bar baz"' + + :param iterable: the iterable or dict of values to quote. + :param allow_token: if set to `False` tokens as values are disallowed. + See :func:`quote_header_value` for more details. + """ + if isinstance(iterable, dict): + items = [] + for key, value in iteritems(iterable): + if value is None: + items.append(key) + else: + items.append( + "%s=%s" % (key, quote_header_value(value, allow_token=allow_token)) + ) + else: + items = [quote_header_value(x, allow_token=allow_token) for x in iterable] + return ", ".join(items) + + +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +def parse_dict_header(value, cls=dict): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict (or any other mapping object created from + the type with a dict like interface provided by the `cls` argument): + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + .. versionchanged:: 0.9 + Added support for `cls` argument. + + :param value: a string with a dict header. + :param cls: callable to use for storage of parsed results. + :return: an instance of `cls` + """ + result = cls() + if not isinstance(value, text_type): + # XXX: validate + value = bytes_to_wsgi(value) + for item in _parse_list_header(value): + if "=" not in item: + result[item] = None + continue + name, value = item.split("=", 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +def parse_options_header(value, multiple=False): + """Parse a ``Content-Type`` like header into a tuple with the content + type and the options: + + >>> parse_options_header('text/html; charset=utf8') + ('text/html', {'charset': 'utf8'}) + + This should not be used to parse ``Cache-Control`` like headers that use + a slightly different format. For these headers use the + :func:`parse_dict_header` function. + + .. versionchanged:: 0.15 + :rfc:`2231` parameter continuations are handled. + + .. versionadded:: 0.5 + + :param value: the header to parse. + :param multiple: Whether try to parse and return multiple MIME types + :return: (mimetype, options) or (mimetype, options, mimetype, options, …) + if multiple=True + """ + if not value: + return "", {} + + result = [] + + value = "," + value.replace("\n", ",") + while value: + match = _option_header_start_mime_type.match(value) + if not match: + break + result.append(match.group(1)) # mimetype + options = {} + # Parse options + rest = match.group(2) + continued_encoding = None + while rest: + optmatch = _option_header_piece_re.match(rest) + if not optmatch: + break + option, count, encoding, language, option_value = optmatch.groups() + # Continuations don't have to supply the encoding after the + # first line. If we're in a continuation, track the current + # encoding to use for subsequent lines. Reset it when the + # continuation ends. + if not count: + continued_encoding = None + else: + if not encoding: + encoding = continued_encoding + continued_encoding = encoding + option = unquote_header_value(option) + if option_value is not None: + option_value = unquote_header_value(option_value, option == "filename") + if encoding is not None: + option_value = _unquote(option_value).decode(encoding) + if count: + # Continuations append to the existing value. For + # simplicity, this ignores the possibility of + # out-of-order indices, which shouldn't happen anyway. + options[option] = options.get(option, "") + option_value + else: + options[option] = option_value + rest = rest[optmatch.end() :] + result.append(options) + if multiple is False: + return tuple(result) + value = rest + + return tuple(result) if result else ("", {}) + + +def parse_accept_header(value, cls=None): + """Parses an HTTP Accept-* header. This does not implement a complete + valid algorithm but one that supports at least value and quality + extraction. + + Returns a new :class:`Accept` object (basically a list of ``(value, quality)`` + tuples sorted by the quality with some additional accessor methods). + + The second parameter can be a subclass of :class:`Accept` that is created + with the parsed values and returned. + + :param value: the accept header string to be parsed. + :param cls: the wrapper class for the return value (can be + :class:`Accept` or a subclass thereof) + :return: an instance of `cls`. + """ + if cls is None: + cls = Accept + + if not value: + return cls(None) + + result = [] + for match in _accept_re.finditer(value): + quality = match.group(2) + if not quality: + quality = 1 + else: + quality = max(min(float(quality), 1), 0) + result.append((match.group(1), quality)) + return cls(result) + + +def parse_cache_control_header(value, on_update=None, cls=None): + """Parse a cache control header. The RFC differs between response and + request cache control, this method does not. It's your responsibility + to not use the wrong control statements. + + .. versionadded:: 0.5 + The `cls` was added. If not specified an immutable + :class:`~werkzeug.datastructures.RequestCacheControl` is returned. + + :param value: a cache control header to be parsed. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.CacheControl` + object is changed. + :param cls: the class for the returned object. By default + :class:`~werkzeug.datastructures.RequestCacheControl` is used. + :return: a `cls` object. + """ + if cls is None: + cls = RequestCacheControl + if not value: + return cls(None, on_update) + return cls(parse_dict_header(value), on_update) + + +def parse_set_header(value, on_update=None): + """Parse a set-like header and return a + :class:`~werkzeug.datastructures.HeaderSet` object: + + >>> hs = parse_set_header('token, "quoted value"') + + The return value is an object that treats the items case-insensitively + and keeps the order of the items: + + >>> 'TOKEN' in hs + True + >>> hs.index('quoted value') + 1 + >>> hs + HeaderSet(['token', 'quoted value']) + + To create a header from the :class:`HeaderSet` again, use the + :func:`dump_header` function. + + :param value: a set header to be parsed. + :param on_update: an optional callable that is called every time a + value on the :class:`~werkzeug.datastructures.HeaderSet` + object is changed. + :return: a :class:`~werkzeug.datastructures.HeaderSet` + """ + if not value: + return HeaderSet(None, on_update) + return HeaderSet(parse_list_header(value), on_update) + + +def parse_authorization_header(value): + """Parse an HTTP basic/digest authorization header transmitted by the web + browser. The return value is either `None` if the header was invalid or + not given, otherwise an :class:`~werkzeug.datastructures.Authorization` + object. + + :param value: the authorization header to parse. + :return: a :class:`~werkzeug.datastructures.Authorization` object or `None`. + """ + if not value: + return + value = wsgi_to_bytes(value) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except ValueError: + return + if auth_type == b"basic": + try: + username, password = base64.b64decode(auth_info).split(b":", 1) + except Exception: + return + return Authorization( + "basic", + { + "username": to_unicode(username, _basic_auth_charset), + "password": to_unicode(password, _basic_auth_charset), + }, + ) + elif auth_type == b"digest": + auth_map = parse_dict_header(auth_info) + for key in "username", "realm", "nonce", "uri", "response": + if key not in auth_map: + return + if "qop" in auth_map: + if not auth_map.get("nc") or not auth_map.get("cnonce"): + return + return Authorization("digest", auth_map) + + +def parse_www_authenticate_header(value, on_update=None): + """Parse an HTTP WWW-Authenticate header into a + :class:`~werkzeug.datastructures.WWWAuthenticate` object. + + :param value: a WWW-Authenticate header to parse. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.WWWAuthenticate` + object is changed. + :return: a :class:`~werkzeug.datastructures.WWWAuthenticate` object. + """ + if not value: + return WWWAuthenticate(on_update=on_update) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except (ValueError, AttributeError): + return WWWAuthenticate(value.strip().lower(), on_update=on_update) + return WWWAuthenticate(auth_type, parse_dict_header(auth_info), on_update) + + +def parse_if_range_header(value): + """Parses an if-range header which can be an etag or a date. Returns + a :class:`~werkzeug.datastructures.IfRange` object. + + .. versionadded:: 0.7 + """ + if not value: + return IfRange() + date = parse_date(value) + if date is not None: + return IfRange(date=date) + # drop weakness information + return IfRange(unquote_etag(value)[0]) + + +def parse_range_header(value, make_inclusive=True): + """Parses a range header into a :class:`~werkzeug.datastructures.Range` + object. If the header is missing or malformed `None` is returned. + `ranges` is a list of ``(start, stop)`` tuples where the ranges are + non-inclusive. + + .. versionadded:: 0.7 + """ + if not value or "=" not in value: + return None + + ranges = [] + last_end = 0 + units, rng = value.split("=", 1) + units = units.strip().lower() + + for item in rng.split(","): + item = item.strip() + if "-" not in item: + return None + if item.startswith("-"): + if last_end < 0: + return None + try: + begin = int(item) + except ValueError: + return None + end = None + last_end = -1 + elif "-" in item: + begin, end = item.split("-", 1) + begin = begin.strip() + end = end.strip() + if not begin.isdigit(): + return None + begin = int(begin) + if begin < last_end or last_end < 0: + return None + if end: + if not end.isdigit(): + return None + end = int(end) + 1 + if begin >= end: + return None + else: + end = None + last_end = end + ranges.append((begin, end)) + + return Range(units, ranges) + + +def parse_content_range_header(value, on_update=None): + """Parses a range header into a + :class:`~werkzeug.datastructures.ContentRange` object or `None` if + parsing is not possible. + + .. versionadded:: 0.7 + + :param value: a content range header to be parsed. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.ContentRange` + object is changed. + """ + if value is None: + return None + try: + units, rangedef = (value or "").strip().split(None, 1) + except ValueError: + return None + + if "/" not in rangedef: + return None + rng, length = rangedef.split("/", 1) + if length == "*": + length = None + elif length.isdigit(): + length = int(length) + else: + return None + + if rng == "*": + return ContentRange(units, None, None, length, on_update=on_update) + elif "-" not in rng: + return None + + start, stop = rng.split("-", 1) + try: + start = int(start) + stop = int(stop) + 1 + except ValueError: + return None + + if is_byte_range_valid(start, stop, length): + return ContentRange(units, start, stop, length, on_update=on_update) + + +def quote_etag(etag, weak=False): + """Quote an etag. + + :param etag: the etag to quote. + :param weak: set to `True` to tag it "weak". + """ + if '"' in etag: + raise ValueError("invalid etag") + etag = '"%s"' % etag + if weak: + etag = "W/" + etag + return etag + + +def unquote_etag(etag): + """Unquote a single etag: + + >>> unquote_etag('W/"bar"') + ('bar', True) + >>> unquote_etag('"bar"') + ('bar', False) + + :param etag: the etag identifier to unquote. + :return: a ``(etag, weak)`` tuple. + """ + if not etag: + return None, None + etag = etag.strip() + weak = False + if etag.startswith(("W/", "w/")): + weak = True + etag = etag[2:] + if etag[:1] == etag[-1:] == '"': + etag = etag[1:-1] + return etag, weak + + +def parse_etags(value): + """Parse an etag header. + + :param value: the tag header to parse + :return: an :class:`~werkzeug.datastructures.ETags` object. + """ + if not value: + return ETags() + strong = [] + weak = [] + end = len(value) + pos = 0 + while pos < end: + match = _etag_re.match(value, pos) + if match is None: + break + is_weak, quoted, raw = match.groups() + if raw == "*": + return ETags(star_tag=True) + elif quoted: + raw = quoted + if is_weak: + weak.append(raw) + else: + strong.append(raw) + pos = match.end() + return ETags(strong, weak) + + +def generate_etag(data): + """Generate an etag for some data.""" + return md5(data).hexdigest() + + +def parse_date(value): + """Parse one of the following date formats into a datetime object: + + .. sourcecode:: text + + Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 + Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 + Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format + + If parsing fails the return value is `None`. + + :param value: a string with a supported date format. + :return: a :class:`datetime.datetime` object. + """ + if value: + t = parsedate_tz(value.strip()) + if t is not None: + try: + year = t[0] + # unfortunately that function does not tell us if two digit + # years were part of the string, or if they were prefixed + # with two zeroes. So what we do is to assume that 69-99 + # refer to 1900, and everything below to 2000 + if year >= 0 and year <= 68: + year += 2000 + elif year >= 69 and year <= 99: + year += 1900 + return datetime(*((year,) + t[1:7])) - timedelta(seconds=t[-1] or 0) + except (ValueError, OverflowError): + return None + + +def _dump_date(d, delim): + """Used for `http_date` and `cookie_date`.""" + if d is None: + d = gmtime() + elif isinstance(d, datetime): + d = d.utctimetuple() + elif isinstance(d, (integer_types, float)): + d = gmtime(d) + return "%s, %02d%s%s%s%s %02d:%02d:%02d GMT" % ( + ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")[d.tm_wday], + d.tm_mday, + delim, + ( + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + )[d.tm_mon - 1], + delim, + str(d.tm_year), + d.tm_hour, + d.tm_min, + d.tm_sec, + ) + + +def cookie_date(expires=None): + """Formats the time to ensure compatibility with Netscape's cookie + standard. + + Accepts a floating point number expressed in seconds since the epoch in, a + datetime object or a timetuple. All times in UTC. The :func:`parse_date` + function can be used to parse such a date. + + Outputs a string in the format ``Wdy, DD-Mon-YYYY HH:MM:SS GMT``. + + :param expires: If provided that date is used, otherwise the current. + """ + return _dump_date(expires, "-") + + +def http_date(timestamp=None): + """Formats the time to match the RFC1123 date format. + + Accepts a floating point number expressed in seconds since the epoch in, a + datetime object or a timetuple. All times in UTC. The :func:`parse_date` + function can be used to parse such a date. + + Outputs a string in the format ``Wdy, DD Mon YYYY HH:MM:SS GMT``. + + :param timestamp: If provided that date is used, otherwise the current. + """ + return _dump_date(timestamp, " ") + + +def parse_age(value=None): + """Parses a base-10 integer count of seconds into a timedelta. + + If parsing fails, the return value is `None`. + + :param value: a string consisting of an integer represented in base-10 + :return: a :class:`datetime.timedelta` object or `None`. + """ + if not value: + return None + try: + seconds = int(value) + except ValueError: + return None + if seconds < 0: + return None + try: + return timedelta(seconds=seconds) + except OverflowError: + return None + + +def dump_age(age=None): + """Formats the duration as a base-10 integer. + + :param age: should be an integer number of seconds, + a :class:`datetime.timedelta` object, or, + if the age is unknown, `None` (default). + """ + if age is None: + return + if isinstance(age, timedelta): + # do the equivalent of Python 2.7's timedelta.total_seconds(), + # but disregarding fractional seconds + age = age.seconds + (age.days * 24 * 3600) + + age = int(age) + if age < 0: + raise ValueError("age cannot be negative") + + return str(age) + + +def is_resource_modified( + environ, etag=None, data=None, last_modified=None, ignore_if_range=True +): + """Convenience method for conditional requests. + + :param environ: the WSGI environment of the request to be checked. + :param etag: the etag for the response for comparison. + :param data: or alternatively the data of the response to automatically + generate an etag using :func:`generate_etag`. + :param last_modified: an optional date of the last modification. + :param ignore_if_range: If `False`, `If-Range` header will be taken into + account. + :return: `True` if the resource was modified, otherwise `False`. + """ + if etag is None and data is not None: + etag = generate_etag(data) + elif data is not None: + raise TypeError("both data and etag given") + if environ["REQUEST_METHOD"] not in ("GET", "HEAD"): + return False + + unmodified = False + if isinstance(last_modified, string_types): + last_modified = parse_date(last_modified) + + # ensure that microsecond is zero because the HTTP spec does not transmit + # that either and we might have some false positives. See issue #39 + if last_modified is not None: + last_modified = last_modified.replace(microsecond=0) + + if_range = None + if not ignore_if_range and "HTTP_RANGE" in environ: + # https://tools.ietf.org/html/rfc7233#section-3.2 + # A server MUST ignore an If-Range header field received in a request + # that does not contain a Range header field. + if_range = parse_if_range_header(environ.get("HTTP_IF_RANGE")) + + if if_range is not None and if_range.date is not None: + modified_since = if_range.date + else: + modified_since = parse_date(environ.get("HTTP_IF_MODIFIED_SINCE")) + + if modified_since and last_modified and last_modified <= modified_since: + unmodified = True + + if etag: + etag, _ = unquote_etag(etag) + if if_range is not None and if_range.etag is not None: + unmodified = parse_etags(if_range.etag).contains(etag) + else: + if_none_match = parse_etags(environ.get("HTTP_IF_NONE_MATCH")) + if if_none_match: + # https://tools.ietf.org/html/rfc7232#section-3.2 + # "A recipient MUST use the weak comparison function when comparing + # entity-tags for If-None-Match" + unmodified = if_none_match.contains_weak(etag) + + # https://tools.ietf.org/html/rfc7232#section-3.1 + # "Origin server MUST use the strong comparison function when + # comparing entity-tags for If-Match" + if_match = parse_etags(environ.get("HTTP_IF_MATCH")) + if if_match: + unmodified = not if_match.is_strong(etag) + + return not unmodified + + +def remove_entity_headers(headers, allowed=("expires", "content-location")): + """Remove all entity headers from a list or :class:`Headers` object. This + operation works in-place. `Expires` and `Content-Location` headers are + by default not removed. The reason for this is :rfc:`2616` section + 10.3.5 which specifies some entity headers that should be sent. + + .. versionchanged:: 0.5 + added `allowed` parameter. + + :param headers: a list or :class:`Headers` object. + :param allowed: a list of headers that should still be allowed even though + they are entity headers. + """ + allowed = set(x.lower() for x in allowed) + headers[:] = [ + (key, value) + for key, value in headers + if not is_entity_header(key) or key.lower() in allowed + ] + + +def remove_hop_by_hop_headers(headers): + """Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or + :class:`Headers` object. This operation works in-place. + + .. versionadded:: 0.5 + + :param headers: a list or :class:`Headers` object. + """ + headers[:] = [ + (key, value) for key, value in headers if not is_hop_by_hop_header(key) + ] + + +def is_entity_header(header): + """Check if a header is an entity header. + + .. versionadded:: 0.5 + + :param header: the header to test. + :return: `True` if it's an entity header, `False` otherwise. + """ + return header.lower() in _entity_headers + + +def is_hop_by_hop_header(header): + """Check if a header is an HTTP/1.1 "Hop-by-Hop" header. + + .. versionadded:: 0.5 + + :param header: the header to test. + :return: `True` if it's an HTTP/1.1 "Hop-by-Hop" header, `False` otherwise. + """ + return header.lower() in _hop_by_hop_headers + + +def parse_cookie(header, charset="utf-8", errors="replace", cls=None): + """Parse a cookie. Either from a string or WSGI environ. + + Per default encoding errors are ignored. If you want a different behavior + you can set `errors` to ``'replace'`` or ``'strict'``. In strict mode a + :exc:`HTTPUnicodeError` is raised. + + .. versionchanged:: 0.5 + This function now returns a :class:`TypeConversionDict` instead of a + regular dict. The `cls` parameter was added. + + :param header: the header to be used to parse the cookie. Alternatively + this can be a WSGI environment. + :param charset: the charset for the cookie values. + :param errors: the error behavior for the charset decoding. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`TypeConversionDict` is + used. + """ + if isinstance(header, dict): + header = header.get("HTTP_COOKIE", "") + elif header is None: + header = "" + + # If the value is an unicode string it's mangled through latin1. This + # is done because on PEP 3333 on Python 3 all headers are assumed latin1 + # which however is incorrect for cookies, which are sent in page encoding. + # As a result we + if isinstance(header, text_type): + header = header.encode("latin1", "replace") + + if cls is None: + cls = TypeConversionDict + + def _parse_pairs(): + for key, val in _cookie_parse_impl(header): + key = to_unicode(key, charset, errors, allow_none_charset=True) + if not key: + continue + val = to_unicode(val, charset, errors, allow_none_charset=True) + yield try_coerce_native(key), val + + return cls(_parse_pairs()) + + +def dump_cookie( + key, + value="", + max_age=None, + expires=None, + path="/", + domain=None, + secure=False, + httponly=False, + charset="utf-8", + sync_expires=True, + max_size=4093, + samesite=None, +): + """Creates a new Set-Cookie header without the ``Set-Cookie`` prefix + The parameters are the same as in the cookie Morsel object in the + Python standard library but it accepts unicode data, too. + + On Python 3 the return value of this function will be a unicode + string, on Python 2 it will be a native string. In both cases the + return value is usually restricted to ascii as the vast majority of + values are properly escaped, but that is no guarantee. If a unicode + string is returned it's tunneled through latin1 as required by + PEP 3333. + + The return value is not ASCII safe if the key contains unicode + characters. This is technically against the specification but + happens in the wild. It's strongly recommended to not use + non-ASCII values for the keys. + + :param max_age: should be a number of seconds, or `None` (default) if + the cookie should last only as long as the client's + browser session. Additionally `timedelta` objects + are accepted, too. + :param expires: should be a `datetime` object or unix timestamp. + :param path: limits the cookie to a given path, per default it will + span the whole domain. + :param domain: Use this if you want to set a cross-domain cookie. For + example, ``domain=".example.com"`` will set a cookie + that is readable by the domain ``www.example.com``, + ``foo.example.com`` etc. Otherwise, a cookie will only + be readable by the domain that set it. + :param secure: The cookie will only be available via HTTPS + :param httponly: disallow JavaScript to access the cookie. This is an + extension to the cookie standard and probably not + supported by all browsers. + :param charset: the encoding for unicode values. + :param sync_expires: automatically set expires if max_age is defined + but expires not. + :param max_size: Warn if the final header value exceeds this size. The + default, 4093, should be safely `supported by most browsers + `_. Set to 0 to disable this check. + :param samesite: Limits the scope of the cookie such that it will only + be attached to requests if those requests are "same-site". + + .. _`cookie`: http://browsercookielimits.squawky.net/ + """ + key = to_bytes(key, charset) + value = to_bytes(value, charset) + + if path is not None: + path = iri_to_uri(path, charset) + domain = _make_cookie_domain(domain) + if isinstance(max_age, timedelta): + max_age = (max_age.days * 60 * 60 * 24) + max_age.seconds + if expires is not None: + if not isinstance(expires, string_types): + expires = cookie_date(expires) + elif max_age is not None and sync_expires: + expires = to_bytes(cookie_date(time() + max_age)) + + samesite = samesite.title() if samesite else None + if samesite not in ("Strict", "Lax", None): + raise ValueError("invalid SameSite value; must be 'Strict', 'Lax' or None") + + buf = [key + b"=" + _cookie_quote(value)] + + # XXX: In theory all of these parameters that are not marked with `None` + # should be quoted. Because stdlib did not quote it before I did not + # want to introduce quoting there now. + for k, v, q in ( + (b"Domain", domain, True), + (b"Expires", expires, False), + (b"Max-Age", max_age, False), + (b"Secure", secure, None), + (b"HttpOnly", httponly, None), + (b"Path", path, False), + (b"SameSite", samesite, False), + ): + if q is None: + if v: + buf.append(k) + continue + + if v is None: + continue + + tmp = bytearray(k) + if not isinstance(v, (bytes, bytearray)): + v = to_bytes(text_type(v), charset) + if q: + v = _cookie_quote(v) + tmp += b"=" + v + buf.append(bytes(tmp)) + + # The return value will be an incorrectly encoded latin1 header on + # Python 3 for consistency with the headers object and a bytestring + # on Python 2 because that's how the API makes more sense. + rv = b"; ".join(buf) + if not PY2: + rv = rv.decode("latin1") + + # Warn if the final value of the cookie is less than the limit. If the + # cookie is too large, then it may be silently ignored, which can be quite + # hard to debug. + cookie_size = len(rv) + + if max_size and cookie_size > max_size: + value_size = len(value) + warnings.warn( + 'The "{key}" cookie is too large: the value was {value_size} bytes' + " but the header required {extra_size} extra bytes. The final size" + " was {cookie_size} bytes but the limit is {max_size} bytes." + " Browsers may silently ignore cookies larger than this.".format( + key=key, + value_size=value_size, + extra_size=cookie_size - value_size, + cookie_size=cookie_size, + max_size=max_size, + ), + stacklevel=2, + ) + + return rv + + +def is_byte_range_valid(start, stop, length): + """Checks if a given byte content range is valid for the given length. + + .. versionadded:: 0.7 + """ + if (start is None) != (stop is None): + return False + elif start is None: + return length is None or length >= 0 + elif length is None: + return 0 <= start < stop + elif start >= stop: + return False + return 0 <= start < length + + +# circular dependency fun +from .datastructures import Accept +from .datastructures import Authorization +from .datastructures import ContentRange +from .datastructures import ETags +from .datastructures import HeaderSet +from .datastructures import IfRange +from .datastructures import Range +from .datastructures import RequestCacheControl +from .datastructures import TypeConversionDict +from .datastructures import WWWAuthenticate +from .urls import iri_to_uri + +# DEPRECATED +from .datastructures import CharsetAccept as _CharsetAccept +from .datastructures import Headers as _Headers +from .datastructures import LanguageAccept as _LanguageAccept +from .datastructures import MIMEAccept as _MIMEAccept + + +class MIMEAccept(_MIMEAccept): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.http.MIMEAccept' has moved to 'werkzeug" + ".datastructures.MIMEAccept' as of version 0.5. This old" + " import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(MIMEAccept, self).__init__(*args, **kwargs) + + +class CharsetAccept(_CharsetAccept): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.http.CharsetAccept' has moved to 'werkzeug" + ".datastructures.CharsetAccept' as of version 0.5. This old" + " import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(CharsetAccept, self).__init__(*args, **kwargs) + + +class LanguageAccept(_LanguageAccept): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.http.LanguageAccept' has moved to 'werkzeug" + ".datastructures.LanguageAccept' as of version 0.5. This" + " old import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(LanguageAccept, self).__init__(*args, **kwargs) + + +class Headers(_Headers): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.http.Headers' has moved to 'werkzeug" + ".datastructures.Headers' as of version 0.5. This old" + " import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(Headers, self).__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/local.py b/venv/lib/python3.7/site-packages/werkzeug/local.py new file mode 100644 index 0000000..9a6088c --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/local.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.local + ~~~~~~~~~~~~~~ + + This module implements context-local objects. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import copy +from functools import update_wrapper + +from ._compat import implements_bool +from ._compat import PY2 +from .wsgi import ClosingIterator + +# since each thread has its own greenlet we can just use those as identifiers +# for the context. If greenlets are not available we fall back to the +# current thread ident depending on where it is. +try: + from greenlet import getcurrent as get_ident +except ImportError: + try: + from thread import get_ident + except ImportError: + from _thread import get_ident + + +def release_local(local): + """Releases the contents of the local for the current context. + This makes it possible to use locals without a manager. + + Example:: + + >>> loc = Local() + >>> loc.foo = 42 + >>> release_local(loc) + >>> hasattr(loc, 'foo') + False + + With this function one can release :class:`Local` objects as well + as :class:`LocalStack` objects. However it is not possible to + release data held by proxies that way, one always has to retain + a reference to the underlying local object in order to be able + to release it. + + .. versionadded:: 0.6.1 + """ + local.__release_local__() + + +class Local(object): + __slots__ = ("__storage__", "__ident_func__") + + def __init__(self): + object.__setattr__(self, "__storage__", {}) + object.__setattr__(self, "__ident_func__", get_ident) + + def __iter__(self): + return iter(self.__storage__.items()) + + def __call__(self, proxy): + """Create a proxy for a name.""" + return LocalProxy(self, proxy) + + def __release_local__(self): + self.__storage__.pop(self.__ident_func__(), None) + + def __getattr__(self, name): + try: + return self.__storage__[self.__ident_func__()][name] + except KeyError: + raise AttributeError(name) + + def __setattr__(self, name, value): + ident = self.__ident_func__() + storage = self.__storage__ + try: + storage[ident][name] = value + except KeyError: + storage[ident] = {name: value} + + def __delattr__(self, name): + try: + del self.__storage__[self.__ident_func__()][name] + except KeyError: + raise AttributeError(name) + + +class LocalStack(object): + """This class works similar to a :class:`Local` but keeps a stack + of objects instead. This is best explained with an example:: + + >>> ls = LocalStack() + >>> ls.push(42) + >>> ls.top + 42 + >>> ls.push(23) + >>> ls.top + 23 + >>> ls.pop() + 23 + >>> ls.top + 42 + + They can be force released by using a :class:`LocalManager` or with + the :func:`release_local` function but the correct way is to pop the + item from the stack after using. When the stack is empty it will + no longer be bound to the current context (and as such released). + + By calling the stack without arguments it returns a proxy that resolves to + the topmost item on the stack. + + .. versionadded:: 0.6.1 + """ + + def __init__(self): + self._local = Local() + + def __release_local__(self): + self._local.__release_local__() + + def _get__ident_func__(self): + return self._local.__ident_func__ + + def _set__ident_func__(self, value): + object.__setattr__(self._local, "__ident_func__", value) + + __ident_func__ = property(_get__ident_func__, _set__ident_func__) + del _get__ident_func__, _set__ident_func__ + + def __call__(self): + def _lookup(): + rv = self.top + if rv is None: + raise RuntimeError("object unbound") + return rv + + return LocalProxy(_lookup) + + def push(self, obj): + """Pushes a new item to the stack""" + rv = getattr(self._local, "stack", None) + if rv is None: + self._local.stack = rv = [] + rv.append(obj) + return rv + + def pop(self): + """Removes the topmost item from the stack, will return the + old value or `None` if the stack was already empty. + """ + stack = getattr(self._local, "stack", None) + if stack is None: + return None + elif len(stack) == 1: + release_local(self._local) + return stack[-1] + else: + return stack.pop() + + @property + def top(self): + """The topmost item on the stack. If the stack is empty, + `None` is returned. + """ + try: + return self._local.stack[-1] + except (AttributeError, IndexError): + return None + + +class LocalManager(object): + """Local objects cannot manage themselves. For that you need a local + manager. You can pass a local manager multiple locals or add them later + by appending them to `manager.locals`. Every time the manager cleans up, + it will clean up all the data left in the locals for this context. + + The `ident_func` parameter can be added to override the default ident + function for the wrapped locals. + + .. versionchanged:: 0.6.1 + Instead of a manager the :func:`release_local` function can be used + as well. + + .. versionchanged:: 0.7 + `ident_func` was added. + """ + + def __init__(self, locals=None, ident_func=None): + if locals is None: + self.locals = [] + elif isinstance(locals, Local): + self.locals = [locals] + else: + self.locals = list(locals) + if ident_func is not None: + self.ident_func = ident_func + for local in self.locals: + object.__setattr__(local, "__ident_func__", ident_func) + else: + self.ident_func = get_ident + + def get_ident(self): + """Return the context identifier the local objects use internally for + this context. You cannot override this method to change the behavior + but use it to link other context local objects (such as SQLAlchemy's + scoped sessions) to the Werkzeug locals. + + .. versionchanged:: 0.7 + You can pass a different ident function to the local manager that + will then be propagated to all the locals passed to the + constructor. + """ + return self.ident_func() + + def cleanup(self): + """Manually clean up the data in the locals for this context. Call + this at the end of the request or use `make_middleware()`. + """ + for local in self.locals: + release_local(local) + + def make_middleware(self, app): + """Wrap a WSGI application so that cleaning up happens after + request end. + """ + + def application(environ, start_response): + return ClosingIterator(app(environ, start_response), self.cleanup) + + return application + + def middleware(self, func): + """Like `make_middleware` but for decorating functions. + + Example usage:: + + @manager.middleware + def application(environ, start_response): + ... + + The difference to `make_middleware` is that the function passed + will have all the arguments copied from the inner application + (name, docstring, module). + """ + return update_wrapper(self.make_middleware(func), func) + + def __repr__(self): + return "<%s storages: %d>" % (self.__class__.__name__, len(self.locals)) + + +@implements_bool +class LocalProxy(object): + """Acts as a proxy for a werkzeug local. Forwards all operations to + a proxied object. The only operations not supported for forwarding + are right handed operands and any kind of assignment. + + Example usage:: + + from werkzeug.local import Local + l = Local() + + # these are proxies + request = l('request') + user = l('user') + + + from werkzeug.local import LocalStack + _response_local = LocalStack() + + # this is a proxy + response = _response_local() + + Whenever something is bound to l.user / l.request the proxy objects + will forward all operations. If no object is bound a :exc:`RuntimeError` + will be raised. + + To create proxies to :class:`Local` or :class:`LocalStack` objects, + call the object as shown above. If you want to have a proxy to an + object looked up by a function, you can (as of Werkzeug 0.6.1) pass + a function to the :class:`LocalProxy` constructor:: + + session = LocalProxy(lambda: get_current_request().session) + + .. versionchanged:: 0.6.1 + The class can be instantiated with a callable as well now. + """ + + __slots__ = ("__local", "__dict__", "__name__", "__wrapped__") + + def __init__(self, local, name=None): + object.__setattr__(self, "_LocalProxy__local", local) + object.__setattr__(self, "__name__", name) + if callable(local) and not hasattr(local, "__release_local__"): + # "local" is a callable that is not an instance of Local or + # LocalManager: mark it as a wrapped function. + object.__setattr__(self, "__wrapped__", local) + + def _get_current_object(self): + """Return the current object. This is useful if you want the real + object behind the proxy at a time for performance reasons or because + you want to pass the object into a different context. + """ + if not hasattr(self.__local, "__release_local__"): + return self.__local() + try: + return getattr(self.__local, self.__name__) + except AttributeError: + raise RuntimeError("no object bound to %s" % self.__name__) + + @property + def __dict__(self): + try: + return self._get_current_object().__dict__ + except RuntimeError: + raise AttributeError("__dict__") + + def __repr__(self): + try: + obj = self._get_current_object() + except RuntimeError: + return "<%s unbound>" % self.__class__.__name__ + return repr(obj) + + def __bool__(self): + try: + return bool(self._get_current_object()) + except RuntimeError: + return False + + def __unicode__(self): + try: + return unicode(self._get_current_object()) # noqa + except RuntimeError: + return repr(self) + + def __dir__(self): + try: + return dir(self._get_current_object()) + except RuntimeError: + return [] + + def __getattr__(self, name): + if name == "__members__": + return dir(self._get_current_object()) + return getattr(self._get_current_object(), name) + + def __setitem__(self, key, value): + self._get_current_object()[key] = value + + def __delitem__(self, key): + del self._get_current_object()[key] + + if PY2: + __getslice__ = lambda x, i, j: x._get_current_object()[i:j] + + def __setslice__(self, i, j, seq): + self._get_current_object()[i:j] = seq + + def __delslice__(self, i, j): + del self._get_current_object()[i:j] + + __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v) + __delattr__ = lambda x, n: delattr(x._get_current_object(), n) + __str__ = lambda x: str(x._get_current_object()) + __lt__ = lambda x, o: x._get_current_object() < o + __le__ = lambda x, o: x._get_current_object() <= o + __eq__ = lambda x, o: x._get_current_object() == o + __ne__ = lambda x, o: x._get_current_object() != o + __gt__ = lambda x, o: x._get_current_object() > o + __ge__ = lambda x, o: x._get_current_object() >= o + __cmp__ = lambda x, o: cmp(x._get_current_object(), o) # noqa + __hash__ = lambda x: hash(x._get_current_object()) + __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw) + __len__ = lambda x: len(x._get_current_object()) + __getitem__ = lambda x, i: x._get_current_object()[i] + __iter__ = lambda x: iter(x._get_current_object()) + __contains__ = lambda x, i: i in x._get_current_object() + __add__ = lambda x, o: x._get_current_object() + o + __sub__ = lambda x, o: x._get_current_object() - o + __mul__ = lambda x, o: x._get_current_object() * o + __floordiv__ = lambda x, o: x._get_current_object() // o + __mod__ = lambda x, o: x._get_current_object() % o + __divmod__ = lambda x, o: x._get_current_object().__divmod__(o) + __pow__ = lambda x, o: x._get_current_object() ** o + __lshift__ = lambda x, o: x._get_current_object() << o + __rshift__ = lambda x, o: x._get_current_object() >> o + __and__ = lambda x, o: x._get_current_object() & o + __xor__ = lambda x, o: x._get_current_object() ^ o + __or__ = lambda x, o: x._get_current_object() | o + __div__ = lambda x, o: x._get_current_object().__div__(o) + __truediv__ = lambda x, o: x._get_current_object().__truediv__(o) + __neg__ = lambda x: -(x._get_current_object()) + __pos__ = lambda x: +(x._get_current_object()) + __abs__ = lambda x: abs(x._get_current_object()) + __invert__ = lambda x: ~(x._get_current_object()) + __complex__ = lambda x: complex(x._get_current_object()) + __int__ = lambda x: int(x._get_current_object()) + __long__ = lambda x: long(x._get_current_object()) # noqa + __float__ = lambda x: float(x._get_current_object()) + __oct__ = lambda x: oct(x._get_current_object()) + __hex__ = lambda x: hex(x._get_current_object()) + __index__ = lambda x: x._get_current_object().__index__() + __coerce__ = lambda x, o: x._get_current_object().__coerce__(x, o) + __enter__ = lambda x: x._get_current_object().__enter__() + __exit__ = lambda x, *a, **kw: x._get_current_object().__exit__(*a, **kw) + __radd__ = lambda x, o: o + x._get_current_object() + __rsub__ = lambda x, o: o - x._get_current_object() + __rmul__ = lambda x, o: o * x._get_current_object() + __rdiv__ = lambda x, o: o / x._get_current_object() + if PY2: + __rtruediv__ = lambda x, o: x._get_current_object().__rtruediv__(o) + else: + __rtruediv__ = __rdiv__ + __rfloordiv__ = lambda x, o: o // x._get_current_object() + __rmod__ = lambda x, o: o % x._get_current_object() + __rdivmod__ = lambda x, o: x._get_current_object().__rdivmod__(o) + __copy__ = lambda x: copy.copy(x._get_current_object()) + __deepcopy__ = lambda x, memo: copy.deepcopy(x._get_current_object(), memo) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py new file mode 100644 index 0000000..5e049f5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/middleware/__init__.py @@ -0,0 +1,25 @@ +""" +Middleware +========== + +A WSGI middleware is a WSGI application that wraps another application +in order to observe or change its behavior. Werkzeug provides some +middleware for common use cases. + +.. toctree:: + :maxdepth: 1 + + proxy_fix + shared_data + dispatcher + http_proxy + lint + profiler + +The :doc:`interactive debugger ` is also a middleware that can +be applied manually, although it is typically used automatically with +the :doc:`development server `. + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff39b969b01147599043fc7bb89a96f424e96af0 GIT binary patch literal 762 zcmYjPOK%e~5Z?4cWvM@a3z`duN+g?tO3JE4P>>J@5K<~tLP#5DJ=rz&+Qy#UJbn-o zf2mh4+~LHD*-cwAlC61o9^W^vhfA(E`BJZYD^?6w@?G-b(P&(mI=&U?~Kbj;iyjGnVXTCu<# zS*W0vwvonco`5t|xu&d`oi3d=p1I~o2U&q^$kj~!&b8812`2q^7=i-D#Fdev$atY>BW7?hdpmqKd}AcH6CaNUHxKfhk>>f2 zB=CRPU4Pru2i;1-w3Q)UI>S4TsUN52>lxAZ#p(0wSWZs-h9=)~6&7b>meQt|sn>p} wZ6t0y^xO5~bS-UqxB7H-`v=nhbftN&t)@I5`OVGYdF@nVaQcu(`OPQ!2T=6({Qv*} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ae77eeff6c0e2d471d4105ccf553191a04441b6 GIT binary patch literal 2451 zcmZ`)TW=dh6yA&DxJwEZRNN$_QBYMPC2vtw{rkU9|7Qlgxymn<9W0v zb#VKgPY~?vDZ>Uzh*%zTEm@=`&!u6U8I|nDl0DhJzsdNF(tMBSOjMc;%hO;mjB}OY zaGJx`TOu%!4wGC8W+nT5sb!M0pC3PBaBt772EjUu(!l^O%M(5zP4Mbis~kSSmF?1% z4&Rk*Ccb5M40Do=(jnX9N0RZN$D;$82)5pV(-=AH>lCIjC3ToEm9U5Wh;K()WjQOO zNf9wzXF45{$pB~Qv!~NzgMc)=#DKF2)ADdAjde_@DwGVK88S7na*#QadKJl)Q~QW$ zlGFz~TaT=N54TxgAzbT**-MA9U_HsK0>S#J#;H+2S;DeW0#+8AJX4FvnT4*(*K2@4 zsLVi?v0)APS-_O@`T&<#k}xE?YY~n zi8)b!?sVsbhu+i}U!L}&DJA$r*Ksz|K~E);O_~T8P<1fiHd8fkwxU(blgDL2;v8DR zqzsTmpl8WkDVqXE`L#8rKo(=QR2|CJ1ae5UY!N;K;y{ZKeygvMiOL|&Ro{YfUJ?@$ z3v`#{YR(4Kih+A&iaaPoI5%WBOp9&t%#{9RTK3fmitcqPmPJ^Z231Qn?TB!phei+o z4gAezyb8B)LZ|Su1?6A{ynu?^Uh>91!W-91(@XxiW@OygB&$iuAC8{G@am+QX>|m$ zHjlV&_R|TrY0LkJN%M)+2d8ql+dQr&(<`W1#f1)eueyQsluxVG z*-0XBl{zG26Y(1+h5N!@o-e&KUwCJ=leX{+|Ddkhgq7XD|>*<8md{1>=h zMeU{c6cT53F;~=!THpKFIjbFh_yoz^hej*wL+6~;Ul$(c^TmAOe*%l5e#$DhW|E4TR%%E39EYhE!|O!vL*jmMjvov^*W^}|wa?C;9l zLNcyvg96DdNJ|Y(;f?2Ia-?w6b>By(bslPIvJ^!;t{Z#LbuSRxkV$lJ0=Ihs%^?p} zE(hJqDcXQacpR2z!-Nl{g}r>$$pB!80AUzj!@~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9eb03644846a5b1256a71d7f612aa5dcf267cfcb GIT binary patch literal 6366 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/lint.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/lint.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0db7183dfa196e7502dcfc754b3b3dd9fc3a0c7e GIT binary patch literal 11674 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 I60$1%2k^VjssI20 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..56b4ea66466cb1eba7d9572906a425cc9143f7aa GIT binary patch literal 8338 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"`` (default): + The host header is automatically rewritten to the URL of the + target. + ``None``: + The host header is unmodified from the client request. + Any other value: + The host header is overwritten with the value. + ``headers``: + A dictionary of headers to be sent with the request to the + target. The default is ``{}``. + ``ssl_context``: + A :class:`ssl.SSLContext` defining how to verify requests if the + target is HTTPS. The default is ``None``. + + In the example above, everything under ``"/static/"`` is proxied to + the server on port 5001. The host header is rewritten to the target, + and the ``"/static/"`` prefix is removed from the URLs. + + :param app: The WSGI application to wrap. + :param targets: Proxy target configurations. See description above. + :param chunk_size: Size of chunks to read from input stream and + write to target. + :param timeout: Seconds before an operation to a target fails. + + .. versionadded:: 0.14 + """ + + def __init__(self, app, targets, chunk_size=2 << 13, timeout=10): + def _set_defaults(opts): + opts.setdefault("remove_prefix", False) + opts.setdefault("host", "") + opts.setdefault("headers", {}) + opts.setdefault("ssl_context", None) + return opts + + self.app = app + self.targets = dict( + ("/%s/" % k.strip("/"), _set_defaults(v)) for k, v in targets.items() + ) + self.chunk_size = chunk_size + self.timeout = timeout + + def proxy_to(self, opts, path, prefix): + target = url_parse(opts["target"]) + + def application(environ, start_response): + headers = list(EnvironHeaders(environ).items()) + headers[:] = [ + (k, v) + for k, v in headers + if not is_hop_by_hop_header(k) + and k.lower() not in ("content-length", "host") + ] + headers.append(("Connection", "close")) + + if opts["host"] == "": + headers.append(("Host", target.ascii_host)) + elif opts["host"] is None: + headers.append(("Host", environ["HTTP_HOST"])) + else: + headers.append(("Host", opts["host"])) + + headers.extend(opts["headers"].items()) + remote_path = path + + if opts["remove_prefix"]: + remote_path = "%s/%s" % ( + target.path.rstrip("/"), + remote_path[len(prefix) :].lstrip("/"), + ) + + content_length = environ.get("CONTENT_LENGTH") + chunked = False + + if content_length not in ("", None): + headers.append(("Content-Length", content_length)) + elif content_length is not None: + headers.append(("Transfer-Encoding", "chunked")) + chunked = True + + try: + if target.scheme == "http": + con = client.HTTPConnection( + target.ascii_host, target.port or 80, timeout=self.timeout + ) + elif target.scheme == "https": + con = client.HTTPSConnection( + target.ascii_host, + target.port or 443, + timeout=self.timeout, + context=opts["ssl_context"], + ) + else: + raise RuntimeError( + "Target scheme must be 'http' or 'https', got '{}'.".format( + target.scheme + ) + ) + + con.connect() + remote_url = url_quote(remote_path) + querystring = environ["QUERY_STRING"] + + if querystring: + remote_url = remote_url + "?" + querystring + + con.putrequest(environ["REQUEST_METHOD"], remote_url, skip_host=True) + + for k, v in headers: + if k.lower() == "connection": + v = "close" + + con.putheader(k, v) + + con.endheaders() + stream = get_input_stream(environ) + + while 1: + data = stream.read(self.chunk_size) + + if not data: + break + + if chunked: + con.send(b"%x\r\n%s\r\n" % (len(data), data)) + else: + con.send(data) + + resp = con.getresponse() + except socket.error: + from ..exceptions import BadGateway + + return BadGateway()(environ, start_response) + + start_response( + "%d %s" % (resp.status, resp.reason), + [ + (k.title(), v) + for k, v in resp.getheaders() + if not is_hop_by_hop_header(k) + ], + ) + + def read(): + while 1: + try: + data = resp.read(self.chunk_size) + except socket.error: + break + + if not data: + break + + yield data + + return read() + + return application + + def __call__(self, environ, start_response): + path = environ["PATH_INFO"] + app = self.app + + for prefix, opts in self.targets.items(): + if path.startswith(prefix): + app = self.proxy_to(opts, path, prefix) + break + + return app(environ, start_response) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py new file mode 100644 index 0000000..98f9581 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/middleware/lint.py @@ -0,0 +1,408 @@ +""" +WSGI Protocol Linter +==================== + +This module provides a middleware that performs sanity checks on the +behavior of the WSGI server and application. It checks that the +:pep:`3333` WSGI spec is properly implemented. It also warns on some +common HTTP errors such as non-empty responses for 304 status codes. + +.. autoclass:: LintMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +from warnings import warn + +from .._compat import implements_iterator +from .._compat import PY2 +from .._compat import string_types +from ..datastructures import Headers +from ..http import is_entity_header +from ..wsgi import FileWrapper + +try: + from urllib.parse import urlparse +except ImportError: + from urlparse import urlparse + + +class WSGIWarning(Warning): + """Warning class for WSGI warnings.""" + + +class HTTPWarning(Warning): + """Warning class for HTTP warnings.""" + + +def check_string(context, obj, stacklevel=3): + if type(obj) is not str: + warn( + "'%s' requires strings, got '%s'" % (context, type(obj).__name__), + WSGIWarning, + ) + + +class InputStream(object): + def __init__(self, stream): + self._stream = stream + + def read(self, *args): + if len(args) == 0: + warn( + "WSGI does not guarantee an EOF marker on the input stream, thus making" + " calls to 'wsgi.input.read()' unsafe. Conforming servers may never" + " return from this call.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) != 1: + warn( + "Too many parameters passed to 'wsgi.input.read()'.", + WSGIWarning, + stacklevel=2, + ) + return self._stream.read(*args) + + def readline(self, *args): + if len(args) == 0: + warn( + "Calls to 'wsgi.input.readline()' without arguments are unsafe. Use" + " 'wsgi.input.read()' instead.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) == 1: + warn( + "'wsgi.input.readline()' was called with a size hint. WSGI does not" + " support this, although it's available on all major servers.", + WSGIWarning, + stacklevel=2, + ) + else: + raise TypeError("Too many arguments passed to 'wsgi.input.readline()'.") + return self._stream.readline(*args) + + def __iter__(self): + try: + return iter(self._stream) + except TypeError: + warn("'wsgi.input' is not iterable.", WSGIWarning, stacklevel=2) + return iter(()) + + def close(self): + warn("The application closed the input stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class ErrorStream(object): + def __init__(self, stream): + self._stream = stream + + def write(self, s): + check_string("wsgi.error.write()", s) + self._stream.write(s) + + def flush(self): + self._stream.flush() + + def writelines(self, seq): + for line in seq: + self.write(line) + + def close(self): + warn("The application closed the error stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class GuardedWrite(object): + def __init__(self, write, chunks): + self._write = write + self._chunks = chunks + + def __call__(self, s): + check_string("write()", s) + self._write.write(s) + self._chunks.append(len(s)) + + +@implements_iterator +class GuardedIterator(object): + def __init__(self, iterator, headers_set, chunks): + self._iterator = iterator + if PY2: + self._next = iter(iterator).next + else: + self._next = iter(iterator).__next__ + self.closed = False + self.headers_set = headers_set + self.chunks = chunks + + def __iter__(self): + return self + + def __next__(self): + if self.closed: + warn("Iterated over closed 'app_iter'.", WSGIWarning, stacklevel=2) + + rv = self._next() + + if not self.headers_set: + warn( + "The application returned before it started the response.", + WSGIWarning, + stacklevel=2, + ) + + check_string("application iterator items", rv) + self.chunks.append(len(rv)) + return rv + + def close(self): + self.closed = True + + if hasattr(self._iterator, "close"): + self._iterator.close() + + if self.headers_set: + status_code, headers = self.headers_set + bytes_sent = sum(self.chunks) + content_length = headers.get("content-length", type=int) + + if status_code == 304: + for key, _value in headers: + key = key.lower() + if key not in ("expires", "content-location") and is_entity_header( + key + ): + warn( + "Entity header %r found in 304 response." % key, HTTPWarning + ) + if bytes_sent: + warn("304 responses must not have a body.", HTTPWarning) + elif 100 <= status_code < 200 or status_code == 204: + if content_length != 0: + warn( + "%r responses must have an empty content length." % status_code, + HTTPWarning, + ) + if bytes_sent: + warn( + "%r responses must not have a body." % status_code, HTTPWarning + ) + elif content_length is not None and content_length != bytes_sent: + warn( + "Content-Length and the number of bytes sent to the client do not" + " match.", + WSGIWarning, + ) + + def __del__(self): + if not self.closed: + try: + warn( + "Iterator was garbage collected before it was closed.", WSGIWarning + ) + except Exception: + pass + + +class LintMiddleware(object): + """Warns about common errors in the WSGI and HTTP behavior of the + server and wrapped application. Some of the issues it check are: + + - invalid status codes + - non-bytestrings sent to the WSGI server + - strings returned from the WSGI application + - non-empty conditional responses + - unquoted etags + - relative URLs in the Location header + - unsafe calls to wsgi.input + - unclosed iterators + + Error information is emitted using the :mod:`warnings` module. + + :param app: The WSGI application to wrap. + + .. code-block:: python + + from werkzeug.middleware.lint import LintMiddleware + app = LintMiddleware(app) + """ + + def __init__(self, app): + self.app = app + + def check_environ(self, environ): + if type(environ) is not dict: + warn( + "WSGI environment is not a standard Python dict.", + WSGIWarning, + stacklevel=4, + ) + for key in ( + "REQUEST_METHOD", + "SERVER_NAME", + "SERVER_PORT", + "wsgi.version", + "wsgi.input", + "wsgi.errors", + "wsgi.multithread", + "wsgi.multiprocess", + "wsgi.run_once", + ): + if key not in environ: + warn( + "Required environment key %r not found" % key, + WSGIWarning, + stacklevel=3, + ) + if environ["wsgi.version"] != (1, 0): + warn("Environ is not a WSGI 1.0 environ.", WSGIWarning, stacklevel=3) + + script_name = environ.get("SCRIPT_NAME", "") + path_info = environ.get("PATH_INFO", "") + + if script_name and script_name[0] != "/": + warn( + "'SCRIPT_NAME' does not start with a slash: %r" % script_name, + WSGIWarning, + stacklevel=3, + ) + + if path_info and path_info[0] != "/": + warn( + "'PATH_INFO' does not start with a slash: %r" % path_info, + WSGIWarning, + stacklevel=3, + ) + + def check_start_response(self, status, headers, exc_info): + check_string("status", status) + status_code = status.split(None, 1)[0] + + if len(status_code) != 3 or not status_code.isdigit(): + warn(WSGIWarning("Status code must be three digits"), stacklevel=3) + + if len(status) < 4 or status[3] != " ": + warn( + WSGIWarning( + "Invalid value for status %r. Valid " + "status strings are three digits, a space " + "and a status explanation" + ), + stacklevel=3, + ) + + status_code = int(status_code) + + if status_code < 100: + warn(WSGIWarning("status code < 100 detected"), stacklevel=3) + + if type(headers) is not list: + warn(WSGIWarning("header list is not a list"), stacklevel=3) + + for item in headers: + if type(item) is not tuple or len(item) != 2: + warn(WSGIWarning("Headers must tuple 2-item tuples"), stacklevel=3) + name, value = item + if type(name) is not str or type(value) is not str: + warn(WSGIWarning("header items must be strings"), stacklevel=3) + if name.lower() == "status": + warn( + WSGIWarning( + "The status header is not supported due to " + "conflicts with the CGI spec." + ), + stacklevel=3, + ) + + if exc_info is not None and not isinstance(exc_info, tuple): + warn(WSGIWarning("invalid value for exc_info"), stacklevel=3) + + headers = Headers(headers) + self.check_headers(headers) + + return status_code, headers + + def check_headers(self, headers): + etag = headers.get("etag") + + if etag is not None: + if etag.startswith(("W/", "w/")): + if etag.startswith("w/"): + warn( + HTTPWarning("weak etag indicator should be upcase."), + stacklevel=4, + ) + + etag = etag[2:] + + if not (etag[:1] == etag[-1:] == '"'): + warn(HTTPWarning("unquoted etag emitted."), stacklevel=4) + + location = headers.get("location") + + if location is not None: + if not urlparse(location).netloc: + warn( + HTTPWarning("absolute URLs required for location header"), + stacklevel=4, + ) + + def check_iterator(self, app_iter): + if isinstance(app_iter, string_types): + warn( + "The application returned astring. The response will send one character" + " at a time to the client, which will kill performance. Return a list" + " or iterable instead.", + WSGIWarning, + stacklevel=3, + ) + + def __call__(self, *args, **kwargs): + if len(args) != 2: + warn("A WSGI app takes two arguments.", WSGIWarning, stacklevel=2) + + if kwargs: + warn( + "A WSGI app does not take keyword arguments.", WSGIWarning, stacklevel=2 + ) + + environ, start_response = args + + self.check_environ(environ) + environ["wsgi.input"] = InputStream(environ["wsgi.input"]) + environ["wsgi.errors"] = ErrorStream(environ["wsgi.errors"]) + + # Hook our own file wrapper in so that applications will always + # iterate to the end and we can check the content length. + environ["wsgi.file_wrapper"] = FileWrapper + + headers_set = [] + chunks = [] + + def checking_start_response(*args, **kwargs): + if len(args) not in (2, 3): + warn( + "Invalid number of arguments: %s, expected 2 or 3." % len(args), + WSGIWarning, + stacklevel=2, + ) + + if kwargs: + warn("'start_response' does not take keyword arguments.", WSGIWarning) + + status, headers = args[:2] + + if len(args) == 3: + exc_info = args[2] + else: + exc_info = None + + headers_set[:] = self.check_start_response(status, headers, exc_info) + return GuardedWrite(start_response(status, headers, exc_info), chunks) + + app_iter = self.app(environ, checking_start_response) + self.check_iterator(app_iter) + return GuardedIterator(app_iter, headers_set, chunks) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py new file mode 100644 index 0000000..32a14d9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/middleware/profiler.py @@ -0,0 +1,132 @@ +""" +Application Profiler +==================== + +This module provides a middleware that profiles each request with the +:mod:`cProfile` module. This can help identify bottlenecks in your code +that may be slowing down your application. + +.. autoclass:: ProfilerMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +from __future__ import print_function + +import os.path +import sys +import time +from pstats import Stats + +try: + from cProfile import Profile +except ImportError: + from profile import Profile + + +class ProfilerMiddleware(object): + """Wrap a WSGI application and profile the execution of each + request. Responses are buffered so that timings are more exact. + + If ``stream`` is given, :class:`pstats.Stats` are written to it + after each request. If ``profile_dir`` is given, :mod:`cProfile` + data files are saved to that directory, one file per request. + + The filename can be customized by passing ``filename_format``. If + it is a string, it will be formatted using :meth:`str.format` with + the following fields available: + + - ``{method}`` - The request method; GET, POST, etc. + - ``{path}`` - The request path or 'root' should one not exist. + - ``{elapsed}`` - The elapsed time of the request. + - ``{time}`` - The time of the request. + + If it is a callable, it will be called with the WSGI ``environ`` + dict and should return a filename. + + :param app: The WSGI application to wrap. + :param stream: Write stats to this stream. Disable with ``None``. + :param sort_by: A tuple of columns to sort stats by. See + :meth:`pstats.Stats.sort_stats`. + :param restrictions: A tuple of restrictions to filter stats by. See + :meth:`pstats.Stats.print_stats`. + :param profile_dir: Save profile data files to this directory. + :param filename_format: Format string for profile data file names, + or a callable returning a name. See explanation above. + + .. code-block:: python + + from werkzeug.middleware.profiler import ProfilerMiddleware + app = ProfilerMiddleware(app) + + .. versionchanged:: 0.15 + Stats are written even if ``profile_dir`` is given, and can be + disable by passing ``stream=None``. + + .. versionadded:: 0.15 + Added ``filename_format``. + + .. versionadded:: 0.9 + Added ``restrictions`` and ``profile_dir``. + """ + + def __init__( + self, + app, + stream=sys.stdout, + sort_by=("time", "calls"), + restrictions=(), + profile_dir=None, + filename_format="{method}.{path}.{elapsed:.0f}ms.{time:.0f}.prof", + ): + self._app = app + self._stream = stream + self._sort_by = sort_by + self._restrictions = restrictions + self._profile_dir = profile_dir + self._filename_format = filename_format + + def __call__(self, environ, start_response): + response_body = [] + + def catching_start_response(status, headers, exc_info=None): + start_response(status, headers, exc_info) + return response_body.append + + def runapp(): + app_iter = self._app(environ, catching_start_response) + response_body.extend(app_iter) + + if hasattr(app_iter, "close"): + app_iter.close() + + profile = Profile() + start = time.time() + profile.runcall(runapp) + body = b"".join(response_body) + elapsed = time.time() - start + + if self._profile_dir is not None: + if callable(self._filename_format): + filename = self._filename_format(environ) + else: + filename = self._filename_format.format( + method=environ["REQUEST_METHOD"], + path=( + environ.get("PATH_INFO").strip("/").replace("/", ".") or "root" + ), + elapsed=elapsed * 1000.0, + time=time.time(), + ) + filename = os.path.join(self._profile_dir, filename) + profile.dump_stats(filename) + + if self._stream is not None: + stats = Stats(profile, stream=self._stream) + stats.sort_stats(*self._sort_by) + print("-" * 80, file=self._stream) + print("PATH: {!r}".format(environ.get("PATH_INFO", "")), file=self._stream) + stats.print_stats(*self._restrictions) + print("-" * 80 + "\n", file=self._stream) + + return [body] diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py new file mode 100644 index 0000000..dc1dacc --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/middleware/proxy_fix.py @@ -0,0 +1,228 @@ +""" +X-Forwarded-For Proxy Fix +========================= + +This module provides a middleware that adjusts the WSGI environ based on +``X-Forwarded-`` headers that proxies in front of an application may +set. + +When an application is running behind a proxy server, WSGI may see the +request as coming from that server rather than the real client. Proxies +set various headers to track where the request actually came from. + +This middleware should only be applied if the application is actually +behind such a proxy, and should be configured with the number of proxies +that are chained in front of it. Not all proxies set all the headers. +Since incoming headers can be faked, you must set how many proxies are +setting each header so the middleware knows what to trust. + +.. autoclass:: ProxyFix + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import warnings + + +class ProxyFix(object): + """Adjust the WSGI environ based on ``X-Forwarded-`` that proxies in + front of the application may set. + + - ``X-Forwarded-For`` sets ``REMOTE_ADDR``. + - ``X-Forwarded-Proto`` sets ``wsgi.url_scheme``. + - ``X-Forwarded-Host`` sets ``HTTP_HOST``, ``SERVER_NAME``, and + ``SERVER_PORT``. + - ``X-Forwarded-Port`` sets ``HTTP_HOST`` and ``SERVER_PORT``. + - ``X-Forwarded-Prefix`` sets ``SCRIPT_NAME``. + + You must tell the middleware how many proxies set each header so it + knows what values to trust. It is a security issue to trust values + that came from the client rather than a proxy. + + The original values of the headers are stored in the WSGI + environ as ``werkzeug.proxy_fix.orig``, a dict. + + :param app: The WSGI application to wrap. + :param x_for: Number of values to trust for ``X-Forwarded-For``. + :param x_proto: Number of values to trust for ``X-Forwarded-Proto``. + :param x_host: Number of values to trust for ``X-Forwarded-Host``. + :param x_port: Number of values to trust for ``X-Forwarded-Port``. + :param x_prefix: Number of values to trust for + ``X-Forwarded-Prefix``. + :param num_proxies: Deprecated, use ``x_for`` instead. + + .. code-block:: python + + from werkzeug.middleware.proxy_fix import ProxyFix + # App is behind one proxy that sets the -For and -Host headers. + app = ProxyFix(app, x_for=1, x_host=1) + + .. versionchanged:: 0.15 + All headers support multiple values. The ``num_proxies`` + argument is deprecated. Each header is configured with a + separate number of trusted proxies. + + .. versionchanged:: 0.15 + Original WSGI environ values are stored in the + ``werkzeug.proxy_fix.orig`` dict. ``orig_remote_addr``, + ``orig_wsgi_url_scheme``, and ``orig_http_host`` are deprecated + and will be removed in 1.0. + + .. versionchanged:: 0.15 + Support ``X-Forwarded-Port`` and ``X-Forwarded-Prefix``. + + .. versionchanged:: 0.15 + ``X-Fowarded-Host`` and ``X-Forwarded-Port`` modify + ``SERVER_NAME`` and ``SERVER_PORT``. + """ + + def __init__( + self, app, num_proxies=None, x_for=1, x_proto=0, x_host=0, x_port=0, x_prefix=0 + ): + self.app = app + self.x_for = x_for + self.x_proto = x_proto + self.x_host = x_host + self.x_port = x_port + self.x_prefix = x_prefix + self.num_proxies = num_proxies + + @property + def num_proxies(self): + """The number of proxies setting ``X-Forwarded-For`` in front + of the application. + + .. deprecated:: 0.15 + A separate number of trusted proxies is configured for each + header. ``num_proxies`` maps to ``x_for``. This method will + be removed in 1.0. + + :internal: + """ + warnings.warn( + "'num_proxies' is deprecated as of version 0.15 and will be" + " removed in version 1.0. Use 'x_for' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self.x_for + + @num_proxies.setter + def num_proxies(self, value): + if value is not None: + warnings.warn( + "'num_proxies' is deprecated as of version 0.15 and" + " will be removed in version 1.0. Use 'x_for' instead.", + DeprecationWarning, + stacklevel=2, + ) + self.x_for = value + + def get_remote_addr(self, forwarded_for): + """Get the real ``remote_addr`` by looking backwards ``x_for`` + number of values in the ``X-Forwarded-For`` header. + + :param forwarded_for: List of values parsed from the + ``X-Forwarded-For`` header. + :return: The real ``remote_addr``, or ``None`` if there were not + at least ``x_for`` values. + + .. deprecated:: 0.15 + This is handled internally for each header. This method will + be removed in 1.0. + + .. versionchanged:: 0.9 + Use ``num_proxies`` instead of always picking the first + value. + + .. versionadded:: 0.8 + """ + warnings.warn( + "'get_remote_addr' is deprecated as of version 0.15 and" + " will be removed in version 1.0. It is now handled" + " internally for each header.", + DeprecationWarning, + ) + return self._get_trusted_comma(self.x_for, ",".join(forwarded_for)) + + def _get_trusted_comma(self, trusted, value): + """Get the real value from a comma-separated header based on the + configured number of trusted proxies. + + :param trusted: Number of values to trust in the header. + :param value: Header value to parse. + :return: The real value, or ``None`` if there are fewer values + than the number of trusted proxies. + + .. versionadded:: 0.15 + """ + if not (trusted and value): + return + values = [x.strip() for x in value.split(",")] + if len(values) >= trusted: + return values[-trusted] + + def __call__(self, environ, start_response): + """Modify the WSGI environ based on the various ``Forwarded`` + headers before calling the wrapped application. Store the + original environ values in ``werkzeug.proxy_fix.orig_{key}``. + """ + environ_get = environ.get + orig_remote_addr = environ_get("REMOTE_ADDR") + orig_wsgi_url_scheme = environ_get("wsgi.url_scheme") + orig_http_host = environ_get("HTTP_HOST") + environ.update( + { + "werkzeug.proxy_fix.orig": { + "REMOTE_ADDR": orig_remote_addr, + "wsgi.url_scheme": orig_wsgi_url_scheme, + "HTTP_HOST": orig_http_host, + "SERVER_NAME": environ_get("SERVER_NAME"), + "SERVER_PORT": environ_get("SERVER_PORT"), + "SCRIPT_NAME": environ_get("SCRIPT_NAME"), + }, + # todo: remove deprecated keys + "werkzeug.proxy_fix.orig_remote_addr": orig_remote_addr, + "werkzeug.proxy_fix.orig_wsgi_url_scheme": orig_wsgi_url_scheme, + "werkzeug.proxy_fix.orig_http_host": orig_http_host, + } + ) + + x_for = self._get_trusted_comma(self.x_for, environ_get("HTTP_X_FORWARDED_FOR")) + if x_for: + environ["REMOTE_ADDR"] = x_for + + x_proto = self._get_trusted_comma( + self.x_proto, environ_get("HTTP_X_FORWARDED_PROTO") + ) + if x_proto: + environ["wsgi.url_scheme"] = x_proto + + x_host = self._get_trusted_comma( + self.x_host, environ_get("HTTP_X_FORWARDED_HOST") + ) + if x_host: + environ["HTTP_HOST"] = x_host + parts = x_host.split(":", 1) + environ["SERVER_NAME"] = parts[0] + if len(parts) == 2: + environ["SERVER_PORT"] = parts[1] + + x_port = self._get_trusted_comma( + self.x_port, environ_get("HTTP_X_FORWARDED_PORT") + ) + if x_port: + host = environ.get("HTTP_HOST") + if host: + parts = host.split(":", 1) + host = parts[0] if len(parts) == 2 else host + environ["HTTP_HOST"] = "%s:%s" % (host, x_port) + environ["SERVER_PORT"] = x_port + + x_prefix = self._get_trusted_comma( + self.x_prefix, environ_get("HTTP_X_FORWARDED_PREFIX") + ) + if x_prefix: + environ["SCRIPT_NAME"] = x_prefix + + return self.app(environ, start_response) diff --git a/venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py b/venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py new file mode 100644 index 0000000..a902281 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py @@ -0,0 +1,260 @@ +""" +Serve Shared Static Files +========================= + +.. autoclass:: SharedDataMiddleware + :members: is_allowed + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import mimetypes +import os +import posixpath +from datetime import datetime +from io import BytesIO +from time import mktime +from time import time +from zlib import adler32 + +from .._compat import PY2 +from .._compat import string_types +from ..filesystem import get_filesystem_encoding +from ..http import http_date +from ..http import is_resource_modified +from ..wsgi import get_path_info +from ..wsgi import wrap_file + + +class SharedDataMiddleware(object): + + """A WSGI middleware that provides static content for development + environments or simple server setups. Usage is quite simple:: + + import os + from werkzeug.wsgi import SharedDataMiddleware + + app = SharedDataMiddleware(app, { + '/static': os.path.join(os.path.dirname(__file__), 'static') + }) + + The contents of the folder ``./shared`` will now be available on + ``http://example.com/shared/``. This is pretty useful during development + because a standalone media server is not required. One can also mount + files on the root folder and still continue to use the application because + the shared data middleware forwards all unhandled requests to the + application, even if the requests are below one of the shared folders. + + If `pkg_resources` is available you can also tell the middleware to serve + files from package data:: + + app = SharedDataMiddleware(app, { + '/static': ('myapplication', 'static') + }) + + This will then serve the ``static`` folder in the `myapplication` + Python package. + + The optional `disallow` parameter can be a list of :func:`~fnmatch.fnmatch` + rules for files that are not accessible from the web. If `cache` is set to + `False` no caching headers are sent. + + Currently the middleware does not support non ASCII filenames. If the + encoding on the file system happens to be the encoding of the URI it may + work but this could also be by accident. We strongly suggest using ASCII + only file names for static files. + + The middleware will guess the mimetype using the Python `mimetype` + module. If it's unable to figure out the charset it will fall back + to `fallback_mimetype`. + + .. versionchanged:: 0.5 + The cache timeout is configurable now. + + .. versionadded:: 0.6 + The `fallback_mimetype` parameter was added. + + :param app: the application to wrap. If you don't want to wrap an + application you can pass it :exc:`NotFound`. + :param exports: a list or dict of exported files and folders. + :param disallow: a list of :func:`~fnmatch.fnmatch` rules. + :param fallback_mimetype: the fallback mimetype for unknown files. + :param cache: enable or disable caching headers. + :param cache_timeout: the cache timeout in seconds for the headers. + """ + + def __init__( + self, + app, + exports, + disallow=None, + cache=True, + cache_timeout=60 * 60 * 12, + fallback_mimetype="text/plain", + ): + self.app = app + self.exports = [] + self.cache = cache + self.cache_timeout = cache_timeout + + if hasattr(exports, "items"): + exports = exports.items() + + for key, value in exports: + if isinstance(value, tuple): + loader = self.get_package_loader(*value) + elif isinstance(value, string_types): + if os.path.isfile(value): + loader = self.get_file_loader(value) + else: + loader = self.get_directory_loader(value) + else: + raise TypeError("unknown def %r" % value) + + self.exports.append((key, loader)) + + if disallow is not None: + from fnmatch import fnmatch + + self.is_allowed = lambda x: not fnmatch(x, disallow) + + self.fallback_mimetype = fallback_mimetype + + def is_allowed(self, filename): + """Subclasses can override this method to disallow the access to + certain files. However by providing `disallow` in the constructor + this method is overwritten. + """ + return True + + def _opener(self, filename): + return lambda: ( + open(filename, "rb"), + datetime.utcfromtimestamp(os.path.getmtime(filename)), + int(os.path.getsize(filename)), + ) + + def get_file_loader(self, filename): + return lambda x: (os.path.basename(filename), self._opener(filename)) + + def get_package_loader(self, package, package_path): + from pkg_resources import DefaultProvider, ResourceManager, get_provider + + loadtime = datetime.utcnow() + provider = get_provider(package) + manager = ResourceManager() + filesystem_bound = isinstance(provider, DefaultProvider) + + def loader(path): + if path is None: + return None, None + + path = posixpath.join(package_path, path) + + if not provider.has_resource(path): + return None, None + + basename = posixpath.basename(path) + + if filesystem_bound: + return ( + basename, + self._opener(provider.get_resource_filename(manager, path)), + ) + + s = provider.get_resource_string(manager, path) + return basename, lambda: (BytesIO(s), loadtime, len(s)) + + return loader + + def get_directory_loader(self, directory): + def loader(path): + if path is not None: + path = os.path.join(directory, path) + else: + path = directory + + if os.path.isfile(path): + return os.path.basename(path), self._opener(path) + + return None, None + + return loader + + def generate_etag(self, mtime, file_size, real_filename): + if not isinstance(real_filename, bytes): + real_filename = real_filename.encode(get_filesystem_encoding()) + + return "wzsdm-%d-%s-%s" % ( + mktime(mtime.timetuple()), + file_size, + adler32(real_filename) & 0xFFFFFFFF, + ) + + def __call__(self, environ, start_response): + cleaned_path = get_path_info(environ) + + if PY2: + cleaned_path = cleaned_path.encode(get_filesystem_encoding()) + + # sanitize the path for non unix systems + cleaned_path = cleaned_path.strip("/") + + for sep in os.sep, os.altsep: + if sep and sep != "/": + cleaned_path = cleaned_path.replace(sep, "/") + + path = "/" + "/".join(x for x in cleaned_path.split("/") if x and x != "..") + file_loader = None + + for search_path, loader in self.exports: + if search_path == path: + real_filename, file_loader = loader(None) + + if file_loader is not None: + break + + if not search_path.endswith("/"): + search_path += "/" + + if path.startswith(search_path): + real_filename, file_loader = loader(path[len(search_path) :]) + + if file_loader is not None: + break + + if file_loader is None or not self.is_allowed(real_filename): + return self.app(environ, start_response) + + guessed_type = mimetypes.guess_type(real_filename) + mime_type = guessed_type[0] or self.fallback_mimetype + f, mtime, file_size = file_loader() + + headers = [("Date", http_date())] + + if self.cache: + timeout = self.cache_timeout + etag = self.generate_etag(mtime, file_size, real_filename) + headers += [ + ("Etag", '"%s"' % etag), + ("Cache-Control", "max-age=%d, public" % timeout), + ] + + if not is_resource_modified(environ, etag, last_modified=mtime): + f.close() + start_response("304 Not Modified", headers) + return [] + + headers.append(("Expires", http_date(time() + timeout))) + else: + headers.append(("Cache-Control", "public")) + + headers.extend( + ( + ("Content-Type", mime_type), + ("Content-Length", str(file_size)), + ("Last-Modified", http_date(mtime)), + ) + ) + start_response("200 OK", headers) + return wrap_file(environ, f) diff --git a/venv/lib/python3.7/site-packages/werkzeug/posixemulation.py b/venv/lib/python3.7/site-packages/werkzeug/posixemulation.py new file mode 100644 index 0000000..696b456 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/posixemulation.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +r""" + werkzeug.posixemulation + ~~~~~~~~~~~~~~~~~~~~~~~ + + Provides a POSIX emulation for some features that are relevant to + web applications. The main purpose is to simplify support for + systems such as Windows NT that are not 100% POSIX compatible. + + Currently this only implements a :func:`rename` function that + follows POSIX semantics. Eg: if the target file already exists it + will be replaced without asking. + + This module was introduced in 0.6.1 and is not a public interface. + It might become one in later versions of Werkzeug. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import errno +import os +import random +import sys +import time + +from ._compat import to_unicode +from .filesystem import get_filesystem_encoding + +can_rename_open_file = False + +if os.name == "nt": + try: + import ctypes + + _MOVEFILE_REPLACE_EXISTING = 0x1 + _MOVEFILE_WRITE_THROUGH = 0x8 + _MoveFileEx = ctypes.windll.kernel32.MoveFileExW + + def _rename(src, dst): + src = to_unicode(src, get_filesystem_encoding()) + dst = to_unicode(dst, get_filesystem_encoding()) + if _rename_atomic(src, dst): + return True + retry = 0 + rv = False + while not rv and retry < 100: + rv = _MoveFileEx( + src, dst, _MOVEFILE_REPLACE_EXISTING | _MOVEFILE_WRITE_THROUGH + ) + if not rv: + time.sleep(0.001) + retry += 1 + return rv + + # new in Vista and Windows Server 2008 + _CreateTransaction = ctypes.windll.ktmw32.CreateTransaction + _CommitTransaction = ctypes.windll.ktmw32.CommitTransaction + _MoveFileTransacted = ctypes.windll.kernel32.MoveFileTransactedW + _CloseHandle = ctypes.windll.kernel32.CloseHandle + can_rename_open_file = True + + def _rename_atomic(src, dst): + ta = _CreateTransaction(None, 0, 0, 0, 0, 1000, "Werkzeug rename") + if ta == -1: + return False + try: + retry = 0 + rv = False + while not rv and retry < 100: + rv = _MoveFileTransacted( + src, + dst, + None, + None, + _MOVEFILE_REPLACE_EXISTING | _MOVEFILE_WRITE_THROUGH, + ta, + ) + if rv: + rv = _CommitTransaction(ta) + break + else: + time.sleep(0.001) + retry += 1 + return rv + finally: + _CloseHandle(ta) + + except Exception: + + def _rename(src, dst): + return False + + def _rename_atomic(src, dst): + return False + + def rename(src, dst): + # Try atomic or pseudo-atomic rename + if _rename(src, dst): + return + # Fall back to "move away and replace" + try: + os.rename(src, dst) + except OSError as e: + if e.errno != errno.EEXIST: + raise + old = "%s-%08x" % (dst, random.randint(0, sys.maxsize)) + os.rename(dst, old) + os.rename(src, dst) + try: + os.unlink(old) + except Exception: + pass + + +else: + rename = os.rename + can_rename_open_file = True diff --git a/venv/lib/python3.7/site-packages/werkzeug/routing.py b/venv/lib/python3.7/site-packages/werkzeug/routing.py new file mode 100644 index 0000000..6b1dd98 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/routing.py @@ -0,0 +1,2026 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.routing + ~~~~~~~~~~~~~~~~ + + When it comes to combining multiple controller or view functions (however + you want to call them) you need a dispatcher. A simple way would be + applying regular expression tests on the ``PATH_INFO`` and calling + registered callback functions that return the value then. + + This module implements a much more powerful system than simple regular + expression matching because it can also convert values in the URLs and + build URLs. + + Here a simple example that creates an URL map for an application with + two subdomains (www and kb) and some URL rules: + + >>> m = Map([ + ... # Static URLs + ... Rule('/', endpoint='static/index'), + ... Rule('/about', endpoint='static/about'), + ... Rule('/help', endpoint='static/help'), + ... # Knowledge Base + ... Subdomain('kb', [ + ... Rule('/', endpoint='kb/index'), + ... Rule('/browse/', endpoint='kb/browse'), + ... Rule('/browse//', endpoint='kb/browse'), + ... Rule('/browse//', endpoint='kb/browse') + ... ]) + ... ], default_subdomain='www') + + If the application doesn't use subdomains it's perfectly fine to not set + the default subdomain and not use the `Subdomain` rule factory. The endpoint + in the rules can be anything, for example import paths or unique + identifiers. The WSGI application can use those endpoints to get the + handler for that URL. It doesn't have to be a string at all but it's + recommended. + + Now it's possible to create a URL adapter for one of the subdomains and + build URLs: + + >>> c = m.bind('example.com') + >>> c.build("kb/browse", dict(id=42)) + 'http://kb.example.com/browse/42/' + >>> c.build("kb/browse", dict()) + 'http://kb.example.com/browse/' + >>> c.build("kb/browse", dict(id=42, page=3)) + 'http://kb.example.com/browse/42/3' + >>> c.build("static/about") + '/about' + >>> c.build("static/index", force_external=True) + 'http://www.example.com/' + + >>> c = m.bind('example.com', subdomain='kb') + >>> c.build("static/about") + 'http://www.example.com/about' + + The first argument to bind is the server name *without* the subdomain. + Per default it will assume that the script is mounted on the root, but + often that's not the case so you can provide the real mount point as + second argument: + + >>> c = m.bind('example.com', '/applications/example') + + The third argument can be the subdomain, if not given the default + subdomain is used. For more details about binding have a look at the + documentation of the `MapAdapter`. + + And here is how you can match URLs: + + >>> c = m.bind('example.com') + >>> c.match("/") + ('static/index', {}) + >>> c.match("/about") + ('static/about', {}) + >>> c = m.bind('example.com', '/', 'kb') + >>> c.match("/") + ('kb/index', {}) + >>> c.match("/browse/42/23") + ('kb/browse', {'id': 42, 'page': 23}) + + If matching fails you get a `NotFound` exception, if the rule thinks + it's a good idea to redirect (for example because the URL was defined + to have a slash at the end but the request was missing that slash) it + will raise a `RequestRedirect` exception. Both are subclasses of the + `HTTPException` so you can use those errors as responses in the + application. + + If matching succeeded but the URL rule was incompatible to the given + method (for example there were only rules for `GET` and `HEAD` and + routing system tried to match a `POST` request) a `MethodNotAllowed` + exception is raised. + + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import ast +import difflib +import posixpath +import re +import uuid +from pprint import pformat +from threading import Lock + +from ._compat import implements_to_string +from ._compat import iteritems +from ._compat import itervalues +from ._compat import native_string_result +from ._compat import string_types +from ._compat import text_type +from ._compat import to_bytes +from ._compat import to_unicode +from ._compat import wsgi_decoding_dance +from ._internal import _encode_idna +from ._internal import _get_environ +from .datastructures import ImmutableDict +from .datastructures import MultiDict +from .exceptions import BadHost +from .exceptions import HTTPException +from .exceptions import MethodNotAllowed +from .exceptions import NotFound +from .urls import _fast_url_quote +from .urls import url_encode +from .urls import url_join +from .urls import url_quote +from .utils import cached_property +from .utils import format_string +from .utils import redirect +from .wsgi import get_host + +_rule_re = re.compile( + r""" + (?P[^<]*) # static rule data + < + (?: + (?P[a-zA-Z_][a-zA-Z0-9_]*) # converter name + (?:\((?P.*?)\))? # converter arguments + \: # variable delimiter + )? + (?P[a-zA-Z_][a-zA-Z0-9_]*) # variable name + > + """, + re.VERBOSE, +) +_simple_rule_re = re.compile(r"<([^>]+)>") +_converter_args_re = re.compile( + r""" + ((?P\w+)\s*=\s*)? + (?P + True|False| + \d+.\d+| + \d+.| + \d+| + [\w\d_.]+| + [urUR]?(?P"[^"]*?"|'[^']*') + )\s*, + """, + re.VERBOSE | re.UNICODE, +) + + +_PYTHON_CONSTANTS = {"None": None, "True": True, "False": False} + + +def _pythonize(value): + if value in _PYTHON_CONSTANTS: + return _PYTHON_CONSTANTS[value] + for convert in int, float: + try: + return convert(value) + except ValueError: + pass + if value[:1] == value[-1:] and value[0] in "\"'": + value = value[1:-1] + return text_type(value) + + +def parse_converter_args(argstr): + argstr += "," + args = [] + kwargs = {} + + for item in _converter_args_re.finditer(argstr): + value = item.group("stringval") + if value is None: + value = item.group("value") + value = _pythonize(value) + if not item.group("name"): + args.append(value) + else: + name = item.group("name") + kwargs[name] = value + + return tuple(args), kwargs + + +def parse_rule(rule): + """Parse a rule and return it as generator. Each iteration yields tuples + in the form ``(converter, arguments, variable)``. If the converter is + `None` it's a static url part, otherwise it's a dynamic one. + + :internal: + """ + pos = 0 + end = len(rule) + do_match = _rule_re.match + used_names = set() + while pos < end: + m = do_match(rule, pos) + if m is None: + break + data = m.groupdict() + if data["static"]: + yield None, None, data["static"] + variable = data["variable"] + converter = data["converter"] or "default" + if variable in used_names: + raise ValueError("variable name %r used twice." % variable) + used_names.add(variable) + yield converter, data["args"] or None, variable + pos = m.end() + if pos < end: + remaining = rule[pos:] + if ">" in remaining or "<" in remaining: + raise ValueError("malformed url rule: %r" % rule) + yield None, None, remaining + + +class RoutingException(Exception): + """Special exceptions that require the application to redirect, notifying + about missing urls, etc. + + :internal: + """ + + +class RequestRedirect(HTTPException, RoutingException): + """Raise if the map requests a redirect. This is for example the case if + `strict_slashes` are activated and an url that requires a trailing slash. + + The attribute `new_url` contains the absolute destination url. + """ + + code = 308 + + def __init__(self, new_url): + RoutingException.__init__(self, new_url) + self.new_url = new_url + + def get_response(self, environ): + return redirect(self.new_url, self.code) + + +class RequestSlash(RoutingException): + """Internal exception.""" + + +class RequestAliasRedirect(RoutingException): # noqa: B903 + """This rule is an alias and wants to redirect to the canonical URL.""" + + def __init__(self, matched_values): + self.matched_values = matched_values + + +@implements_to_string +class BuildError(RoutingException, LookupError): + """Raised if the build system cannot find a URL for an endpoint with the + values provided. + """ + + def __init__(self, endpoint, values, method, adapter=None): + LookupError.__init__(self, endpoint, values, method) + self.endpoint = endpoint + self.values = values + self.method = method + self.adapter = adapter + + @cached_property + def suggested(self): + return self.closest_rule(self.adapter) + + def closest_rule(self, adapter): + def _score_rule(rule): + return sum( + [ + 0.98 + * difflib.SequenceMatcher( + None, rule.endpoint, self.endpoint + ).ratio(), + 0.01 * bool(set(self.values or ()).issubset(rule.arguments)), + 0.01 * bool(rule.methods and self.method in rule.methods), + ] + ) + + if adapter and adapter.map._rules: + return max(adapter.map._rules, key=_score_rule) + + def __str__(self): + message = [] + message.append("Could not build url for endpoint %r" % self.endpoint) + if self.method: + message.append(" (%r)" % self.method) + if self.values: + message.append(" with values %r" % sorted(self.values.keys())) + message.append(".") + if self.suggested: + if self.endpoint == self.suggested.endpoint: + if self.method and self.method not in self.suggested.methods: + message.append( + " Did you mean to use methods %r?" + % sorted(self.suggested.methods) + ) + missing_values = self.suggested.arguments.union( + set(self.suggested.defaults or ()) + ) - set(self.values.keys()) + if missing_values: + message.append( + " Did you forget to specify values %r?" % sorted(missing_values) + ) + else: + message.append(" Did you mean %r instead?" % self.suggested.endpoint) + return u"".join(message) + + +class ValidationError(ValueError): + """Validation error. If a rule converter raises this exception the rule + does not match the current URL and the next URL is tried. + """ + + +class RuleFactory(object): + """As soon as you have more complex URL setups it's a good idea to use rule + factories to avoid repetitive tasks. Some of them are builtin, others can + be added by subclassing `RuleFactory` and overriding `get_rules`. + """ + + def get_rules(self, map): + """Subclasses of `RuleFactory` have to override this method and return + an iterable of rules.""" + raise NotImplementedError() + + +class Subdomain(RuleFactory): + """All URLs provided by this factory have the subdomain set to a + specific domain. For example if you want to use the subdomain for + the current language this can be a good setup:: + + url_map = Map([ + Rule('/', endpoint='#select_language'), + Subdomain('', [ + Rule('/', endpoint='index'), + Rule('/about', endpoint='about'), + Rule('/help', endpoint='help') + ]) + ]) + + All the rules except for the ``'#select_language'`` endpoint will now + listen on a two letter long subdomain that holds the language code + for the current request. + """ + + def __init__(self, subdomain, rules): + self.subdomain = subdomain + self.rules = rules + + def get_rules(self, map): + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + rule = rule.empty() + rule.subdomain = self.subdomain + yield rule + + +class Submount(RuleFactory): + """Like `Subdomain` but prefixes the URL rule with a given string:: + + url_map = Map([ + Rule('/', endpoint='index'), + Submount('/blog', [ + Rule('/', endpoint='blog/index'), + Rule('/entry/', endpoint='blog/show') + ]) + ]) + + Now the rule ``'blog/show'`` matches ``/blog/entry/``. + """ + + def __init__(self, path, rules): + self.path = path.rstrip("/") + self.rules = rules + + def get_rules(self, map): + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + rule = rule.empty() + rule.rule = self.path + rule.rule + yield rule + + +class EndpointPrefix(RuleFactory): + """Prefixes all endpoints (which must be strings for this factory) with + another string. This can be useful for sub applications:: + + url_map = Map([ + Rule('/', endpoint='index'), + EndpointPrefix('blog/', [Submount('/blog', [ + Rule('/', endpoint='index'), + Rule('/entry/', endpoint='show') + ])]) + ]) + """ + + def __init__(self, prefix, rules): + self.prefix = prefix + self.rules = rules + + def get_rules(self, map): + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + rule = rule.empty() + rule.endpoint = self.prefix + rule.endpoint + yield rule + + +class RuleTemplate(object): + """Returns copies of the rules wrapped and expands string templates in + the endpoint, rule, defaults or subdomain sections. + + Here a small example for such a rule template:: + + from werkzeug.routing import Map, Rule, RuleTemplate + + resource = RuleTemplate([ + Rule('/$name/', endpoint='$name.list'), + Rule('/$name/', endpoint='$name.show') + ]) + + url_map = Map([resource(name='user'), resource(name='page')]) + + When a rule template is called the keyword arguments are used to + replace the placeholders in all the string parameters. + """ + + def __init__(self, rules): + self.rules = list(rules) + + def __call__(self, *args, **kwargs): + return RuleTemplateFactory(self.rules, dict(*args, **kwargs)) + + +class RuleTemplateFactory(RuleFactory): + """A factory that fills in template variables into rules. Used by + `RuleTemplate` internally. + + :internal: + """ + + def __init__(self, rules, context): + self.rules = rules + self.context = context + + def get_rules(self, map): + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + new_defaults = subdomain = None + if rule.defaults: + new_defaults = {} + for key, value in iteritems(rule.defaults): + if isinstance(value, string_types): + value = format_string(value, self.context) + new_defaults[key] = value + if rule.subdomain is not None: + subdomain = format_string(rule.subdomain, self.context) + new_endpoint = rule.endpoint + if isinstance(new_endpoint, string_types): + new_endpoint = format_string(new_endpoint, self.context) + yield Rule( + format_string(rule.rule, self.context), + new_defaults, + subdomain, + rule.methods, + rule.build_only, + new_endpoint, + rule.strict_slashes, + ) + + +def _prefix_names(src): + """ast parse and prefix names with `.` to avoid collision with user vars""" + tree = ast.parse(src).body[0] + if isinstance(tree, ast.Expr): + tree = tree.value + for node in ast.walk(tree): + if isinstance(node, ast.Name): + node.id = "." + node.id + return tree + + +_CALL_CONVERTER_CODE_FMT = "self._converters[{elem!r}].to_url()" +_IF_KWARGS_URL_ENCODE_CODE = """\ +if kwargs: + q = '?' + params = self._encode_query_vars(kwargs) +else: + q = params = '' +""" +_IF_KWARGS_URL_ENCODE_AST = _prefix_names(_IF_KWARGS_URL_ENCODE_CODE) +_URL_ENCODE_AST_NAMES = (_prefix_names("q"), _prefix_names("params")) + + +@implements_to_string +class Rule(RuleFactory): + """A Rule represents one URL pattern. There are some options for `Rule` + that change the way it behaves and are passed to the `Rule` constructor. + Note that besides the rule-string all arguments *must* be keyword arguments + in order to not break the application on Werkzeug upgrades. + + `string` + Rule strings basically are just normal URL paths with placeholders in + the format ```` where the converter and the + arguments are optional. If no converter is defined the `default` + converter is used which means `string` in the normal configuration. + + URL rules that end with a slash are branch URLs, others are leaves. + If you have `strict_slashes` enabled (which is the default), all + branch URLs that are matched without a trailing slash will trigger a + redirect to the same URL with the missing slash appended. + + The converters are defined on the `Map`. + + `endpoint` + The endpoint for this rule. This can be anything. A reference to a + function, a string, a number etc. The preferred way is using a string + because the endpoint is used for URL generation. + + `defaults` + An optional dict with defaults for other rules with the same endpoint. + This is a bit tricky but useful if you want to have unique URLs:: + + url_map = Map([ + Rule('/all/', defaults={'page': 1}, endpoint='all_entries'), + Rule('/all/page/', endpoint='all_entries') + ]) + + If a user now visits ``http://example.com/all/page/1`` he will be + redirected to ``http://example.com/all/``. If `redirect_defaults` is + disabled on the `Map` instance this will only affect the URL + generation. + + `subdomain` + The subdomain rule string for this rule. If not specified the rule + only matches for the `default_subdomain` of the map. If the map is + not bound to a subdomain this feature is disabled. + + Can be useful if you want to have user profiles on different subdomains + and all subdomains are forwarded to your application:: + + url_map = Map([ + Rule('/', subdomain='', endpoint='user/homepage'), + Rule('/stats', subdomain='', endpoint='user/stats') + ]) + + `methods` + A sequence of http methods this rule applies to. If not specified, all + methods are allowed. For example this can be useful if you want different + endpoints for `POST` and `GET`. If methods are defined and the path + matches but the method matched against is not in this list or in the + list of another rule for that path the error raised is of the type + `MethodNotAllowed` rather than `NotFound`. If `GET` is present in the + list of methods and `HEAD` is not, `HEAD` is added automatically. + + .. versionchanged:: 0.6.1 + `HEAD` is now automatically added to the methods if `GET` is + present. The reason for this is that existing code often did not + work properly in servers not rewriting `HEAD` to `GET` + automatically and it was not documented how `HEAD` should be + treated. This was considered a bug in Werkzeug because of that. + + `strict_slashes` + Override the `Map` setting for `strict_slashes` only for this rule. If + not specified the `Map` setting is used. + + `build_only` + Set this to True and the rule will never match but will create a URL + that can be build. This is useful if you have resources on a subdomain + or folder that are not handled by the WSGI application (like static data) + + `redirect_to` + If given this must be either a string or callable. In case of a + callable it's called with the url adapter that triggered the match and + the values of the URL as keyword arguments and has to return the target + for the redirect, otherwise it has to be a string with placeholders in + rule syntax:: + + def foo_with_slug(adapter, id): + # ask the database for the slug for the old id. this of + # course has nothing to do with werkzeug. + return 'foo/' + Foo.get_slug_for_id(id) + + url_map = Map([ + Rule('/foo/', endpoint='foo'), + Rule('/some/old/url/', redirect_to='foo/'), + Rule('/other/old/url/', redirect_to=foo_with_slug) + ]) + + When the rule is matched the routing system will raise a + `RequestRedirect` exception with the target for the redirect. + + Keep in mind that the URL will be joined against the URL root of the + script so don't use a leading slash on the target URL unless you + really mean root of that domain. + + `alias` + If enabled this rule serves as an alias for another rule with the same + endpoint and arguments. + + `host` + If provided and the URL map has host matching enabled this can be + used to provide a match rule for the whole host. This also means + that the subdomain feature is disabled. + + .. versionadded:: 0.7 + The `alias` and `host` parameters were added. + """ + + def __init__( + self, + string, + defaults=None, + subdomain=None, + methods=None, + build_only=False, + endpoint=None, + strict_slashes=None, + redirect_to=None, + alias=False, + host=None, + ): + if not string.startswith("/"): + raise ValueError("urls must start with a leading slash") + self.rule = string + self.is_leaf = not string.endswith("/") + + self.map = None + self.strict_slashes = strict_slashes + self.subdomain = subdomain + self.host = host + self.defaults = defaults + self.build_only = build_only + self.alias = alias + if methods is None: + self.methods = None + else: + if isinstance(methods, str): + raise TypeError("param `methods` should be `Iterable[str]`, not `str`") + self.methods = set([x.upper() for x in methods]) + if "HEAD" not in self.methods and "GET" in self.methods: + self.methods.add("HEAD") + self.endpoint = endpoint + self.redirect_to = redirect_to + + if defaults: + self.arguments = set(map(str, defaults)) + else: + self.arguments = set() + self._trace = self._converters = self._regex = self._argument_weights = None + + def empty(self): + """ + Return an unbound copy of this rule. + + This can be useful if want to reuse an already bound URL for another + map. See ``get_empty_kwargs`` to override what keyword arguments are + provided to the new copy. + """ + return type(self)(self.rule, **self.get_empty_kwargs()) + + def get_empty_kwargs(self): + """ + Provides kwargs for instantiating empty copy with empty() + + Use this method to provide custom keyword arguments to the subclass of + ``Rule`` when calling ``some_rule.empty()``. Helpful when the subclass + has custom keyword arguments that are needed at instantiation. + + Must return a ``dict`` that will be provided as kwargs to the new + instance of ``Rule``, following the initial ``self.rule`` value which + is always provided as the first, required positional argument. + """ + defaults = None + if self.defaults: + defaults = dict(self.defaults) + return dict( + defaults=defaults, + subdomain=self.subdomain, + methods=self.methods, + build_only=self.build_only, + endpoint=self.endpoint, + strict_slashes=self.strict_slashes, + redirect_to=self.redirect_to, + alias=self.alias, + host=self.host, + ) + + def get_rules(self, map): + yield self + + def refresh(self): + """Rebinds and refreshes the URL. Call this if you modified the + rule in place. + + :internal: + """ + self.bind(self.map, rebind=True) + + def bind(self, map, rebind=False): + """Bind the url to a map and create a regular expression based on + the information from the rule itself and the defaults from the map. + + :internal: + """ + if self.map is not None and not rebind: + raise RuntimeError("url rule %r already bound to map %r" % (self, self.map)) + self.map = map + if self.strict_slashes is None: + self.strict_slashes = map.strict_slashes + if self.subdomain is None: + self.subdomain = map.default_subdomain + self.compile() + + def get_converter(self, variable_name, converter_name, args, kwargs): + """Looks up the converter for the given parameter. + + .. versionadded:: 0.9 + """ + if converter_name not in self.map.converters: + raise LookupError("the converter %r does not exist" % converter_name) + return self.map.converters[converter_name](self.map, *args, **kwargs) + + def _encode_query_vars(self, query_vars): + return url_encode( + query_vars, + charset=self.map.charset, + sort=self.map.sort_parameters, + key=self.map.sort_key, + ) + + def compile(self): + """Compiles the regular expression and stores it.""" + assert self.map is not None, "rule not bound" + + if self.map.host_matching: + domain_rule = self.host or "" + else: + domain_rule = self.subdomain or "" + + self._trace = [] + self._converters = {} + self._static_weights = [] + self._argument_weights = [] + regex_parts = [] + + def _build_regex(rule): + index = 0 + for converter, arguments, variable in parse_rule(rule): + if converter is None: + regex_parts.append(re.escape(variable)) + self._trace.append((False, variable)) + for part in variable.split("/"): + if part: + self._static_weights.append((index, -len(part))) + else: + if arguments: + c_args, c_kwargs = parse_converter_args(arguments) + else: + c_args = () + c_kwargs = {} + convobj = self.get_converter(variable, converter, c_args, c_kwargs) + regex_parts.append("(?P<%s>%s)" % (variable, convobj.regex)) + self._converters[variable] = convobj + self._trace.append((True, variable)) + self._argument_weights.append(convobj.weight) + self.arguments.add(str(variable)) + index = index + 1 + + _build_regex(domain_rule) + regex_parts.append("\\|") + self._trace.append((False, "|")) + _build_regex(self.rule if self.is_leaf else self.rule.rstrip("/")) + if not self.is_leaf: + self._trace.append((False, "/")) + + self._build = self._compile_builder(False).__get__(self, None) + self._build_unknown = self._compile_builder(True).__get__(self, None) + + if self.build_only: + return + regex = r"^%s%s$" % ( + u"".join(regex_parts), + (not self.is_leaf or not self.strict_slashes) + and "(?/?)" + or "", + ) + self._regex = re.compile(regex, re.UNICODE) + + def match(self, path, method=None): + """Check if the rule matches a given path. Path is a string in the + form ``"subdomain|/path"`` and is assembled by the map. If + the map is doing host matching the subdomain part will be the host + instead. + + If the rule matches a dict with the converted values is returned, + otherwise the return value is `None`. + + :internal: + """ + if not self.build_only: + m = self._regex.search(path) + if m is not None: + groups = m.groupdict() + # we have a folder like part of the url without a trailing + # slash and strict slashes enabled. raise an exception that + # tells the map to redirect to the same url but with a + # trailing slash + if ( + self.strict_slashes + and not self.is_leaf + and not groups.pop("__suffix__") + and ( + method is None or self.methods is None or method in self.methods + ) + ): + raise RequestSlash() + # if we are not in strict slashes mode we have to remove + # a __suffix__ + elif not self.strict_slashes: + del groups["__suffix__"] + + result = {} + for name, value in iteritems(groups): + try: + value = self._converters[name].to_python(value) + except ValidationError: + return + result[str(name)] = value + if self.defaults: + result.update(self.defaults) + + if self.alias and self.map.redirect_defaults: + raise RequestAliasRedirect(result) + + return result + + @staticmethod + def _get_func_code(code, name): + globs, locs = {}, {} + exec(code, globs, locs) + return locs[name] + + def _compile_builder(self, append_unknown=True): + defaults = self.defaults or {} + dom_ops = [] + url_ops = [] + + opl = dom_ops + for is_dynamic, data in self._trace: + if data == "|" and opl is dom_ops: + opl = url_ops + continue + # this seems like a silly case to ever come up but: + # if a default is given for a value that appears in the rule, + # resolve it to a constant ahead of time + if is_dynamic and data in defaults: + data = self._converters[data].to_url(defaults[data]) + opl.append((False, data)) + elif not is_dynamic: + opl.append( + (False, url_quote(to_bytes(data, self.map.charset), safe="/:|+")) + ) + else: + opl.append((True, data)) + + def _convert(elem): + ret = _prefix_names(_CALL_CONVERTER_CODE_FMT.format(elem=elem)) + ret.args = [ast.Name(str(elem), ast.Load())] # str for py2 + return ret + + def _parts(ops): + parts = [ + _convert(elem) if is_dynamic else ast.Str(s=elem) + for is_dynamic, elem in ops + ] + parts = parts or [ast.Str("")] + # constant fold + ret = [parts[0]] + for p in parts[1:]: + if isinstance(p, ast.Str) and isinstance(ret[-1], ast.Str): + ret[-1] = ast.Str(ret[-1].s + p.s) + else: + ret.append(p) + return ret + + dom_parts = _parts(dom_ops) + url_parts = _parts(url_ops) + if not append_unknown: + body = [] + else: + body = [_IF_KWARGS_URL_ENCODE_AST] + url_parts.extend(_URL_ENCODE_AST_NAMES) + + def _join(parts): + if len(parts) == 1: # shortcut + return parts[0] + elif hasattr(ast, "JoinedStr"): # py36+ + return ast.JoinedStr(parts) + else: + call = _prefix_names('"".join()') + call.args = [ast.Tuple(parts, ast.Load())] + return call + + body.append( + ast.Return(ast.Tuple([_join(dom_parts), _join(url_parts)], ast.Load())) + ) + + # str is necessary for python2 + pargs = [ + str(elem) + for is_dynamic, elem in dom_ops + url_ops + if is_dynamic and elem not in defaults + ] + kargs = [str(k) for k in defaults] + + func_ast = _prefix_names("def _(): pass") + func_ast.name = "".format(self.rule) + if hasattr(ast, "arg"): # py3 + func_ast.args.args.append(ast.arg(".self", None)) + for arg in pargs + kargs: + func_ast.args.args.append(ast.arg(arg, None)) + func_ast.args.kwarg = ast.arg(".kwargs", None) + else: + func_ast.args.args.append(ast.Name(".self", ast.Load())) + for arg in pargs + kargs: + func_ast.args.args.append(ast.Name(arg, ast.Load())) + func_ast.args.kwarg = ".kwargs" + for _ in kargs: + func_ast.args.defaults.append(ast.Str("")) + func_ast.body = body + + module = ast.fix_missing_locations(ast.Module([func_ast])) + code = compile(module, "", "exec") + return self._get_func_code(code, func_ast.name) + + def build(self, values, append_unknown=True): + """Assembles the relative url for that rule and the subdomain. + If building doesn't work for some reasons `None` is returned. + + :internal: + """ + try: + if append_unknown: + return self._build_unknown(**values) + else: + return self._build(**values) + except ValidationError: + return None + + def provides_defaults_for(self, rule): + """Check if this rule has defaults for a given rule. + + :internal: + """ + return ( + not self.build_only + and self.defaults + and self.endpoint == rule.endpoint + and self != rule + and self.arguments == rule.arguments + ) + + def suitable_for(self, values, method=None): + """Check if the dict of values has enough data for url generation. + + :internal: + """ + # if a method was given explicitly and that method is not supported + # by this rule, this rule is not suitable. + if ( + method is not None + and self.methods is not None + and method not in self.methods + ): + return False + + defaults = self.defaults or () + + # all arguments required must be either in the defaults dict or + # the value dictionary otherwise it's not suitable + for key in self.arguments: + if key not in defaults and key not in values: + return False + + # in case defaults are given we ensure that either the value was + # skipped or the value is the same as the default value. + if defaults: + for key, value in iteritems(defaults): + if key in values and value != values[key]: + return False + + return True + + def match_compare_key(self): + """The match compare key for sorting. + + Current implementation: + + 1. rules without any arguments come first for performance + reasons only as we expect them to match faster and some + common ones usually don't have any arguments (index pages etc.) + 2. rules with more static parts come first so the second argument + is the negative length of the number of the static weights. + 3. we order by static weights, which is a combination of index + and length + 4. The more complex rules come first so the next argument is the + negative length of the number of argument weights. + 5. lastly we order by the actual argument weights. + + :internal: + """ + return ( + bool(self.arguments), + -len(self._static_weights), + self._static_weights, + -len(self._argument_weights), + self._argument_weights, + ) + + def build_compare_key(self): + """The build compare key for sorting. + + :internal: + """ + return 1 if self.alias else 0, -len(self.arguments), -len(self.defaults or ()) + + def __eq__(self, other): + return self.__class__ is other.__class__ and self._trace == other._trace + + __hash__ = None + + def __ne__(self, other): + return not self.__eq__(other) + + def __str__(self): + return self.rule + + @native_string_result + def __repr__(self): + if self.map is None: + return u"<%s (unbound)>" % self.__class__.__name__ + tmp = [] + for is_dynamic, data in self._trace: + if is_dynamic: + tmp.append(u"<%s>" % data) + else: + tmp.append(data) + return u"<%s %s%s -> %s>" % ( + self.__class__.__name__, + repr((u"".join(tmp)).lstrip(u"|")).lstrip(u"u"), + self.methods is not None and u" (%s)" % u", ".join(self.methods) or u"", + self.endpoint, + ) + + +class BaseConverter(object): + """Base class for all converters.""" + + regex = "[^/]+" + weight = 100 + + def __init__(self, map): + self.map = map + + def to_python(self, value): + return value + + def to_url(self, value): + if isinstance(value, (bytes, bytearray)): + return _fast_url_quote(value) + return _fast_url_quote(text_type(value).encode(self.map.charset)) + + +class UnicodeConverter(BaseConverter): + """This converter is the default converter and accepts any string but + only one path segment. Thus the string can not include a slash. + + This is the default validator. + + Example:: + + Rule('/pages/'), + Rule('/') + + :param map: the :class:`Map`. + :param minlength: the minimum length of the string. Must be greater + or equal 1. + :param maxlength: the maximum length of the string. + :param length: the exact length of the string. + """ + + def __init__(self, map, minlength=1, maxlength=None, length=None): + BaseConverter.__init__(self, map) + if length is not None: + length = "{%d}" % int(length) + else: + if maxlength is None: + maxlength = "" + else: + maxlength = int(maxlength) + length = "{%s,%s}" % (int(minlength), maxlength) + self.regex = "[^/]" + length + + +class AnyConverter(BaseConverter): + """Matches one of the items provided. Items can either be Python + identifiers or strings:: + + Rule('/') + + :param map: the :class:`Map`. + :param items: this function accepts the possible items as positional + arguments. + """ + + def __init__(self, map, *items): + BaseConverter.__init__(self, map) + self.regex = "(?:%s)" % "|".join([re.escape(x) for x in items]) + + +class PathConverter(BaseConverter): + """Like the default :class:`UnicodeConverter`, but it also matches + slashes. This is useful for wikis and similar applications:: + + Rule('/') + Rule('//edit') + + :param map: the :class:`Map`. + """ + + regex = "[^/].*?" + weight = 200 + + +class NumberConverter(BaseConverter): + """Baseclass for `IntegerConverter` and `FloatConverter`. + + :internal: + """ + + weight = 50 + + def __init__(self, map, fixed_digits=0, min=None, max=None, signed=False): + if signed: + self.regex = self.signed_regex + BaseConverter.__init__(self, map) + self.fixed_digits = fixed_digits + self.min = min + self.max = max + self.signed = signed + + def to_python(self, value): + if self.fixed_digits and len(value) != self.fixed_digits: + raise ValidationError() + value = self.num_convert(value) + if (self.min is not None and value < self.min) or ( + self.max is not None and value > self.max + ): + raise ValidationError() + return value + + def to_url(self, value): + value = self.num_convert(value) + if self.fixed_digits: + value = ("%%0%sd" % self.fixed_digits) % value + return str(value) + + @property + def signed_regex(self): + return r"-?" + self.regex + + +class IntegerConverter(NumberConverter): + """This converter only accepts integer values:: + + Rule("/page/") + + By default it only accepts unsigned, positive values. The ``signed`` + parameter will enable signed, negative values. :: + + Rule("/page/") + + :param map: The :class:`Map`. + :param fixed_digits: The number of fixed digits in the URL. If you + set this to ``4`` for example, the rule will only match if the + URL looks like ``/0001/``. The default is variable length. + :param min: The minimal value. + :param max: The maximal value. + :param signed: Allow signed (negative) values. + + .. versionadded:: 0.15 + The ``signed`` parameter. + """ + + regex = r"\d+" + num_convert = int + + +class FloatConverter(NumberConverter): + """This converter only accepts floating point values:: + + Rule("/probability/") + + By default it only accepts unsigned, positive values. The ``signed`` + parameter will enable signed, negative values. :: + + Rule("/offset/") + + :param map: The :class:`Map`. + :param min: The minimal value. + :param max: The maximal value. + :param signed: Allow signed (negative) values. + + .. versionadded:: 0.15 + The ``signed`` parameter. + """ + + regex = r"\d+\.\d+" + num_convert = float + + def __init__(self, map, min=None, max=None, signed=False): + NumberConverter.__init__(self, map, min=min, max=max, signed=signed) + + +class UUIDConverter(BaseConverter): + """This converter only accepts UUID strings:: + + Rule('/object/') + + .. versionadded:: 0.10 + + :param map: the :class:`Map`. + """ + + regex = ( + r"[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-" + r"[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}" + ) + + def to_python(self, value): + return uuid.UUID(value) + + def to_url(self, value): + return str(value) + + +#: the default converter mapping for the map. +DEFAULT_CONVERTERS = { + "default": UnicodeConverter, + "string": UnicodeConverter, + "any": AnyConverter, + "path": PathConverter, + "int": IntegerConverter, + "float": FloatConverter, + "uuid": UUIDConverter, +} + + +class Map(object): + """The map class stores all the URL rules and some configuration + parameters. Some of the configuration values are only stored on the + `Map` instance since those affect all rules, others are just defaults + and can be overridden for each rule. Note that you have to specify all + arguments besides the `rules` as keyword arguments! + + :param rules: sequence of url rules for this map. + :param default_subdomain: The default subdomain for rules without a + subdomain defined. + :param charset: charset of the url. defaults to ``"utf-8"`` + :param strict_slashes: Take care of trailing slashes. + :param redirect_defaults: This will redirect to the default rule if it + wasn't visited that way. This helps creating + unique URLs. + :param converters: A dict of converters that adds additional converters + to the list of converters. If you redefine one + converter this will override the original one. + :param sort_parameters: If set to `True` the url parameters are sorted. + See `url_encode` for more details. + :param sort_key: The sort key function for `url_encode`. + :param encoding_errors: the error method to use for decoding + :param host_matching: if set to `True` it enables the host matching + feature and disables the subdomain one. If + enabled the `host` parameter to rules is used + instead of the `subdomain` one. + + .. versionadded:: 0.5 + `sort_parameters` and `sort_key` was added. + + .. versionadded:: 0.7 + `encoding_errors` and `host_matching` was added. + """ + + #: A dict of default converters to be used. + default_converters = ImmutableDict(DEFAULT_CONVERTERS) + + def __init__( + self, + rules=None, + default_subdomain="", + charset="utf-8", + strict_slashes=True, + redirect_defaults=True, + converters=None, + sort_parameters=False, + sort_key=None, + encoding_errors="replace", + host_matching=False, + ): + self._rules = [] + self._rules_by_endpoint = {} + self._remap = True + self._remap_lock = Lock() + + self.default_subdomain = default_subdomain + self.charset = charset + self.encoding_errors = encoding_errors + self.strict_slashes = strict_slashes + self.redirect_defaults = redirect_defaults + self.host_matching = host_matching + + self.converters = self.default_converters.copy() + if converters: + self.converters.update(converters) + + self.sort_parameters = sort_parameters + self.sort_key = sort_key + + for rulefactory in rules or (): + self.add(rulefactory) + + def is_endpoint_expecting(self, endpoint, *arguments): + """Iterate over all rules and check if the endpoint expects + the arguments provided. This is for example useful if you have + some URLs that expect a language code and others that do not and + you want to wrap the builder a bit so that the current language + code is automatically added if not provided but endpoints expect + it. + + :param endpoint: the endpoint to check. + :param arguments: this function accepts one or more arguments + as positional arguments. Each one of them is + checked. + """ + self.update() + arguments = set(arguments) + for rule in self._rules_by_endpoint[endpoint]: + if arguments.issubset(rule.arguments): + return True + return False + + def iter_rules(self, endpoint=None): + """Iterate over all rules or the rules of an endpoint. + + :param endpoint: if provided only the rules for that endpoint + are returned. + :return: an iterator + """ + self.update() + if endpoint is not None: + return iter(self._rules_by_endpoint[endpoint]) + return iter(self._rules) + + def add(self, rulefactory): + """Add a new rule or factory to the map and bind it. Requires that the + rule is not bound to another map. + + :param rulefactory: a :class:`Rule` or :class:`RuleFactory` + """ + for rule in rulefactory.get_rules(self): + rule.bind(self) + self._rules.append(rule) + self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule) + self._remap = True + + def bind( + self, + server_name, + script_name=None, + subdomain=None, + url_scheme="http", + default_method="GET", + path_info=None, + query_args=None, + ): + """Return a new :class:`MapAdapter` with the details specified to the + call. Note that `script_name` will default to ``'/'`` if not further + specified or `None`. The `server_name` at least is a requirement + because the HTTP RFC requires absolute URLs for redirects and so all + redirect exceptions raised by Werkzeug will contain the full canonical + URL. + + If no path_info is passed to :meth:`match` it will use the default path + info passed to bind. While this doesn't really make sense for + manual bind calls, it's useful if you bind a map to a WSGI + environment which already contains the path info. + + `subdomain` will default to the `default_subdomain` for this map if + no defined. If there is no `default_subdomain` you cannot use the + subdomain feature. + + .. versionadded:: 0.7 + `query_args` added + + .. versionadded:: 0.8 + `query_args` can now also be a string. + + .. versionchanged:: 0.15 + ``path_info`` defaults to ``'/'`` if ``None``. + """ + server_name = server_name.lower() + if self.host_matching: + if subdomain is not None: + raise RuntimeError("host matching enabled and a subdomain was provided") + elif subdomain is None: + subdomain = self.default_subdomain + if script_name is None: + script_name = "/" + if path_info is None: + path_info = "/" + try: + server_name = _encode_idna(server_name) + except UnicodeError: + raise BadHost() + return MapAdapter( + self, + server_name, + script_name, + subdomain, + url_scheme, + path_info, + default_method, + query_args, + ) + + def bind_to_environ(self, environ, server_name=None, subdomain=None): + """Like :meth:`bind` but you can pass it an WSGI environment and it + will fetch the information from that dictionary. Note that because of + limitations in the protocol there is no way to get the current + subdomain and real `server_name` from the environment. If you don't + provide it, Werkzeug will use `SERVER_NAME` and `SERVER_PORT` (or + `HTTP_HOST` if provided) as used `server_name` with disabled subdomain + feature. + + If `subdomain` is `None` but an environment and a server name is + provided it will calculate the current subdomain automatically. + Example: `server_name` is ``'example.com'`` and the `SERVER_NAME` + in the wsgi `environ` is ``'staging.dev.example.com'`` the calculated + subdomain will be ``'staging.dev'``. + + If the object passed as environ has an environ attribute, the value of + this attribute is used instead. This allows you to pass request + objects. Additionally `PATH_INFO` added as a default of the + :class:`MapAdapter` so that you don't have to pass the path info to + the match method. + + .. versionchanged:: 0.5 + previously this method accepted a bogus `calculate_subdomain` + parameter that did not have any effect. It was removed because + of that. + + .. versionchanged:: 0.8 + This will no longer raise a ValueError when an unexpected server + name was passed. + + :param environ: a WSGI environment. + :param server_name: an optional server name hint (see above). + :param subdomain: optionally the current subdomain (see above). + """ + environ = _get_environ(environ) + + wsgi_server_name = get_host(environ).lower() + + if server_name is None: + server_name = wsgi_server_name + else: + server_name = server_name.lower() + + if subdomain is None and not self.host_matching: + cur_server_name = wsgi_server_name.split(".") + real_server_name = server_name.split(".") + offset = -len(real_server_name) + if cur_server_name[offset:] != real_server_name: + # This can happen even with valid configs if the server was + # accesssed directly by IP address under some situations. + # Instead of raising an exception like in Werkzeug 0.7 or + # earlier we go by an invalid subdomain which will result + # in a 404 error on matching. + subdomain = "" + else: + subdomain = ".".join(filter(None, cur_server_name[:offset])) + + def _get_wsgi_string(name): + val = environ.get(name) + if val is not None: + return wsgi_decoding_dance(val, self.charset) + + script_name = _get_wsgi_string("SCRIPT_NAME") + path_info = _get_wsgi_string("PATH_INFO") + query_args = _get_wsgi_string("QUERY_STRING") + return Map.bind( + self, + server_name, + script_name, + subdomain, + environ["wsgi.url_scheme"], + environ["REQUEST_METHOD"], + path_info, + query_args=query_args, + ) + + def update(self): + """Called before matching and building to keep the compiled rules + in the correct order after things changed. + """ + if not self._remap: + return + + with self._remap_lock: + if not self._remap: + return + + self._rules.sort(key=lambda x: x.match_compare_key()) + for rules in itervalues(self._rules_by_endpoint): + rules.sort(key=lambda x: x.build_compare_key()) + self._remap = False + + def __repr__(self): + rules = self.iter_rules() + return "%s(%s)" % (self.__class__.__name__, pformat(list(rules))) + + +class MapAdapter(object): + + """Returned by :meth:`Map.bind` or :meth:`Map.bind_to_environ` and does + the URL matching and building based on runtime information. + """ + + def __init__( + self, + map, + server_name, + script_name, + subdomain, + url_scheme, + path_info, + default_method, + query_args=None, + ): + self.map = map + self.server_name = to_unicode(server_name) + script_name = to_unicode(script_name) + if not script_name.endswith(u"/"): + script_name += u"/" + self.script_name = script_name + self.subdomain = to_unicode(subdomain) + self.url_scheme = to_unicode(url_scheme) + self.path_info = to_unicode(path_info) + self.default_method = to_unicode(default_method) + self.query_args = query_args + + def dispatch( + self, view_func, path_info=None, method=None, catch_http_exceptions=False + ): + """Does the complete dispatching process. `view_func` is called with + the endpoint and a dict with the values for the view. It should + look up the view function, call it, and return a response object + or WSGI application. http exceptions are not caught by default + so that applications can display nicer error messages by just + catching them by hand. If you want to stick with the default + error messages you can pass it ``catch_http_exceptions=True`` and + it will catch the http exceptions. + + Here a small example for the dispatch usage:: + + from werkzeug.wrappers import Request, Response + from werkzeug.wsgi import responder + from werkzeug.routing import Map, Rule + + def on_index(request): + return Response('Hello from the index') + + url_map = Map([Rule('/', endpoint='index')]) + views = {'index': on_index} + + @responder + def application(environ, start_response): + request = Request(environ) + urls = url_map.bind_to_environ(environ) + return urls.dispatch(lambda e, v: views[e](request, **v), + catch_http_exceptions=True) + + Keep in mind that this method might return exception objects, too, so + use :class:`Response.force_type` to get a response object. + + :param view_func: a function that is called with the endpoint as + first argument and the value dict as second. Has + to dispatch to the actual view function with this + information. (see above) + :param path_info: the path info to use for matching. Overrides the + path info specified on binding. + :param method: the HTTP method used for matching. Overrides the + method specified on binding. + :param catch_http_exceptions: set to `True` to catch any of the + werkzeug :class:`HTTPException`\\s. + """ + try: + try: + endpoint, args = self.match(path_info, method) + except RequestRedirect as e: + return e + return view_func(endpoint, args) + except HTTPException as e: + if catch_http_exceptions: + return e + raise + + def match(self, path_info=None, method=None, return_rule=False, query_args=None): + """The usage is simple: you just pass the match method the current + path info as well as the method (which defaults to `GET`). The + following things can then happen: + + - you receive a `NotFound` exception that indicates that no URL is + matching. A `NotFound` exception is also a WSGI application you + can call to get a default page not found page (happens to be the + same object as `werkzeug.exceptions.NotFound`) + + - you receive a `MethodNotAllowed` exception that indicates that there + is a match for this URL but not for the current request method. + This is useful for RESTful applications. + + - you receive a `RequestRedirect` exception with a `new_url` + attribute. This exception is used to notify you about a request + Werkzeug requests from your WSGI application. This is for example the + case if you request ``/foo`` although the correct URL is ``/foo/`` + You can use the `RequestRedirect` instance as response-like object + similar to all other subclasses of `HTTPException`. + + - you get a tuple in the form ``(endpoint, arguments)`` if there is + a match (unless `return_rule` is True, in which case you get a tuple + in the form ``(rule, arguments)``) + + If the path info is not passed to the match method the default path + info of the map is used (defaults to the root URL if not defined + explicitly). + + All of the exceptions raised are subclasses of `HTTPException` so they + can be used as WSGI responses. They will all render generic error or + redirect pages. + + Here is a small example for matching: + + >>> m = Map([ + ... Rule('/', endpoint='index'), + ... Rule('/downloads/', endpoint='downloads/index'), + ... Rule('/downloads/', endpoint='downloads/show') + ... ]) + >>> urls = m.bind("example.com", "/") + >>> urls.match("/", "GET") + ('index', {}) + >>> urls.match("/downloads/42") + ('downloads/show', {'id': 42}) + + And here is what happens on redirect and missing URLs: + + >>> urls.match("/downloads") + Traceback (most recent call last): + ... + RequestRedirect: http://example.com/downloads/ + >>> urls.match("/missing") + Traceback (most recent call last): + ... + NotFound: 404 Not Found + + :param path_info: the path info to use for matching. Overrides the + path info specified on binding. + :param method: the HTTP method used for matching. Overrides the + method specified on binding. + :param return_rule: return the rule that matched instead of just the + endpoint (defaults to `False`). + :param query_args: optional query arguments that are used for + automatic redirects as string or dictionary. It's + currently not possible to use the query arguments + for URL matching. + + .. versionadded:: 0.6 + `return_rule` was added. + + .. versionadded:: 0.7 + `query_args` was added. + + .. versionchanged:: 0.8 + `query_args` can now also be a string. + """ + self.map.update() + if path_info is None: + path_info = self.path_info + else: + path_info = to_unicode(path_info, self.map.charset) + if query_args is None: + query_args = self.query_args + method = (method or self.default_method).upper() + + path = u"%s|%s" % ( + self.map.host_matching and self.server_name or self.subdomain, + path_info and "/%s" % path_info.lstrip("/"), + ) + + have_match_for = set() + for rule in self.map._rules: + try: + rv = rule.match(path, method) + except RequestSlash: + raise RequestRedirect( + self.make_redirect_url( + url_quote(path_info, self.map.charset, safe="/:|+") + "/", + query_args, + ) + ) + except RequestAliasRedirect as e: + raise RequestRedirect( + self.make_alias_redirect_url( + path, rule.endpoint, e.matched_values, method, query_args + ) + ) + if rv is None: + continue + if rule.methods is not None and method not in rule.methods: + have_match_for.update(rule.methods) + continue + + if self.map.redirect_defaults: + redirect_url = self.get_default_redirect(rule, method, rv, query_args) + if redirect_url is not None: + raise RequestRedirect(redirect_url) + + if rule.redirect_to is not None: + if isinstance(rule.redirect_to, string_types): + + def _handle_match(match): + value = rv[match.group(1)] + return rule._converters[match.group(1)].to_url(value) + + redirect_url = _simple_rule_re.sub(_handle_match, rule.redirect_to) + else: + redirect_url = rule.redirect_to(self, **rv) + raise RequestRedirect( + str( + url_join( + "%s://%s%s%s" + % ( + self.url_scheme or "http", + self.subdomain + "." if self.subdomain else "", + self.server_name, + self.script_name, + ), + redirect_url, + ) + ) + ) + + if return_rule: + return rule, rv + else: + return rule.endpoint, rv + + if have_match_for: + raise MethodNotAllowed(valid_methods=list(have_match_for)) + raise NotFound() + + def test(self, path_info=None, method=None): + """Test if a rule would match. Works like `match` but returns `True` + if the URL matches, or `False` if it does not exist. + + :param path_info: the path info to use for matching. Overrides the + path info specified on binding. + :param method: the HTTP method used for matching. Overrides the + method specified on binding. + """ + try: + self.match(path_info, method) + except RequestRedirect: + pass + except HTTPException: + return False + return True + + def allowed_methods(self, path_info=None): + """Returns the valid methods that match for a given path. + + .. versionadded:: 0.7 + """ + try: + self.match(path_info, method="--") + except MethodNotAllowed as e: + return e.valid_methods + except HTTPException: + pass + return [] + + def get_host(self, domain_part): + """Figures out the full host name for the given domain part. The + domain part is a subdomain in case host matching is disabled or + a full host name. + """ + if self.map.host_matching: + if domain_part is None: + return self.server_name + return to_unicode(domain_part, "ascii") + subdomain = domain_part + if subdomain is None: + subdomain = self.subdomain + else: + subdomain = to_unicode(subdomain, "ascii") + return (subdomain + u"." if subdomain else u"") + self.server_name + + def get_default_redirect(self, rule, method, values, query_args): + """A helper that returns the URL to redirect to if it finds one. + This is used for default redirecting only. + + :internal: + """ + assert self.map.redirect_defaults + for r in self.map._rules_by_endpoint[rule.endpoint]: + # every rule that comes after this one, including ourself + # has a lower priority for the defaults. We order the ones + # with the highest priority up for building. + if r is rule: + break + if r.provides_defaults_for(rule) and r.suitable_for(values, method): + values.update(r.defaults) + domain_part, path = r.build(values) + return self.make_redirect_url(path, query_args, domain_part=domain_part) + + def encode_query_args(self, query_args): + if not isinstance(query_args, string_types): + query_args = url_encode(query_args, self.map.charset) + return query_args + + def make_redirect_url(self, path_info, query_args=None, domain_part=None): + """Creates a redirect URL. + + :internal: + """ + suffix = "" + if query_args: + suffix = "?" + self.encode_query_args(query_args) + return str( + "%s://%s/%s%s" + % ( + self.url_scheme or "http", + self.get_host(domain_part), + posixpath.join( + self.script_name[:-1].lstrip("/"), path_info.lstrip("/") + ), + suffix, + ) + ) + + def make_alias_redirect_url(self, path, endpoint, values, method, query_args): + """Internally called to make an alias redirect URL.""" + url = self.build( + endpoint, values, method, append_unknown=False, force_external=True + ) + if query_args: + url += "?" + self.encode_query_args(query_args) + assert url != path, "detected invalid alias setting. No canonical URL found" + return url + + def _partial_build(self, endpoint, values, method, append_unknown): + """Helper for :meth:`build`. Returns subdomain and path for the + rule that accepts this endpoint, values and method. + + :internal: + """ + # in case the method is none, try with the default method first + if method is None: + rv = self._partial_build( + endpoint, values, self.default_method, append_unknown + ) + if rv is not None: + return rv + + # default method did not match or a specific method is passed, + # check all and go with first result. + for rule in self.map._rules_by_endpoint.get(endpoint, ()): + if rule.suitable_for(values, method): + rv = rule.build(values, append_unknown) + if rv is not None: + return rv + + def build( + self, + endpoint, + values=None, + method=None, + force_external=False, + append_unknown=True, + ): + """Building URLs works pretty much the other way round. Instead of + `match` you call `build` and pass it the endpoint and a dict of + arguments for the placeholders. + + The `build` function also accepts an argument called `force_external` + which, if you set it to `True` will force external URLs. Per default + external URLs (include the server name) will only be used if the + target URL is on a different subdomain. + + >>> m = Map([ + ... Rule('/', endpoint='index'), + ... Rule('/downloads/', endpoint='downloads/index'), + ... Rule('/downloads/', endpoint='downloads/show') + ... ]) + >>> urls = m.bind("example.com", "/") + >>> urls.build("index", {}) + '/' + >>> urls.build("downloads/show", {'id': 42}) + '/downloads/42' + >>> urls.build("downloads/show", {'id': 42}, force_external=True) + 'http://example.com/downloads/42' + + Because URLs cannot contain non ASCII data you will always get + bytestrings back. Non ASCII characters are urlencoded with the + charset defined on the map instance. + + Additional values are converted to unicode and appended to the URL as + URL querystring parameters: + + >>> urls.build("index", {'q': 'My Searchstring'}) + '/?q=My+Searchstring' + + When processing those additional values, lists are furthermore + interpreted as multiple values (as per + :py:class:`werkzeug.datastructures.MultiDict`): + + >>> urls.build("index", {'q': ['a', 'b', 'c']}) + '/?q=a&q=b&q=c' + + Passing a ``MultiDict`` will also add multiple values: + + >>> urls.build("index", MultiDict((('p', 'z'), ('q', 'a'), ('q', 'b')))) + '/?p=z&q=a&q=b' + + If a rule does not exist when building a `BuildError` exception is + raised. + + The build method accepts an argument called `method` which allows you + to specify the method you want to have an URL built for if you have + different methods for the same endpoint specified. + + .. versionadded:: 0.6 + the `append_unknown` parameter was added. + + :param endpoint: the endpoint of the URL to build. + :param values: the values for the URL to build. Unhandled values are + appended to the URL as query parameters. + :param method: the HTTP method for the rule if there are different + URLs for different methods on the same endpoint. + :param force_external: enforce full canonical external URLs. If the URL + scheme is not provided, this will generate + a protocol-relative URL. + :param append_unknown: unknown parameters are appended to the generated + URL as query string argument. Disable this + if you want the builder to ignore those. + """ + self.map.update() + + if values: + if isinstance(values, MultiDict): + temp_values = {} + # iteritems(dict, values) is like `values.lists()` + # without the call or `list()` coercion overhead. + for key, value in iteritems(dict, values): + if not value: + continue + if len(value) == 1: # flatten single item lists + value = value[0] + if value is None: # drop None + continue + temp_values[key] = value + values = temp_values + else: + # drop None + values = dict(i for i in iteritems(values) if i[1] is not None) + else: + values = {} + + rv = self._partial_build(endpoint, values, method, append_unknown) + if rv is None: + raise BuildError(endpoint, values, method, self) + domain_part, path = rv + + host = self.get_host(domain_part) + + # shortcut this. + if not force_external and ( + (self.map.host_matching and host == self.server_name) + or (not self.map.host_matching and domain_part == self.subdomain) + ): + return "%s/%s" % (self.script_name.rstrip("/"), path.lstrip("/")) + return str( + "%s//%s%s/%s" + % ( + self.url_scheme + ":" if self.url_scheme else "", + host, + self.script_name[:-1], + path.lstrip("/"), + ) + ) diff --git a/venv/lib/python3.7/site-packages/werkzeug/security.py b/venv/lib/python3.7/site-packages/werkzeug/security.py new file mode 100644 index 0000000..1842afd --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/security.py @@ -0,0 +1,241 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.security + ~~~~~~~~~~~~~~~~~ + + Security related helpers such as secure password hashing tools. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import codecs +import hashlib +import hmac +import os +import posixpath +from random import SystemRandom +from struct import Struct + +from ._compat import izip +from ._compat import PY2 +from ._compat import range_type +from ._compat import text_type +from ._compat import to_bytes +from ._compat import to_native + +SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +DEFAULT_PBKDF2_ITERATIONS = 150000 + +_pack_int = Struct(">I").pack +_builtin_safe_str_cmp = getattr(hmac, "compare_digest", None) +_sys_rng = SystemRandom() +_os_alt_seps = list( + sep for sep in [os.path.sep, os.path.altsep] if sep not in (None, "/") +) + + +def pbkdf2_hex( + data, salt, iterations=DEFAULT_PBKDF2_ITERATIONS, keylen=None, hashfunc=None +): + """Like :func:`pbkdf2_bin`, but returns a hex-encoded string. + + .. versionadded:: 0.9 + + :param data: the data to derive. + :param salt: the salt for the derivation. + :param iterations: the number of iterations. + :param keylen: the length of the resulting key. If not provided, + the digest size will be used. + :param hashfunc: the hash function to use. This can either be the + string name of a known hash function, or a function + from the hashlib module. Defaults to sha256. + """ + rv = pbkdf2_bin(data, salt, iterations, keylen, hashfunc) + return to_native(codecs.encode(rv, "hex_codec")) + + +def pbkdf2_bin( + data, salt, iterations=DEFAULT_PBKDF2_ITERATIONS, keylen=None, hashfunc=None +): + """Returns a binary digest for the PBKDF2 hash algorithm of `data` + with the given `salt`. It iterates `iterations` times and produces a + key of `keylen` bytes. By default, SHA-256 is used as hash function; + a different hashlib `hashfunc` can be provided. + + .. versionadded:: 0.9 + + :param data: the data to derive. + :param salt: the salt for the derivation. + :param iterations: the number of iterations. + :param keylen: the length of the resulting key. If not provided + the digest size will be used. + :param hashfunc: the hash function to use. This can either be the + string name of a known hash function or a function + from the hashlib module. Defaults to sha256. + """ + if not hashfunc: + hashfunc = "sha256" + + data = to_bytes(data) + salt = to_bytes(salt) + + if callable(hashfunc): + _test_hash = hashfunc() + hash_name = getattr(_test_hash, "name", None) + else: + hash_name = hashfunc + return hashlib.pbkdf2_hmac(hash_name, data, salt, iterations, keylen) + + +def safe_str_cmp(a, b): + """This function compares strings in somewhat constant time. This + requires that the length of at least one string is known in advance. + + Returns `True` if the two strings are equal, or `False` if they are not. + + .. versionadded:: 0.7 + """ + if isinstance(a, text_type): + a = a.encode("utf-8") + if isinstance(b, text_type): + b = b.encode("utf-8") + + if _builtin_safe_str_cmp is not None: + return _builtin_safe_str_cmp(a, b) + + if len(a) != len(b): + return False + + rv = 0 + if PY2: + for x, y in izip(a, b): + rv |= ord(x) ^ ord(y) + else: + for x, y in izip(a, b): + rv |= x ^ y + + return rv == 0 + + +def gen_salt(length): + """Generate a random string of SALT_CHARS with specified ``length``.""" + if length <= 0: + raise ValueError("Salt length must be positive") + return "".join(_sys_rng.choice(SALT_CHARS) for _ in range_type(length)) + + +def _hash_internal(method, salt, password): + """Internal password hash helper. Supports plaintext without salt, + unsalted and salted passwords. In case salted passwords are used + hmac is used. + """ + if method == "plain": + return password, method + + if isinstance(password, text_type): + password = password.encode("utf-8") + + if method.startswith("pbkdf2:"): + args = method[7:].split(":") + if len(args) not in (1, 2): + raise ValueError("Invalid number of arguments for PBKDF2") + method = args.pop(0) + iterations = args and int(args[0] or 0) or DEFAULT_PBKDF2_ITERATIONS + is_pbkdf2 = True + actual_method = "pbkdf2:%s:%d" % (method, iterations) + else: + is_pbkdf2 = False + actual_method = method + + if is_pbkdf2: + if not salt: + raise ValueError("Salt is required for PBKDF2") + rv = pbkdf2_hex(password, salt, iterations, hashfunc=method) + elif salt: + if isinstance(salt, text_type): + salt = salt.encode("utf-8") + mac = _create_mac(salt, password, method) + rv = mac.hexdigest() + else: + rv = hashlib.new(method, password).hexdigest() + return rv, actual_method + + +def _create_mac(key, msg, method): + if callable(method): + return hmac.HMAC(key, msg, method) + + def hashfunc(d=b""): + return hashlib.new(method, d) + + # Python 2.7 used ``hasattr(digestmod, '__call__')`` + # to detect if hashfunc is callable + hashfunc.__call__ = hashfunc + return hmac.HMAC(key, msg, hashfunc) + + +def generate_password_hash(password, method="pbkdf2:sha256", salt_length=8): + """Hash a password with the given method and salt with a string of + the given length. The format of the string returned includes the method + that was used so that :func:`check_password_hash` can check the hash. + + The format for the hashed string looks like this:: + + method$salt$hash + + This method can **not** generate unsalted passwords but it is possible + to set param method='plain' in order to enforce plaintext passwords. + If a salt is used, hmac is used internally to salt the password. + + If PBKDF2 is wanted it can be enabled by setting the method to + ``pbkdf2:method:iterations`` where iterations is optional:: + + pbkdf2:sha256:80000$salt$hash + pbkdf2:sha256$salt$hash + + :param password: the password to hash. + :param method: the hash method to use (one that hashlib supports). Can + optionally be in the format ``pbkdf2:[:iterations]`` + to enable PBKDF2. + :param salt_length: the length of the salt in letters. + """ + salt = gen_salt(salt_length) if method != "plain" else "" + h, actual_method = _hash_internal(method, salt, password) + return "%s$%s$%s" % (actual_method, salt, h) + + +def check_password_hash(pwhash, password): + """check a password against a given salted and hashed password value. + In order to support unsalted legacy passwords this method supports + plain text passwords, md5 and sha1 hashes (both salted and unsalted). + + Returns `True` if the password matched, `False` otherwise. + + :param pwhash: a hashed string like returned by + :func:`generate_password_hash`. + :param password: the plaintext password to compare against the hash. + """ + if pwhash.count("$") < 2: + return False + method, salt, hashval = pwhash.split("$", 2) + return safe_str_cmp(_hash_internal(method, salt, password)[0], hashval) + + +def safe_join(directory, *pathnames): + """Safely join `directory` and one or more untrusted `pathnames`. If this + cannot be done, this function returns ``None``. + + :param directory: the base directory. + :param pathnames: the untrusted pathnames relative to that directory. + """ + parts = [directory] + for filename in pathnames: + if filename != "": + filename = posixpath.normpath(filename) + for sep in _os_alt_seps: + if sep in filename: + return None + if os.path.isabs(filename) or filename == ".." or filename.startswith("../"): + return None + parts.append(filename) + return posixpath.join(*parts) diff --git a/venv/lib/python3.7/site-packages/werkzeug/serving.py b/venv/lib/python3.7/site-packages/werkzeug/serving.py new file mode 100644 index 0000000..ff9f880 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/serving.py @@ -0,0 +1,1074 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.serving + ~~~~~~~~~~~~~~~~ + + There are many ways to serve a WSGI application. While you're developing + it you usually don't want a full blown webserver like Apache but a simple + standalone one. From Python 2.5 onwards there is the `wsgiref`_ server in + the standard library. If you're using older versions of Python you can + download the package from the cheeseshop. + + However there are some caveats. Sourcecode won't reload itself when + changed and each time you kill the server using ``^C`` you get an + `KeyboardInterrupt` error. While the latter is easy to solve the first + one can be a pain in the ass in some situations. + + The easiest way is creating a small ``start-myproject.py`` that runs the + application:: + + #!/usr/bin/env python + # -*- coding: utf-8 -*- + from myproject import make_app + from werkzeug.serving import run_simple + + app = make_app(...) + run_simple('localhost', 8080, app, use_reloader=True) + + You can also pass it a `extra_files` keyword argument with a list of + additional files (like configuration files) you want to observe. + + For bigger applications you should consider using `click` + (http://click.pocoo.org) instead of a simple start file. + + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import io +import os +import signal +import socket +import sys + +import werkzeug +from ._compat import PY2 +from ._compat import reraise +from ._compat import WIN +from ._compat import wsgi_encoding_dance +from ._internal import _log +from .exceptions import InternalServerError +from .urls import uri_to_iri +from .urls import url_parse +from .urls import url_unquote + +try: + import socketserver + from http.server import BaseHTTPRequestHandler + from http.server import HTTPServer +except ImportError: + import SocketServer as socketserver + from BaseHTTPServer import HTTPServer + from BaseHTTPServer import BaseHTTPRequestHandler + +try: + import ssl +except ImportError: + + class _SslDummy(object): + def __getattr__(self, name): + raise RuntimeError("SSL support unavailable") + + ssl = _SslDummy() + +try: + import termcolor +except ImportError: + termcolor = None + + +def _get_openssl_crypto_module(): + try: + from OpenSSL import crypto + except ImportError: + raise TypeError("Using ad-hoc certificates requires the pyOpenSSL library.") + else: + return crypto + + +ThreadingMixIn = socketserver.ThreadingMixIn +can_fork = hasattr(os, "fork") + +if can_fork: + ForkingMixIn = socketserver.ForkingMixIn +else: + + class ForkingMixIn(object): + pass + + +try: + af_unix = socket.AF_UNIX +except AttributeError: + af_unix = None + + +LISTEN_QUEUE = 128 +can_open_by_fd = not WIN and hasattr(socket, "fromfd") + +# On Python 3, ConnectionError represents the same errnos as +# socket.error from Python 2, while socket.error is an alias for the +# more generic OSError. +if PY2: + _ConnectionError = socket.error +else: + _ConnectionError = ConnectionError + + +class DechunkedInput(io.RawIOBase): + """An input stream that handles Transfer-Encoding 'chunked'""" + + def __init__(self, rfile): + self._rfile = rfile + self._done = False + self._len = 0 + + def readable(self): + return True + + def read_chunk_len(self): + try: + line = self._rfile.readline().decode("latin1") + _len = int(line.strip(), 16) + except ValueError: + raise IOError("Invalid chunk header") + if _len < 0: + raise IOError("Negative chunk length not allowed") + return _len + + def readinto(self, buf): + read = 0 + while not self._done and read < len(buf): + if self._len == 0: + # This is the first chunk or we fully consumed the previous + # one. Read the next length of the next chunk + self._len = self.read_chunk_len() + + if self._len == 0: + # Found the final chunk of size 0. The stream is now exhausted, + # but there is still a final newline that should be consumed + self._done = True + + if self._len > 0: + # There is data (left) in this chunk, so append it to the + # buffer. If this operation fully consumes the chunk, this will + # reset self._len to 0. + n = min(len(buf), self._len) + buf[read : read + n] = self._rfile.read(n) + self._len -= n + read += n + + if self._len == 0: + # Skip the terminating newline of a chunk that has been fully + # consumed. This also applies to the 0-sized final chunk + terminator = self._rfile.readline() + if terminator not in (b"\n", b"\r\n", b"\r"): + raise IOError("Missing chunk terminating newline") + + return read + + +class WSGIRequestHandler(BaseHTTPRequestHandler, object): + + """A request handler that implements WSGI dispatching.""" + + @property + def server_version(self): + return "Werkzeug/" + werkzeug.__version__ + + def make_environ(self): + request_url = url_parse(self.path) + + def shutdown_server(): + self.server.shutdown_signal = True + + url_scheme = "http" if self.server.ssl_context is None else "https" + if not self.client_address: + self.client_address = "" + if isinstance(self.client_address, str): + self.client_address = (self.client_address, 0) + else: + pass + path_info = url_unquote(request_url.path) + + environ = { + "wsgi.version": (1, 0), + "wsgi.url_scheme": url_scheme, + "wsgi.input": self.rfile, + "wsgi.errors": sys.stderr, + "wsgi.multithread": self.server.multithread, + "wsgi.multiprocess": self.server.multiprocess, + "wsgi.run_once": False, + "werkzeug.server.shutdown": shutdown_server, + "SERVER_SOFTWARE": self.server_version, + "REQUEST_METHOD": self.command, + "SCRIPT_NAME": "", + "PATH_INFO": wsgi_encoding_dance(path_info), + "QUERY_STRING": wsgi_encoding_dance(request_url.query), + # Non-standard, added by mod_wsgi, uWSGI + "REQUEST_URI": wsgi_encoding_dance(self.path), + # Non-standard, added by gunicorn + "RAW_URI": wsgi_encoding_dance(self.path), + "REMOTE_ADDR": self.address_string(), + "REMOTE_PORT": self.port_integer(), + "SERVER_NAME": self.server.server_address[0], + "SERVER_PORT": str(self.server.server_address[1]), + "SERVER_PROTOCOL": self.request_version, + } + + for key, value in self.get_header_items(): + key = key.upper().replace("-", "_") + value = value.replace("\r\n", "") + if key not in ("CONTENT_TYPE", "CONTENT_LENGTH"): + key = "HTTP_" + key + if key in environ: + value = "{},{}".format(environ[key], value) + environ[key] = value + + if environ.get("HTTP_TRANSFER_ENCODING", "").strip().lower() == "chunked": + environ["wsgi.input_terminated"] = True + environ["wsgi.input"] = DechunkedInput(environ["wsgi.input"]) + + if request_url.scheme and request_url.netloc: + environ["HTTP_HOST"] = request_url.netloc + + return environ + + def run_wsgi(self): + if self.headers.get("Expect", "").lower().strip() == "100-continue": + self.wfile.write(b"HTTP/1.1 100 Continue\r\n\r\n") + + self.environ = environ = self.make_environ() + headers_set = [] + headers_sent = [] + + def write(data): + assert headers_set, "write() before start_response" + if not headers_sent: + status, response_headers = headers_sent[:] = headers_set + try: + code, msg = status.split(None, 1) + except ValueError: + code, msg = status, "" + code = int(code) + self.send_response(code, msg) + header_keys = set() + for key, value in response_headers: + self.send_header(key, value) + key = key.lower() + header_keys.add(key) + if not ( + "content-length" in header_keys + or environ["REQUEST_METHOD"] == "HEAD" + or code < 200 + or code in (204, 304) + ): + self.close_connection = True + self.send_header("Connection", "close") + if "server" not in header_keys: + self.send_header("Server", self.version_string()) + if "date" not in header_keys: + self.send_header("Date", self.date_time_string()) + self.end_headers() + + assert isinstance(data, bytes), "applications must write bytes" + self.wfile.write(data) + self.wfile.flush() + + def start_response(status, response_headers, exc_info=None): + if exc_info: + try: + if headers_sent: + reraise(*exc_info) + finally: + exc_info = None + elif headers_set: + raise AssertionError("Headers already set") + headers_set[:] = [status, response_headers] + return write + + def execute(app): + application_iter = app(environ, start_response) + try: + for data in application_iter: + write(data) + if not headers_sent: + write(b"") + finally: + if hasattr(application_iter, "close"): + application_iter.close() + application_iter = None + + try: + execute(self.server.app) + except (_ConnectionError, socket.timeout) as e: + self.connection_dropped(e, environ) + except Exception: + if self.server.passthrough_errors: + raise + from .debug.tbtools import get_current_traceback + + traceback = get_current_traceback(ignore_system_exceptions=True) + try: + # if we haven't yet sent the headers but they are set + # we roll back to be able to set them again. + if not headers_sent: + del headers_set[:] + execute(InternalServerError()) + except Exception: + pass + self.server.log("error", "Error on request:\n%s", traceback.plaintext) + + def handle(self): + """Handles a request ignoring dropped connections.""" + rv = None + try: + rv = BaseHTTPRequestHandler.handle(self) + except (_ConnectionError, socket.timeout) as e: + self.connection_dropped(e) + except Exception as e: + if self.server.ssl_context is None or not is_ssl_error(e): + raise + if self.server.shutdown_signal: + self.initiate_shutdown() + return rv + + def initiate_shutdown(self): + """A horrible, horrible way to kill the server for Python 2.6 and + later. It's the best we can do. + """ + # Windows does not provide SIGKILL, go with SIGTERM then. + sig = getattr(signal, "SIGKILL", signal.SIGTERM) + # reloader active + if is_running_from_reloader(): + os.kill(os.getpid(), sig) + # python 2.7 + self.server._BaseServer__shutdown_request = True + # python 2.6 + self.server._BaseServer__serving = False + + def connection_dropped(self, error, environ=None): + """Called if the connection was closed by the client. By default + nothing happens. + """ + + def handle_one_request(self): + """Handle a single HTTP request.""" + self.raw_requestline = self.rfile.readline() + if not self.raw_requestline: + self.close_connection = 1 + elif self.parse_request(): + return self.run_wsgi() + + def send_response(self, code, message=None): + """Send the response header and log the response code.""" + self.log_request(code) + if message is None: + message = code in self.responses and self.responses[code][0] or "" + if self.request_version != "HTTP/0.9": + hdr = "%s %d %s\r\n" % (self.protocol_version, code, message) + self.wfile.write(hdr.encode("ascii")) + + def version_string(self): + return BaseHTTPRequestHandler.version_string(self).strip() + + def address_string(self): + if getattr(self, "environ", None): + return self.environ["REMOTE_ADDR"] + elif not self.client_address: + return "" + elif isinstance(self.client_address, str): + return self.client_address + else: + return self.client_address[0] + + def port_integer(self): + return self.client_address[1] + + def log_request(self, code="-", size="-"): + try: + path = uri_to_iri(self.path) + msg = "%s %s %s" % (self.command, path, self.request_version) + except AttributeError: + # path isn't set if the requestline was bad + msg = self.requestline + + code = str(code) + + if termcolor: + color = termcolor.colored + + if code[0] == "1": # 1xx - Informational + msg = color(msg, attrs=["bold"]) + elif code[0] == "2": # 2xx - Success + msg = color(msg, color="white") + elif code == "304": # 304 - Resource Not Modified + msg = color(msg, color="cyan") + elif code[0] == "3": # 3xx - Redirection + msg = color(msg, color="green") + elif code == "404": # 404 - Resource Not Found + msg = color(msg, color="yellow") + elif code[0] == "4": # 4xx - Client Error + msg = color(msg, color="red", attrs=["bold"]) + else: # 5xx, or any other response + msg = color(msg, color="magenta", attrs=["bold"]) + + self.log("info", '"%s" %s %s', msg, code, size) + + def log_error(self, *args): + self.log("error", *args) + + def log_message(self, format, *args): + self.log("info", format, *args) + + def log(self, type, message, *args): + _log( + type, + "%s - - [%s] %s\n" + % (self.address_string(), self.log_date_time_string(), message % args), + ) + + def get_header_items(self): + """ + Get an iterable list of key/value pairs representing headers. + + This function provides Python 2/3 compatibility as related to the + parsing of request headers. Python 2.7 is not compliant with + RFC 3875 Section 4.1.18 which requires multiple values for headers + to be provided or RFC 2616 which allows for folding of multi-line + headers. This function will return a matching list regardless + of Python version. It can be removed once Python 2.7 support + is dropped. + + :return: List of tuples containing header hey/value pairs + """ + if PY2: + # For Python 2, process the headers manually according to + # W3C RFC 2616 Section 4.2. + items = [] + for header in self.headers.headers: + # Remove "\r\n" from the header and split on ":" to get + # the field name and value. + try: + key, value = header[0:-2].split(":", 1) + except ValueError: + # If header could not be slit with : but starts with white + # space and it follows an existing header, it's a folded + # header. + if header[0] in ("\t", " ") and items: + # Pop off the last header + key, value = items.pop() + # Append the current header to the value of the last + # header which will be placed back on the end of the + # list + value = value + header + # Otherwise it's just a bad header and should error + else: + # Re-raise the value error + raise + + # Add the key and the value once stripped of leading + # white space. The specification allows for stripping + # trailing white space but the Python 3 code does not + # strip trailing white space. Therefore, trailing space + # will be left as is to match the Python 3 behavior. + items.append((key, value.lstrip())) + else: + items = self.headers.items() + + return items + + +#: backwards compatible name if someone is subclassing it +BaseRequestHandler = WSGIRequestHandler + + +def generate_adhoc_ssl_pair(cn=None): + from random import random + + crypto = _get_openssl_crypto_module() + + # pretty damn sure that this is not actually accepted by anyone + if cn is None: + cn = "*" + + cert = crypto.X509() + cert.set_serial_number(int(random() * sys.maxsize)) + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(60 * 60 * 24 * 365) + + subject = cert.get_subject() + subject.CN = cn + subject.O = "Dummy Certificate" # noqa: E741 + + issuer = cert.get_issuer() + issuer.CN = subject.CN + issuer.O = subject.O # noqa: E741 + + pkey = crypto.PKey() + pkey.generate_key(crypto.TYPE_RSA, 2048) + cert.set_pubkey(pkey) + cert.sign(pkey, "sha256") + + return cert, pkey + + +def make_ssl_devcert(base_path, host=None, cn=None): + """Creates an SSL key for development. This should be used instead of + the ``'adhoc'`` key which generates a new cert on each server start. + It accepts a path for where it should store the key and cert and + either a host or CN. If a host is given it will use the CN + ``*.host/CN=host``. + + For more information see :func:`run_simple`. + + .. versionadded:: 0.9 + + :param base_path: the path to the certificate and key. The extension + ``.crt`` is added for the certificate, ``.key`` is + added for the key. + :param host: the name of the host. This can be used as an alternative + for the `cn`. + :param cn: the `CN` to use. + """ + from OpenSSL import crypto + + if host is not None: + cn = "*.%s/CN=%s" % (host, host) + cert, pkey = generate_adhoc_ssl_pair(cn=cn) + + cert_file = base_path + ".crt" + pkey_file = base_path + ".key" + + with open(cert_file, "wb") as f: + f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) + with open(pkey_file, "wb") as f: + f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)) + + return cert_file, pkey_file + + +def generate_adhoc_ssl_context(): + """Generates an adhoc SSL context for the development server.""" + crypto = _get_openssl_crypto_module() + import tempfile + import atexit + + cert, pkey = generate_adhoc_ssl_pair() + cert_handle, cert_file = tempfile.mkstemp() + pkey_handle, pkey_file = tempfile.mkstemp() + atexit.register(os.remove, pkey_file) + atexit.register(os.remove, cert_file) + + os.write(cert_handle, crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) + os.write(pkey_handle, crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)) + os.close(cert_handle) + os.close(pkey_handle) + ctx = load_ssl_context(cert_file, pkey_file) + return ctx + + +def load_ssl_context(cert_file, pkey_file=None, protocol=None): + """Loads SSL context from cert/private key files and optional protocol. + Many parameters are directly taken from the API of + :py:class:`ssl.SSLContext`. + + :param cert_file: Path of the certificate to use. + :param pkey_file: Path of the private key to use. If not given, the key + will be obtained from the certificate file. + :param protocol: One of the ``PROTOCOL_*`` constants in the stdlib ``ssl`` + module. Defaults to ``PROTOCOL_SSLv23``. + """ + if protocol is None: + protocol = ssl.PROTOCOL_SSLv23 + ctx = _SSLContext(protocol) + ctx.load_cert_chain(cert_file, pkey_file) + return ctx + + +class _SSLContext(object): + + """A dummy class with a small subset of Python3's ``ssl.SSLContext``, only + intended to be used with and by Werkzeug.""" + + def __init__(self, protocol): + self._protocol = protocol + self._certfile = None + self._keyfile = None + self._password = None + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._certfile = certfile + self._keyfile = keyfile or certfile + self._password = password + + def wrap_socket(self, sock, **kwargs): + return ssl.wrap_socket( + sock, + keyfile=self._keyfile, + certfile=self._certfile, + ssl_version=self._protocol, + **kwargs + ) + + +def is_ssl_error(error=None): + """Checks if the given error (or the current one) is an SSL error.""" + exc_types = (ssl.SSLError,) + try: + from OpenSSL.SSL import Error + + exc_types += (Error,) + except ImportError: + pass + + if error is None: + error = sys.exc_info()[1] + return isinstance(error, exc_types) + + +def select_address_family(host, port): + """Return ``AF_INET4``, ``AF_INET6``, or ``AF_UNIX`` depending on + the host and port.""" + # disabled due to problems with current ipv6 implementations + # and various operating systems. Probably this code also is + # not supposed to work, but I can't come up with any other + # ways to implement this. + # try: + # info = socket.getaddrinfo(host, port, socket.AF_UNSPEC, + # socket.SOCK_STREAM, 0, + # socket.AI_PASSIVE) + # if info: + # return info[0][0] + # except socket.gaierror: + # pass + if host.startswith("unix://"): + return socket.AF_UNIX + elif ":" in host and hasattr(socket, "AF_INET6"): + return socket.AF_INET6 + return socket.AF_INET + + +def get_sockaddr(host, port, family): + """Return a fully qualified socket address that can be passed to + :func:`socket.bind`.""" + if family == af_unix: + return host.split("://", 1)[1] + try: + res = socket.getaddrinfo( + host, port, family, socket.SOCK_STREAM, socket.IPPROTO_TCP + ) + except socket.gaierror: + return host, port + return res[0][4] + + +class BaseWSGIServer(HTTPServer, object): + + """Simple single-threaded, single-process WSGI server.""" + + multithread = False + multiprocess = False + request_queue_size = LISTEN_QUEUE + + def __init__( + self, + host, + port, + app, + handler=None, + passthrough_errors=False, + ssl_context=None, + fd=None, + ): + if handler is None: + handler = WSGIRequestHandler + + self.address_family = select_address_family(host, port) + + if fd is not None: + real_sock = socket.fromfd(fd, self.address_family, socket.SOCK_STREAM) + port = 0 + + server_address = get_sockaddr(host, int(port), self.address_family) + + # remove socket file if it already exists + if self.address_family == af_unix and os.path.exists(server_address): + os.unlink(server_address) + HTTPServer.__init__(self, server_address, handler) + + self.app = app + self.passthrough_errors = passthrough_errors + self.shutdown_signal = False + self.host = host + self.port = self.socket.getsockname()[1] + + # Patch in the original socket. + if fd is not None: + self.socket.close() + self.socket = real_sock + self.server_address = self.socket.getsockname() + + if ssl_context is not None: + if isinstance(ssl_context, tuple): + ssl_context = load_ssl_context(*ssl_context) + if ssl_context == "adhoc": + ssl_context = generate_adhoc_ssl_context() + # If we are on Python 2 the return value from socket.fromfd + # is an internal socket object but what we need for ssl wrap + # is the wrapper around it :( + sock = self.socket + if PY2 and not isinstance(sock, socket.socket): + sock = socket.socket(sock.family, sock.type, sock.proto, sock) + self.socket = ssl_context.wrap_socket(sock, server_side=True) + self.ssl_context = ssl_context + else: + self.ssl_context = None + + def log(self, type, message, *args): + _log(type, message, *args) + + def serve_forever(self): + self.shutdown_signal = False + try: + HTTPServer.serve_forever(self) + except KeyboardInterrupt: + pass + finally: + self.server_close() + + def handle_error(self, request, client_address): + if self.passthrough_errors: + raise + # Python 2 still causes a socket.error after the earlier + # handling, so silence it here. + if isinstance(sys.exc_info()[1], _ConnectionError): + return + return HTTPServer.handle_error(self, request, client_address) + + def get_request(self): + con, info = self.socket.accept() + return con, info + + +class ThreadedWSGIServer(ThreadingMixIn, BaseWSGIServer): + + """A WSGI server that does threading.""" + + multithread = True + daemon_threads = True + + +class ForkingWSGIServer(ForkingMixIn, BaseWSGIServer): + + """A WSGI server that does forking.""" + + multiprocess = True + + def __init__( + self, + host, + port, + app, + processes=40, + handler=None, + passthrough_errors=False, + ssl_context=None, + fd=None, + ): + if not can_fork: + raise ValueError("Your platform does not support forking.") + BaseWSGIServer.__init__( + self, host, port, app, handler, passthrough_errors, ssl_context, fd + ) + self.max_children = processes + + +def make_server( + host=None, + port=None, + app=None, + threaded=False, + processes=1, + request_handler=None, + passthrough_errors=False, + ssl_context=None, + fd=None, +): + """Create a new server instance that is either threaded, or forks + or just processes one request after another. + """ + if threaded and processes > 1: + raise ValueError("cannot have a multithreaded and multi process server.") + elif threaded: + return ThreadedWSGIServer( + host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd + ) + elif processes > 1: + return ForkingWSGIServer( + host, + port, + app, + processes, + request_handler, + passthrough_errors, + ssl_context, + fd=fd, + ) + else: + return BaseWSGIServer( + host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd + ) + + +def is_running_from_reloader(): + """Checks if the application is running from within the Werkzeug + reloader subprocess. + + .. versionadded:: 0.10 + """ + return os.environ.get("WERKZEUG_RUN_MAIN") == "true" + + +def run_simple( + hostname, + port, + application, + use_reloader=False, + use_debugger=False, + use_evalex=True, + extra_files=None, + reloader_interval=1, + reloader_type="auto", + threaded=False, + processes=1, + request_handler=None, + static_files=None, + passthrough_errors=False, + ssl_context=None, +): + """Start a WSGI application. Optional features include a reloader, + multithreading and fork support. + + This function has a command-line interface too:: + + python -m werkzeug.serving --help + + .. versionadded:: 0.5 + `static_files` was added to simplify serving of static files as well + as `passthrough_errors`. + + .. versionadded:: 0.6 + support for SSL was added. + + .. versionadded:: 0.8 + Added support for automatically loading a SSL context from certificate + file and private key. + + .. versionadded:: 0.9 + Added command-line interface. + + .. versionadded:: 0.10 + Improved the reloader and added support for changing the backend + through the `reloader_type` parameter. See :ref:`reloader` + for more information. + + .. versionchanged:: 0.15 + Bind to a Unix socket by passing a path that starts with + ``unix://`` as the ``hostname``. + + :param hostname: The host to bind to, for example ``'localhost'``. + If the value is a path that starts with ``unix://`` it will bind + to a Unix socket instead of a TCP socket.. + :param port: The port for the server. eg: ``8080`` + :param application: the WSGI application to execute + :param use_reloader: should the server automatically restart the python + process if modules were changed? + :param use_debugger: should the werkzeug debugging system be used? + :param use_evalex: should the exception evaluation feature be enabled? + :param extra_files: a list of files the reloader should watch + additionally to the modules. For example configuration + files. + :param reloader_interval: the interval for the reloader in seconds. + :param reloader_type: the type of reloader to use. The default is + auto detection. Valid values are ``'stat'`` and + ``'watchdog'``. See :ref:`reloader` for more + information. + :param threaded: should the process handle each request in a separate + thread? + :param processes: if greater than 1 then handle each request in a new process + up to this maximum number of concurrent processes. + :param request_handler: optional parameter that can be used to replace + the default one. You can use this to replace it + with a different + :class:`~BaseHTTPServer.BaseHTTPRequestHandler` + subclass. + :param static_files: a list or dict of paths for static files. This works + exactly like :class:`SharedDataMiddleware`, it's actually + just wrapping the application in that middleware before + serving. + :param passthrough_errors: set this to `True` to disable the error catching. + This means that the server will die on errors but + it can be useful to hook debuggers in (pdb etc.) + :param ssl_context: an SSL context for the connection. Either an + :class:`ssl.SSLContext`, a tuple in the form + ``(cert_file, pkey_file)``, the string ``'adhoc'`` if + the server should automatically create one, or ``None`` + to disable SSL (which is the default). + """ + if not isinstance(port, int): + raise TypeError("port must be an integer") + if use_debugger: + from .debug import DebuggedApplication + + application = DebuggedApplication(application, use_evalex) + if static_files: + from .middleware.shared_data import SharedDataMiddleware + + application = SharedDataMiddleware(application, static_files) + + def log_startup(sock): + display_hostname = hostname if hostname not in ("", "*") else "localhost" + quit_msg = "(Press CTRL+C to quit)" + if sock.family == af_unix: + _log("info", " * Running on %s %s", display_hostname, quit_msg) + else: + if ":" in display_hostname: + display_hostname = "[%s]" % display_hostname + port = sock.getsockname()[1] + _log( + "info", + " * Running on %s://%s:%d/ %s", + "http" if ssl_context is None else "https", + display_hostname, + port, + quit_msg, + ) + + def inner(): + try: + fd = int(os.environ["WERKZEUG_SERVER_FD"]) + except (LookupError, ValueError): + fd = None + srv = make_server( + hostname, + port, + application, + threaded, + processes, + request_handler, + passthrough_errors, + ssl_context, + fd=fd, + ) + if fd is None: + log_startup(srv.socket) + srv.serve_forever() + + if use_reloader: + # If we're not running already in the subprocess that is the + # reloader we want to open up a socket early to make sure the + # port is actually available. + if not is_running_from_reloader(): + if port == 0 and not can_open_by_fd: + raise ValueError( + "Cannot bind to a random port with enabled " + "reloader if the Python interpreter does " + "not support socket opening by fd." + ) + + # Create and destroy a socket so that any exceptions are + # raised before we spawn a separate Python interpreter and + # lose this ability. + address_family = select_address_family(hostname, port) + server_address = get_sockaddr(hostname, port, address_family) + s = socket.socket(address_family, socket.SOCK_STREAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind(server_address) + if hasattr(s, "set_inheritable"): + s.set_inheritable(True) + + # If we can open the socket by file descriptor, then we can just + # reuse this one and our socket will survive the restarts. + if can_open_by_fd: + os.environ["WERKZEUG_SERVER_FD"] = str(s.fileno()) + s.listen(LISTEN_QUEUE) + log_startup(s) + else: + s.close() + if address_family == af_unix: + _log("info", "Unlinking %s" % server_address) + os.unlink(server_address) + + # Do not use relative imports, otherwise "python -m werkzeug.serving" + # breaks. + from ._reloader import run_with_reloader + + run_with_reloader(inner, extra_files, reloader_interval, reloader_type) + else: + inner() + + +def run_with_reloader(*args, **kwargs): + # People keep using undocumented APIs. Do not use this function + # please, we do not guarantee that it continues working. + from ._reloader import run_with_reloader + + return run_with_reloader(*args, **kwargs) + + +def main(): + """A simple command-line interface for :py:func:`run_simple`.""" + + # in contrast to argparse, this works at least under Python < 2.7 + import optparse + from .utils import import_string + + parser = optparse.OptionParser(usage="Usage: %prog [options] app_module:app_object") + parser.add_option( + "-b", + "--bind", + dest="address", + help="The hostname:port the app should listen on.", + ) + parser.add_option( + "-d", + "--debug", + dest="use_debugger", + action="store_true", + default=False, + help="Use Werkzeug's debugger.", + ) + parser.add_option( + "-r", + "--reload", + dest="use_reloader", + action="store_true", + default=False, + help="Reload Python process if modules change.", + ) + options, args = parser.parse_args() + + hostname, port = None, None + if options.address: + address = options.address.split(":") + hostname = address[0] + if len(address) > 1: + port = address[1] + + if len(args) != 1: + sys.stdout.write("No application supplied, or too much. See --help\n") + sys.exit(1) + app = import_string(args[0]) + + run_simple( + hostname=(hostname or "127.0.0.1"), + port=int(port or 5000), + application=app, + use_reloader=options.use_reloader, + use_debugger=options.use_debugger, + ) + + +if __name__ == "__main__": + main() diff --git a/venv/lib/python3.7/site-packages/werkzeug/test.py b/venv/lib/python3.7/site-packages/werkzeug/test.py new file mode 100644 index 0000000..6148665 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/test.py @@ -0,0 +1,1146 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.test + ~~~~~~~~~~~~~ + + This module implements a client to WSGI applications for testing. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import mimetypes +import sys +from io import BytesIO +from itertools import chain +from random import random +from tempfile import TemporaryFile +from time import time + +from ._compat import iteritems +from ._compat import iterlists +from ._compat import itervalues +from ._compat import make_literal_wrapper +from ._compat import reraise +from ._compat import string_types +from ._compat import text_type +from ._compat import to_bytes +from ._compat import wsgi_encoding_dance +from ._internal import _get_environ +from .datastructures import CallbackDict +from .datastructures import CombinedMultiDict +from .datastructures import EnvironHeaders +from .datastructures import FileMultiDict +from .datastructures import FileStorage +from .datastructures import Headers +from .datastructures import MultiDict +from .http import dump_cookie +from .http import dump_options_header +from .http import parse_options_header +from .urls import iri_to_uri +from .urls import url_encode +from .urls import url_fix +from .urls import url_parse +from .urls import url_unparse +from .urls import url_unquote +from .utils import get_content_type +from .wrappers import BaseRequest +from .wsgi import ClosingIterator +from .wsgi import get_current_url + +try: + from urllib.request import Request as U2Request +except ImportError: + from urllib2 import Request as U2Request + +try: + from http.cookiejar import CookieJar +except ImportError: + from cookielib import CookieJar + + +def stream_encode_multipart( + values, use_tempfile=True, threshold=1024 * 500, boundary=None, charset="utf-8" +): + """Encode a dict of values (either strings or file descriptors or + :class:`FileStorage` objects.) into a multipart encoded string stored + in a file descriptor. + """ + if boundary is None: + boundary = "---------------WerkzeugFormPart_%s%s" % (time(), random()) + _closure = [BytesIO(), 0, False] + + if use_tempfile: + + def write_binary(string): + stream, total_length, on_disk = _closure + if on_disk: + stream.write(string) + else: + length = len(string) + if length + _closure[1] <= threshold: + stream.write(string) + else: + new_stream = TemporaryFile("wb+") + new_stream.write(stream.getvalue()) + new_stream.write(string) + _closure[0] = new_stream + _closure[2] = True + _closure[1] = total_length + length + + else: + write_binary = _closure[0].write + + def write(string): + write_binary(string.encode(charset)) + + if not isinstance(values, MultiDict): + values = MultiDict(values) + + for key, values in iterlists(values): + for value in values: + write('--%s\r\nContent-Disposition: form-data; name="%s"' % (boundary, key)) + reader = getattr(value, "read", None) + if reader is not None: + filename = getattr(value, "filename", getattr(value, "name", None)) + content_type = getattr(value, "content_type", None) + if content_type is None: + content_type = ( + filename + and mimetypes.guess_type(filename)[0] + or "application/octet-stream" + ) + if filename is not None: + write('; filename="%s"\r\n' % filename) + else: + write("\r\n") + write("Content-Type: %s\r\n\r\n" % content_type) + while 1: + chunk = reader(16384) + if not chunk: + break + write_binary(chunk) + else: + if not isinstance(value, string_types): + value = str(value) + + value = to_bytes(value, charset) + write("\r\n\r\n") + write_binary(value) + write("\r\n") + write("--%s--\r\n" % boundary) + + length = int(_closure[0].tell()) + _closure[0].seek(0) + return _closure[0], length, boundary + + +def encode_multipart(values, boundary=None, charset="utf-8"): + """Like `stream_encode_multipart` but returns a tuple in the form + (``boundary``, ``data``) where data is a bytestring. + """ + stream, length, boundary = stream_encode_multipart( + values, use_tempfile=False, boundary=boundary, charset=charset + ) + return boundary, stream.read() + + +def File(fd, filename=None, mimetype=None): + """Backwards compat. + + .. deprecated:: 0.5 + """ + from warnings import warn + + warn( + "'werkzeug.test.File' is deprecated as of version 0.5 and will" + " be removed in version 1.0. Use 'EnvironBuilder' or" + " 'FileStorage' instead.", + DeprecationWarning, + stacklevel=2, + ) + return FileStorage(fd, filename=filename, content_type=mimetype) + + +class _TestCookieHeaders(object): + + """A headers adapter for cookielib + """ + + def __init__(self, headers): + self.headers = headers + + def getheaders(self, name): + headers = [] + name = name.lower() + for k, v in self.headers: + if k.lower() == name: + headers.append(v) + return headers + + def get_all(self, name, default=None): + rv = [] + for k, v in self.headers: + if k.lower() == name.lower(): + rv.append(v) + return rv or default or [] + + +class _TestCookieResponse(object): + + """Something that looks like a httplib.HTTPResponse, but is actually just an + adapter for our test responses to make them available for cookielib. + """ + + def __init__(self, headers): + self.headers = _TestCookieHeaders(headers) + + def info(self): + return self.headers + + +class _TestCookieJar(CookieJar): + + """A cookielib.CookieJar modified to inject and read cookie headers from + and to wsgi environments, and wsgi application responses. + """ + + def inject_wsgi(self, environ): + """Inject the cookies as client headers into the server's wsgi + environment. + """ + cvals = ["%s=%s" % (c.name, c.value) for c in self] + + if cvals: + environ["HTTP_COOKIE"] = "; ".join(cvals) + else: + environ.pop("HTTP_COOKIE", None) + + def extract_wsgi(self, environ, headers): + """Extract the server's set-cookie headers as cookies into the + cookie jar. + """ + self.extract_cookies( + _TestCookieResponse(headers), U2Request(get_current_url(environ)) + ) + + +def _iter_data(data): + """Iterates over a `dict` or :class:`MultiDict` yielding all keys and + values. + This is used to iterate over the data passed to the + :class:`EnvironBuilder`. + """ + if isinstance(data, MultiDict): + for key, values in iterlists(data): + for value in values: + yield key, value + else: + for key, values in iteritems(data): + if isinstance(values, list): + for value in values: + yield key, value + else: + yield key, values + + +class EnvironBuilder(object): + """This class can be used to conveniently create a WSGI environment + for testing purposes. It can be used to quickly create WSGI environments + or request objects from arbitrary data. + + The signature of this class is also used in some other places as of + Werkzeug 0.5 (:func:`create_environ`, :meth:`BaseResponse.from_values`, + :meth:`Client.open`). Because of this most of the functionality is + available through the constructor alone. + + Files and regular form data can be manipulated independently of each + other with the :attr:`form` and :attr:`files` attributes, but are + passed with the same argument to the constructor: `data`. + + `data` can be any of these values: + + - a `str` or `bytes` object: The object is converted into an + :attr:`input_stream`, the :attr:`content_length` is set and you have to + provide a :attr:`content_type`. + - a `dict` or :class:`MultiDict`: The keys have to be strings. The values + have to be either any of the following objects, or a list of any of the + following objects: + + - a :class:`file`-like object: These are converted into + :class:`FileStorage` objects automatically. + - a `tuple`: The :meth:`~FileMultiDict.add_file` method is called + with the key and the unpacked `tuple` items as positional + arguments. + - a `str`: The string is set as form data for the associated key. + - a file-like object: The object content is loaded in memory and then + handled like a regular `str` or a `bytes`. + + :param path: the path of the request. In the WSGI environment this will + end up as `PATH_INFO`. If the `query_string` is not defined + and there is a question mark in the `path` everything after + it is used as query string. + :param base_url: the base URL is a URL that is used to extract the WSGI + URL scheme, host (server name + server port) and the + script root (`SCRIPT_NAME`). + :param query_string: an optional string or dict with URL parameters. + :param method: the HTTP method to use, defaults to `GET`. + :param input_stream: an optional input stream. Do not specify this and + `data`. As soon as an input stream is set you can't + modify :attr:`args` and :attr:`files` unless you + set the :attr:`input_stream` to `None` again. + :param content_type: The content type for the request. As of 0.5 you + don't have to provide this when specifying files + and form data via `data`. + :param content_length: The content length for the request. You don't + have to specify this when providing data via + `data`. + :param errors_stream: an optional error stream that is used for + `wsgi.errors`. Defaults to :data:`stderr`. + :param multithread: controls `wsgi.multithread`. Defaults to `False`. + :param multiprocess: controls `wsgi.multiprocess`. Defaults to `False`. + :param run_once: controls `wsgi.run_once`. Defaults to `False`. + :param headers: an optional list or :class:`Headers` object of headers. + :param data: a string or dict of form data or a file-object. + See explanation above. + :param json: An object to be serialized and assigned to ``data``. + Defaults the content type to ``"application/json"``. + Serialized with the function assigned to :attr:`json_dumps`. + :param environ_base: an optional dict of environment defaults. + :param environ_overrides: an optional dict of environment overrides. + :param charset: the charset used to encode unicode data. + + .. versionadded:: 0.15 + The ``json`` param and :meth:`json_dumps` method. + + .. versionadded:: 0.15 + The environ has keys ``REQUEST_URI`` and ``RAW_URI`` containing + the path before perecent-decoding. This is not part of the WSGI + PEP, but many WSGI servers include it. + + .. versionchanged:: 0.6 + ``path`` and ``base_url`` can now be unicode strings that are + encoded with :func:`iri_to_uri`. + """ + + #: the server protocol to use. defaults to HTTP/1.1 + server_protocol = "HTTP/1.1" + + #: the wsgi version to use. defaults to (1, 0) + wsgi_version = (1, 0) + + #: the default request class for :meth:`get_request` + request_class = BaseRequest + + import json + + #: The serialization function used when ``json`` is passed. + json_dumps = staticmethod(json.dumps) + del json + + def __init__( + self, + path="/", + base_url=None, + query_string=None, + method="GET", + input_stream=None, + content_type=None, + content_length=None, + errors_stream=None, + multithread=False, + multiprocess=False, + run_once=False, + headers=None, + data=None, + environ_base=None, + environ_overrides=None, + charset="utf-8", + mimetype=None, + json=None, + ): + path_s = make_literal_wrapper(path) + if query_string is not None and path_s("?") in path: + raise ValueError("Query string is defined in the path and as an argument") + if query_string is None and path_s("?") in path: + path, query_string = path.split(path_s("?"), 1) + self.charset = charset + self.path = iri_to_uri(path) + if base_url is not None: + base_url = url_fix(iri_to_uri(base_url, charset), charset) + self.base_url = base_url + if isinstance(query_string, (bytes, text_type)): + self.query_string = query_string + else: + if query_string is None: + query_string = MultiDict() + elif not isinstance(query_string, MultiDict): + query_string = MultiDict(query_string) + self.args = query_string + self.method = method + if headers is None: + headers = Headers() + elif not isinstance(headers, Headers): + headers = Headers(headers) + self.headers = headers + if content_type is not None: + self.content_type = content_type + if errors_stream is None: + errors_stream = sys.stderr + self.errors_stream = errors_stream + self.multithread = multithread + self.multiprocess = multiprocess + self.run_once = run_once + self.environ_base = environ_base + self.environ_overrides = environ_overrides + self.input_stream = input_stream + self.content_length = content_length + self.closed = False + + if json is not None: + if data is not None: + raise TypeError("can't provide both json and data") + + data = self.json_dumps(json) + + if self.content_type is None: + self.content_type = "application/json" + + if data: + if input_stream is not None: + raise TypeError("can't provide input stream and data") + if hasattr(data, "read"): + data = data.read() + if isinstance(data, text_type): + data = data.encode(self.charset) + if isinstance(data, bytes): + self.input_stream = BytesIO(data) + if self.content_length is None: + self.content_length = len(data) + else: + for key, value in _iter_data(data): + if isinstance(value, (tuple, dict)) or hasattr(value, "read"): + self._add_file_from_data(key, value) + else: + self.form.setlistdefault(key).append(value) + + if mimetype is not None: + self.mimetype = mimetype + + @classmethod + def from_environ(cls, environ, **kwargs): + """Turn an environ dict back into a builder. Any extra kwargs + override the args extracted from the environ. + + .. versionadded:: 0.15 + """ + headers = Headers(EnvironHeaders(environ)) + out = { + "path": environ["PATH_INFO"], + "base_url": cls._make_base_url( + environ["wsgi.url_scheme"], headers.pop("Host"), environ["SCRIPT_NAME"] + ), + "query_string": environ["QUERY_STRING"], + "method": environ["REQUEST_METHOD"], + "input_stream": environ["wsgi.input"], + "content_type": headers.pop("Content-Type", None), + "content_length": headers.pop("Content-Length", None), + "errors_stream": environ["wsgi.errors"], + "multithread": environ["wsgi.multithread"], + "multiprocess": environ["wsgi.multiprocess"], + "run_once": environ["wsgi.run_once"], + "headers": headers, + } + out.update(kwargs) + return cls(**out) + + def _add_file_from_data(self, key, value): + """Called in the EnvironBuilder to add files from the data dict.""" + if isinstance(value, tuple): + self.files.add_file(key, *value) + elif isinstance(value, dict): + from warnings import warn + + warn( + "Passing a dict as file data is deprecated as of" + " version 0.5 and will be removed in version 1.0. Use" + " a tuple or 'FileStorage' object instead.", + DeprecationWarning, + stacklevel=2, + ) + value = dict(value) + mimetype = value.pop("mimetype", None) + if mimetype is not None: + value["content_type"] = mimetype + self.files.add_file(key, **value) + else: + self.files.add_file(key, value) + + @staticmethod + def _make_base_url(scheme, host, script_root): + return url_unparse((scheme, host, script_root, "", "")).rstrip("/") + "/" + + @property + def base_url(self): + """The base URL is used to extract the URL scheme, host name, + port, and root path. + """ + return self._make_base_url(self.url_scheme, self.host, self.script_root) + + @base_url.setter + def base_url(self, value): + if value is None: + scheme = "http" + netloc = "localhost" + script_root = "" + else: + scheme, netloc, script_root, qs, anchor = url_parse(value) + if qs or anchor: + raise ValueError("base url must not contain a query string or fragment") + self.script_root = script_root.rstrip("/") + self.host = netloc + self.url_scheme = scheme + + def _get_content_type(self): + ct = self.headers.get("Content-Type") + if ct is None and not self._input_stream: + if self._files: + return "multipart/form-data" + elif self._form: + return "application/x-www-form-urlencoded" + return None + return ct + + def _set_content_type(self, value): + if value is None: + self.headers.pop("Content-Type", None) + else: + self.headers["Content-Type"] = value + + content_type = property( + _get_content_type, + _set_content_type, + doc="""The content type for the request. Reflected from and to + the :attr:`headers`. Do not set if you set :attr:`files` or + :attr:`form` for auto detection.""", + ) + del _get_content_type, _set_content_type + + def _get_content_length(self): + return self.headers.get("Content-Length", type=int) + + def _get_mimetype(self): + ct = self.content_type + if ct: + return ct.split(";")[0].strip() + + def _set_mimetype(self, value): + self.content_type = get_content_type(value, self.charset) + + def _get_mimetype_params(self): + def on_update(d): + self.headers["Content-Type"] = dump_options_header(self.mimetype, d) + + d = parse_options_header(self.headers.get("content-type", ""))[1] + return CallbackDict(d, on_update) + + mimetype = property( + _get_mimetype, + _set_mimetype, + doc="""The mimetype (content type without charset etc.) + + .. versionadded:: 0.14 + """, + ) + mimetype_params = property( + _get_mimetype_params, + doc=""" The mimetype parameters as dict. For example if the + content type is ``text/html; charset=utf-8`` the params would be + ``{'charset': 'utf-8'}``. + + .. versionadded:: 0.14 + """, + ) + del _get_mimetype, _set_mimetype, _get_mimetype_params + + def _set_content_length(self, value): + if value is None: + self.headers.pop("Content-Length", None) + else: + self.headers["Content-Length"] = str(value) + + content_length = property( + _get_content_length, + _set_content_length, + doc="""The content length as integer. Reflected from and to the + :attr:`headers`. Do not set if you set :attr:`files` or + :attr:`form` for auto detection.""", + ) + del _get_content_length, _set_content_length + + def form_property(name, storage, doc): # noqa: B902 + key = "_" + name + + def getter(self): + if self._input_stream is not None: + raise AttributeError("an input stream is defined") + rv = getattr(self, key) + if rv is None: + rv = storage() + setattr(self, key, rv) + + return rv + + def setter(self, value): + self._input_stream = None + setattr(self, key, value) + + return property(getter, setter, doc=doc) + + form = form_property("form", MultiDict, doc="A :class:`MultiDict` of form values.") + files = form_property( + "files", + FileMultiDict, + doc="""A :class:`FileMultiDict` of uploaded files. You can use + the :meth:`~FileMultiDict.add_file` method to add new files to + the dict.""", + ) + del form_property + + def _get_input_stream(self): + return self._input_stream + + def _set_input_stream(self, value): + self._input_stream = value + self._form = self._files = None + + input_stream = property( + _get_input_stream, + _set_input_stream, + doc="""An optional input stream. If you set this it will clear + :attr:`form` and :attr:`files`.""", + ) + del _get_input_stream, _set_input_stream + + def _get_query_string(self): + if self._query_string is None: + if self._args is not None: + return url_encode(self._args, charset=self.charset) + return "" + return self._query_string + + def _set_query_string(self, value): + self._query_string = value + self._args = None + + query_string = property( + _get_query_string, + _set_query_string, + doc="""The query string. If you set this to a string + :attr:`args` will no longer be available.""", + ) + del _get_query_string, _set_query_string + + def _get_args(self): + if self._query_string is not None: + raise AttributeError("a query string is defined") + if self._args is None: + self._args = MultiDict() + return self._args + + def _set_args(self, value): + self._query_string = None + self._args = value + + args = property( + _get_args, _set_args, doc="The URL arguments as :class:`MultiDict`." + ) + del _get_args, _set_args + + @property + def server_name(self): + """The server name (read-only, use :attr:`host` to set)""" + return self.host.split(":", 1)[0] + + @property + def server_port(self): + """The server port as integer (read-only, use :attr:`host` to set)""" + pieces = self.host.split(":", 1) + if len(pieces) == 2 and pieces[1].isdigit(): + return int(pieces[1]) + elif self.url_scheme == "https": + return 443 + return 80 + + def __del__(self): + try: + self.close() + except Exception: + pass + + def close(self): + """Closes all files. If you put real :class:`file` objects into the + :attr:`files` dict you can call this method to automatically close + them all in one go. + """ + if self.closed: + return + try: + files = itervalues(self.files) + except AttributeError: + files = () + for f in files: + try: + f.close() + except Exception: + pass + self.closed = True + + def get_environ(self): + """Return the built environ. + + .. versionchanged:: 0.15 + The content type and length headers are set based on + input stream detection. Previously this only set the WSGI + keys. + """ + input_stream = self.input_stream + content_length = self.content_length + + mimetype = self.mimetype + content_type = self.content_type + + if input_stream is not None: + start_pos = input_stream.tell() + input_stream.seek(0, 2) + end_pos = input_stream.tell() + input_stream.seek(start_pos) + content_length = end_pos - start_pos + elif mimetype == "multipart/form-data": + values = CombinedMultiDict([self.form, self.files]) + input_stream, content_length, boundary = stream_encode_multipart( + values, charset=self.charset + ) + content_type = mimetype + '; boundary="%s"' % boundary + elif mimetype == "application/x-www-form-urlencoded": + # XXX: py2v3 review + values = url_encode(self.form, charset=self.charset) + values = values.encode("ascii") + content_length = len(values) + input_stream = BytesIO(values) + else: + input_stream = BytesIO() + + result = {} + if self.environ_base: + result.update(self.environ_base) + + def _path_encode(x): + return wsgi_encoding_dance(url_unquote(x, self.charset), self.charset) + + qs = wsgi_encoding_dance(self.query_string) + + result.update( + { + "REQUEST_METHOD": self.method, + "SCRIPT_NAME": _path_encode(self.script_root), + "PATH_INFO": _path_encode(self.path), + "QUERY_STRING": qs, + # Non-standard, added by mod_wsgi, uWSGI + "REQUEST_URI": wsgi_encoding_dance(self.path), + # Non-standard, added by gunicorn + "RAW_URI": wsgi_encoding_dance(self.path), + "SERVER_NAME": self.server_name, + "SERVER_PORT": str(self.server_port), + "HTTP_HOST": self.host, + "SERVER_PROTOCOL": self.server_protocol, + "wsgi.version": self.wsgi_version, + "wsgi.url_scheme": self.url_scheme, + "wsgi.input": input_stream, + "wsgi.errors": self.errors_stream, + "wsgi.multithread": self.multithread, + "wsgi.multiprocess": self.multiprocess, + "wsgi.run_once": self.run_once, + } + ) + + headers = self.headers.copy() + + if content_type is not None: + result["CONTENT_TYPE"] = content_type + headers.set("Content-Type", content_type) + + if content_length is not None: + result["CONTENT_LENGTH"] = str(content_length) + headers.set("Content-Length", content_length) + + for key, value in headers.to_wsgi_list(): + result["HTTP_%s" % key.upper().replace("-", "_")] = value + + if self.environ_overrides: + result.update(self.environ_overrides) + + return result + + def get_request(self, cls=None): + """Returns a request with the data. If the request class is not + specified :attr:`request_class` is used. + + :param cls: The request wrapper to use. + """ + if cls is None: + cls = self.request_class + return cls(self.get_environ()) + + +class ClientRedirectError(Exception): + """If a redirect loop is detected when using follow_redirects=True with + the :cls:`Client`, then this exception is raised. + """ + + +class Client(object): + """This class allows you to send requests to a wrapped application. + + The response wrapper can be a class or factory function that takes + three arguments: app_iter, status and headers. The default response + wrapper just returns a tuple. + + Example:: + + class ClientResponse(BaseResponse): + ... + + client = Client(MyApplication(), response_wrapper=ClientResponse) + + The use_cookies parameter indicates whether cookies should be stored and + sent for subsequent requests. This is True by default, but passing False + will disable this behaviour. + + If you want to request some subdomain of your application you may set + `allow_subdomain_redirects` to `True` as if not no external redirects + are allowed. + + .. versionadded:: 0.5 + `use_cookies` is new in this version. Older versions did not provide + builtin cookie support. + + .. versionadded:: 0.14 + The `mimetype` parameter was added. + + .. versionadded:: 0.15 + The ``json`` parameter. + """ + + def __init__( + self, + application, + response_wrapper=None, + use_cookies=True, + allow_subdomain_redirects=False, + ): + self.application = application + self.response_wrapper = response_wrapper + if use_cookies: + self.cookie_jar = _TestCookieJar() + else: + self.cookie_jar = None + self.allow_subdomain_redirects = allow_subdomain_redirects + + def set_cookie( + self, + server_name, + key, + value="", + max_age=None, + expires=None, + path="/", + domain=None, + secure=None, + httponly=False, + charset="utf-8", + ): + """Sets a cookie in the client's cookie jar. The server name + is required and has to match the one that is also passed to + the open call. + """ + assert self.cookie_jar is not None, "cookies disabled" + header = dump_cookie( + key, value, max_age, expires, path, domain, secure, httponly, charset + ) + environ = create_environ(path, base_url="http://" + server_name) + headers = [("Set-Cookie", header)] + self.cookie_jar.extract_wsgi(environ, headers) + + def delete_cookie(self, server_name, key, path="/", domain=None): + """Deletes a cookie in the test client.""" + self.set_cookie( + server_name, key, expires=0, max_age=0, path=path, domain=domain + ) + + def run_wsgi_app(self, environ, buffered=False): + """Runs the wrapped WSGI app with the given environment.""" + if self.cookie_jar is not None: + self.cookie_jar.inject_wsgi(environ) + rv = run_wsgi_app(self.application, environ, buffered=buffered) + if self.cookie_jar is not None: + self.cookie_jar.extract_wsgi(environ, rv[2]) + return rv + + def resolve_redirect(self, response, new_location, environ, buffered=False): + """Perform a new request to the location given by the redirect + response to the previous request. + """ + scheme, netloc, path, qs, anchor = url_parse(new_location) + builder = EnvironBuilder.from_environ(environ, query_string=qs) + + to_name_parts = netloc.split(":", 1)[0].split(".") + from_name_parts = builder.server_name.split(".") + + if to_name_parts != [""]: + # The new location has a host, use it for the base URL. + builder.url_scheme = scheme + builder.host = netloc + else: + # A local redirect with autocorrect_location_header=False + # doesn't have a host, so use the request's host. + to_name_parts = from_name_parts + + # Explain why a redirect to a different server name won't be followed. + if to_name_parts != from_name_parts: + if to_name_parts[-len(from_name_parts) :] == from_name_parts: + if not self.allow_subdomain_redirects: + raise RuntimeError("Following subdomain redirects is not enabled.") + else: + raise RuntimeError("Following external redirects is not supported.") + + path_parts = path.split("/") + root_parts = builder.script_root.split("/") + + if path_parts[: len(root_parts)] == root_parts: + # Strip the script root from the path. + builder.path = path[len(builder.script_root) :] + else: + # The new location is not under the script root, so use the + # whole path and clear the previous root. + builder.path = path + builder.script_root = "" + + status_code = int(response[1].split(None, 1)[0]) + + # Only 307 and 308 preserve all of the original request. + if status_code not in {307, 308}: + # HEAD is preserved, everything else becomes GET. + if builder.method != "HEAD": + builder.method = "GET" + + # Clear the body and the headers that describe it. + builder.input_stream = None + builder.content_type = None + builder.content_length = None + builder.headers.pop("Transfer-Encoding", None) + + # Disable the response wrapper while handling redirects. Not + # thread safe, but the client should not be shared anyway. + old_response_wrapper = self.response_wrapper + self.response_wrapper = None + + try: + return self.open(builder, as_tuple=True, buffered=buffered) + finally: + self.response_wrapper = old_response_wrapper + + def open(self, *args, **kwargs): + """Takes the same arguments as the :class:`EnvironBuilder` class with + some additions: You can provide a :class:`EnvironBuilder` or a WSGI + environment as only argument instead of the :class:`EnvironBuilder` + arguments and two optional keyword arguments (`as_tuple`, `buffered`) + that change the type of the return value or the way the application is + executed. + + .. versionchanged:: 0.5 + If a dict is provided as file in the dict for the `data` parameter + the content type has to be called `content_type` now instead of + `mimetype`. This change was made for consistency with + :class:`werkzeug.FileWrapper`. + + The `follow_redirects` parameter was added to :func:`open`. + + Additional parameters: + + :param as_tuple: Returns a tuple in the form ``(environ, result)`` + :param buffered: Set this to True to buffer the application run. + This will automatically close the application for + you as well. + :param follow_redirects: Set this to True if the `Client` should + follow HTTP redirects. + """ + as_tuple = kwargs.pop("as_tuple", False) + buffered = kwargs.pop("buffered", False) + follow_redirects = kwargs.pop("follow_redirects", False) + environ = None + if not kwargs and len(args) == 1: + if isinstance(args[0], EnvironBuilder): + environ = args[0].get_environ() + elif isinstance(args[0], dict): + environ = args[0] + if environ is None: + builder = EnvironBuilder(*args, **kwargs) + try: + environ = builder.get_environ() + finally: + builder.close() + + response = self.run_wsgi_app(environ.copy(), buffered=buffered) + + # handle redirects + redirect_chain = [] + while 1: + status_code = int(response[1].split(None, 1)[0]) + if ( + status_code not in {301, 302, 303, 305, 307, 308} + or not follow_redirects + ): + break + + # Exhaust intermediate response bodies to ensure middleware + # that returns an iterator runs any cleanup code. + if not buffered: + for _ in response[0]: + pass + + new_location = response[2]["location"] + new_redirect_entry = (new_location, status_code) + if new_redirect_entry in redirect_chain: + raise ClientRedirectError("loop detected") + redirect_chain.append(new_redirect_entry) + environ, response = self.resolve_redirect( + response, new_location, environ, buffered=buffered + ) + + if self.response_wrapper is not None: + response = self.response_wrapper(*response) + if as_tuple: + return environ, response + return response + + def get(self, *args, **kw): + """Like open but method is enforced to GET.""" + kw["method"] = "GET" + return self.open(*args, **kw) + + def patch(self, *args, **kw): + """Like open but method is enforced to PATCH.""" + kw["method"] = "PATCH" + return self.open(*args, **kw) + + def post(self, *args, **kw): + """Like open but method is enforced to POST.""" + kw["method"] = "POST" + return self.open(*args, **kw) + + def head(self, *args, **kw): + """Like open but method is enforced to HEAD.""" + kw["method"] = "HEAD" + return self.open(*args, **kw) + + def put(self, *args, **kw): + """Like open but method is enforced to PUT.""" + kw["method"] = "PUT" + return self.open(*args, **kw) + + def delete(self, *args, **kw): + """Like open but method is enforced to DELETE.""" + kw["method"] = "DELETE" + return self.open(*args, **kw) + + def options(self, *args, **kw): + """Like open but method is enforced to OPTIONS.""" + kw["method"] = "OPTIONS" + return self.open(*args, **kw) + + def trace(self, *args, **kw): + """Like open but method is enforced to TRACE.""" + kw["method"] = "TRACE" + return self.open(*args, **kw) + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, self.application) + + +def create_environ(*args, **kwargs): + """Create a new WSGI environ dict based on the values passed. The first + parameter should be the path of the request which defaults to '/'. The + second one can either be an absolute path (in that case the host is + localhost:80) or a full path to the request with scheme, netloc port and + the path to the script. + + This accepts the same arguments as the :class:`EnvironBuilder` + constructor. + + .. versionchanged:: 0.5 + This function is now a thin wrapper over :class:`EnvironBuilder` which + was added in 0.5. The `headers`, `environ_base`, `environ_overrides` + and `charset` parameters were added. + """ + builder = EnvironBuilder(*args, **kwargs) + try: + return builder.get_environ() + finally: + builder.close() + + +def run_wsgi_app(app, environ, buffered=False): + """Return a tuple in the form (app_iter, status, headers) of the + application output. This works best if you pass it an application that + returns an iterator all the time. + + Sometimes applications may use the `write()` callable returned + by the `start_response` function. This tries to resolve such edge + cases automatically. But if you don't get the expected output you + should set `buffered` to `True` which enforces buffering. + + If passed an invalid WSGI application the behavior of this function is + undefined. Never pass non-conforming WSGI applications to this function. + + :param app: the application to execute. + :param buffered: set to `True` to enforce buffering. + :return: tuple in the form ``(app_iter, status, headers)`` + """ + environ = _get_environ(environ) + response = [] + buffer = [] + + def start_response(status, headers, exc_info=None): + if exc_info is not None: + reraise(*exc_info) + response[:] = [status, headers] + return buffer.append + + app_rv = app(environ, start_response) + close_func = getattr(app_rv, "close", None) + app_iter = iter(app_rv) + + # when buffering we emit the close call early and convert the + # application iterator into a regular list + if buffered: + try: + app_iter = list(app_iter) + finally: + if close_func is not None: + close_func() + + # otherwise we iterate the application iter until we have a response, chain + # the already received data with the already collected data and wrap it in + # a new `ClosingIterator` if we need to restore a `close` callable from the + # original return value. + else: + for item in app_iter: + buffer.append(item) + if response: + break + if buffer: + app_iter = chain(buffer, app_iter) + if close_func is not None and app_iter is not app_rv: + app_iter = ClosingIterator(app_iter, close_func) + + return app_iter, response[0], Headers(response[1]) diff --git a/venv/lib/python3.7/site-packages/werkzeug/testapp.py b/venv/lib/python3.7/site-packages/werkzeug/testapp.py new file mode 100644 index 0000000..8ea23be --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/testapp.py @@ -0,0 +1,241 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.testapp + ~~~~~~~~~~~~~~~~ + + Provide a small test application that can be used to test a WSGI server + and check it for WSGI compliance. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import base64 +import os +import sys +from textwrap import wrap + +import werkzeug +from .utils import escape +from .wrappers import BaseRequest as Request +from .wrappers import BaseResponse as Response + +logo = Response( + base64.b64decode( + """ +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 +=""" + ), + mimetype="image/png", +) + + +TEMPLATE = u"""\ + +WSGI Information + +
    + +

    WSGI Information

    +

    + This page displays all available information about the WSGI server and + the underlying Python interpreter. +

    Python Interpreter

    + + + + + + +
    Python Version + %(python_version)s +
    Platform + %(platform)s [%(os)s] +
    API Version + %(api_version)s +
    Byteorder + %(byteorder)s +
    Werkzeug Version + %(werkzeug_version)s +
    +

    WSGI Environment

    + %(wsgi_env)s
    +

    Installed Eggs

    +

    + The following python packages were installed on the system as + Python eggs: +

      %(python_eggs)s
    +

    System Path

    +

    + The following paths are the current contents of the load path. The + following entries are looked up for Python packages. Note that not + all items in this path are folders. Gray and underlined items are + entries pointing to invalid resources or used by custom import hooks + such as the zip importer. +

    + Items with a bright background were expanded for display from a relative + path. If you encounter such paths in the output you might want to check + your setup as relative paths are usually problematic in multithreaded + environments. +

      %(sys_path)s
    +
    +""" + + +def iter_sys_path(): + if os.name == "posix": + + def strip(x): + prefix = os.path.expanduser("~") + if x.startswith(prefix): + x = "~" + x[len(prefix) :] + return x + + else: + + def strip(x): + return x + + cwd = os.path.abspath(os.getcwd()) + for item in sys.path: + path = os.path.join(cwd, item or os.path.curdir) + yield strip(os.path.normpath(path)), not os.path.isdir(path), path != item + + +def render_testapp(req): + try: + import pkg_resources + except ImportError: + eggs = () + else: + eggs = sorted(pkg_resources.working_set, key=lambda x: x.project_name.lower()) + python_eggs = [] + for egg in eggs: + try: + version = egg.version + except (ValueError, AttributeError): + version = "unknown" + python_eggs.append( + "
  • %s [%s]" % (escape(egg.project_name), escape(version)) + ) + + wsgi_env = [] + sorted_environ = sorted(req.environ.items(), key=lambda x: repr(x[0]).lower()) + for key, value in sorted_environ: + wsgi_env.append( + "%s%s" + % (escape(str(key)), " ".join(wrap(escape(repr(value))))) + ) + + sys_path = [] + for item, virtual, expanded in iter_sys_path(): + class_ = [] + if virtual: + class_.append("virtual") + if expanded: + class_.append("exp") + sys_path.append( + "%s" + % (' class="%s"' % " ".join(class_) if class_ else "", escape(item)) + ) + + return ( + TEMPLATE + % { + "python_version": "
    ".join(escape(sys.version).splitlines()), + "platform": escape(sys.platform), + "os": escape(os.name), + "api_version": sys.api_version, + "byteorder": sys.byteorder, + "werkzeug_version": werkzeug.__version__, + "python_eggs": "\n".join(python_eggs), + "wsgi_env": "\n".join(wsgi_env), + "sys_path": "\n".join(sys_path), + } + ).encode("utf-8") + + +def test_app(environ, start_response): + """Simple test application that dumps the environment. You can use + it to check if Werkzeug is working properly: + + .. sourcecode:: pycon + + >>> from werkzeug.serving import run_simple + >>> from werkzeug.testapp import test_app + >>> run_simple('localhost', 3000, test_app) + * Running on http://localhost:3000/ + + The application displays important information from the WSGI environment, + the Python interpreter and the installed libraries. + """ + req = Request(environ, populate_request=False) + if req.args.get("resource") == "logo": + response = logo + else: + response = Response(render_testapp(req), mimetype="text/html") + return response(environ, start_response) + + +if __name__ == "__main__": + from .serving import run_simple + + run_simple("localhost", 5000, test_app, use_reloader=True) diff --git a/venv/lib/python3.7/site-packages/werkzeug/urls.py b/venv/lib/python3.7/site-packages/werkzeug/urls.py new file mode 100644 index 0000000..38e9e5a --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/urls.py @@ -0,0 +1,1134 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.urls + ~~~~~~~~~~~~~ + + ``werkzeug.urls`` used to provide several wrapper functions for Python 2 + urlparse, whose main purpose were to work around the behavior of the Py2 + stdlib and its lack of unicode support. While this was already a somewhat + inconvenient situation, it got even more complicated because Python 3's + ``urllib.parse`` actually does handle unicode properly. In other words, + this module would wrap two libraries with completely different behavior. So + now this module contains a 2-and-3-compatible backport of Python 3's + ``urllib.parse``, which is mostly API-compatible. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import codecs +import os +import re +from collections import namedtuple + +from ._compat import fix_tuple_repr +from ._compat import implements_to_string +from ._compat import make_literal_wrapper +from ._compat import normalize_string_tuple +from ._compat import PY2 +from ._compat import text_type +from ._compat import to_native +from ._compat import to_unicode +from ._compat import try_coerce_native +from ._internal import _decode_idna +from ._internal import _encode_idna +from .datastructures import iter_multi_items +from .datastructures import MultiDict + +# A regular expression for what a valid schema looks like +_scheme_re = re.compile(r"^[a-zA-Z0-9+-.]+$") + +# Characters that are safe in any part of an URL. +_always_safe = frozenset( + bytearray( + b"abcdefghijklmnopqrstuvwxyz" + b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + b"0123456789" + b"-._~" + ) +) + +_hexdigits = "0123456789ABCDEFabcdef" +_hextobyte = dict( + ((a + b).encode(), int(a + b, 16)) for a in _hexdigits for b in _hexdigits +) +_bytetohex = [("%%%02X" % char).encode("ascii") for char in range(256)] + + +_URLTuple = fix_tuple_repr( + namedtuple("_URLTuple", ["scheme", "netloc", "path", "query", "fragment"]) +) + + +class BaseURL(_URLTuple): + """Superclass of :py:class:`URL` and :py:class:`BytesURL`.""" + + __slots__ = () + + def replace(self, **kwargs): + """Return an URL with the same values, except for those parameters + given new values by whichever keyword arguments are specified.""" + return self._replace(**kwargs) + + @property + def host(self): + """The host part of the URL if available, otherwise `None`. The + host is either the hostname or the IP address mentioned in the + URL. It will not contain the port. + """ + return self._split_host()[0] + + @property + def ascii_host(self): + """Works exactly like :attr:`host` but will return a result that + is restricted to ASCII. If it finds a netloc that is not ASCII + it will attempt to idna decode it. This is useful for socket + operations when the URL might include internationalized characters. + """ + rv = self.host + if rv is not None and isinstance(rv, text_type): + try: + rv = _encode_idna(rv) + except UnicodeError: + rv = rv.encode("ascii", "ignore") + return to_native(rv, "ascii", "ignore") + + @property + def port(self): + """The port in the URL as an integer if it was present, `None` + otherwise. This does not fill in default ports. + """ + try: + rv = int(to_native(self._split_host()[1])) + if 0 <= rv <= 65535: + return rv + except (ValueError, TypeError): + pass + + @property + def auth(self): + """The authentication part in the URL if available, `None` + otherwise. + """ + return self._split_netloc()[0] + + @property + def username(self): + """The username if it was part of the URL, `None` otherwise. + This undergoes URL decoding and will always be a unicode string. + """ + rv = self._split_auth()[0] + if rv is not None: + return _url_unquote_legacy(rv) + + @property + def raw_username(self): + """The username if it was part of the URL, `None` otherwise. + Unlike :attr:`username` this one is not being decoded. + """ + return self._split_auth()[0] + + @property + def password(self): + """The password if it was part of the URL, `None` otherwise. + This undergoes URL decoding and will always be a unicode string. + """ + rv = self._split_auth()[1] + if rv is not None: + return _url_unquote_legacy(rv) + + @property + def raw_password(self): + """The password if it was part of the URL, `None` otherwise. + Unlike :attr:`password` this one is not being decoded. + """ + return self._split_auth()[1] + + def decode_query(self, *args, **kwargs): + """Decodes the query part of the URL. Ths is a shortcut for + calling :func:`url_decode` on the query argument. The arguments and + keyword arguments are forwarded to :func:`url_decode` unchanged. + """ + return url_decode(self.query, *args, **kwargs) + + def join(self, *args, **kwargs): + """Joins this URL with another one. This is just a convenience + function for calling into :meth:`url_join` and then parsing the + return value again. + """ + return url_parse(url_join(self, *args, **kwargs)) + + def to_url(self): + """Returns a URL string or bytes depending on the type of the + information stored. This is just a convenience function + for calling :meth:`url_unparse` for this URL. + """ + return url_unparse(self) + + def decode_netloc(self): + """Decodes the netloc part into a string.""" + rv = _decode_idna(self.host or "") + + if ":" in rv: + rv = "[%s]" % rv + port = self.port + if port is not None: + rv = "%s:%d" % (rv, port) + auth = ":".join( + filter( + None, + [ + _url_unquote_legacy(self.raw_username or "", "/:%@"), + _url_unquote_legacy(self.raw_password or "", "/:%@"), + ], + ) + ) + if auth: + rv = "%s@%s" % (auth, rv) + return rv + + def to_uri_tuple(self): + """Returns a :class:`BytesURL` tuple that holds a URI. This will + encode all the information in the URL properly to ASCII using the + rules a web browser would follow. + + It's usually more interesting to directly call :meth:`iri_to_uri` which + will return a string. + """ + return url_parse(iri_to_uri(self).encode("ascii")) + + def to_iri_tuple(self): + """Returns a :class:`URL` tuple that holds a IRI. This will try + to decode as much information as possible in the URL without + losing information similar to how a web browser does it for the + URL bar. + + It's usually more interesting to directly call :meth:`uri_to_iri` which + will return a string. + """ + return url_parse(uri_to_iri(self)) + + def get_file_location(self, pathformat=None): + """Returns a tuple with the location of the file in the form + ``(server, location)``. If the netloc is empty in the URL or + points to localhost, it's represented as ``None``. + + The `pathformat` by default is autodetection but needs to be set + when working with URLs of a specific system. The supported values + are ``'windows'`` when working with Windows or DOS paths and + ``'posix'`` when working with posix paths. + + If the URL does not point to a local file, the server and location + are both represented as ``None``. + + :param pathformat: The expected format of the path component. + Currently ``'windows'`` and ``'posix'`` are + supported. Defaults to ``None`` which is + autodetect. + """ + if self.scheme != "file": + return None, None + + path = url_unquote(self.path) + host = self.netloc or None + + if pathformat is None: + if os.name == "nt": + pathformat = "windows" + else: + pathformat = "posix" + + if pathformat == "windows": + if path[:1] == "/" and path[1:2].isalpha() and path[2:3] in "|:": + path = path[1:2] + ":" + path[3:] + windows_share = path[:3] in ("\\" * 3, "/" * 3) + import ntpath + + path = ntpath.normpath(path) + # Windows shared drives are represented as ``\\host\\directory``. + # That results in a URL like ``file://///host/directory``, and a + # path like ``///host/directory``. We need to special-case this + # because the path contains the hostname. + if windows_share and host is None: + parts = path.lstrip("\\").split("\\", 1) + if len(parts) == 2: + host, path = parts + else: + host = parts[0] + path = "" + elif pathformat == "posix": + import posixpath + + path = posixpath.normpath(path) + else: + raise TypeError("Invalid path format %s" % repr(pathformat)) + + if host in ("127.0.0.1", "::1", "localhost"): + host = None + + return host, path + + def _split_netloc(self): + if self._at in self.netloc: + return self.netloc.split(self._at, 1) + return None, self.netloc + + def _split_auth(self): + auth = self._split_netloc()[0] + if not auth: + return None, None + if self._colon not in auth: + return auth, None + return auth.split(self._colon, 1) + + def _split_host(self): + rv = self._split_netloc()[1] + if not rv: + return None, None + + if not rv.startswith(self._lbracket): + if self._colon in rv: + return rv.split(self._colon, 1) + return rv, None + + idx = rv.find(self._rbracket) + if idx < 0: + return rv, None + + host = rv[1:idx] + rest = rv[idx + 1 :] + if rest.startswith(self._colon): + return host, rest[1:] + return host, None + + +@implements_to_string +class URL(BaseURL): + """Represents a parsed URL. This behaves like a regular tuple but + also has some extra attributes that give further insight into the + URL. + """ + + __slots__ = () + _at = "@" + _colon = ":" + _lbracket = "[" + _rbracket = "]" + + def __str__(self): + return self.to_url() + + def encode_netloc(self): + """Encodes the netloc part to an ASCII safe URL as bytes.""" + rv = self.ascii_host or "" + if ":" in rv: + rv = "[%s]" % rv + port = self.port + if port is not None: + rv = "%s:%d" % (rv, port) + auth = ":".join( + filter( + None, + [ + url_quote(self.raw_username or "", "utf-8", "strict", "/:%"), + url_quote(self.raw_password or "", "utf-8", "strict", "/:%"), + ], + ) + ) + if auth: + rv = "%s@%s" % (auth, rv) + return to_native(rv) + + def encode(self, charset="utf-8", errors="replace"): + """Encodes the URL to a tuple made out of bytes. The charset is + only being used for the path, query and fragment. + """ + return BytesURL( + self.scheme.encode("ascii"), + self.encode_netloc(), + self.path.encode(charset, errors), + self.query.encode(charset, errors), + self.fragment.encode(charset, errors), + ) + + +class BytesURL(BaseURL): + """Represents a parsed URL in bytes.""" + + __slots__ = () + _at = b"@" + _colon = b":" + _lbracket = b"[" + _rbracket = b"]" + + def __str__(self): + return self.to_url().decode("utf-8", "replace") + + def encode_netloc(self): + """Returns the netloc unchanged as bytes.""" + return self.netloc + + def decode(self, charset="utf-8", errors="replace"): + """Decodes the URL to a tuple made out of strings. The charset is + only being used for the path, query and fragment. + """ + return URL( + self.scheme.decode("ascii"), + self.decode_netloc(), + self.path.decode(charset, errors), + self.query.decode(charset, errors), + self.fragment.decode(charset, errors), + ) + + +_unquote_maps = {frozenset(): _hextobyte} + + +def _unquote_to_bytes(string, unsafe=""): + if isinstance(string, text_type): + string = string.encode("utf-8") + + if isinstance(unsafe, text_type): + unsafe = unsafe.encode("utf-8") + + unsafe = frozenset(bytearray(unsafe)) + groups = iter(string.split(b"%")) + result = bytearray(next(groups, b"")) + + try: + hex_to_byte = _unquote_maps[unsafe] + except KeyError: + hex_to_byte = _unquote_maps[unsafe] = { + h: b for h, b in _hextobyte.items() if b not in unsafe + } + + for group in groups: + code = group[:2] + + if code in hex_to_byte: + result.append(hex_to_byte[code]) + result.extend(group[2:]) + else: + result.append(37) # % + result.extend(group) + + return bytes(result) + + +def _url_encode_impl(obj, charset, encode_keys, sort, key): + iterable = iter_multi_items(obj) + if sort: + iterable = sorted(iterable, key=key) + for key, value in iterable: + if value is None: + continue + if not isinstance(key, bytes): + key = text_type(key).encode(charset) + if not isinstance(value, bytes): + value = text_type(value).encode(charset) + yield _fast_url_quote_plus(key) + "=" + _fast_url_quote_plus(value) + + +def _url_unquote_legacy(value, unsafe=""): + try: + return url_unquote(value, charset="utf-8", errors="strict", unsafe=unsafe) + except UnicodeError: + return url_unquote(value, charset="latin1", unsafe=unsafe) + + +def url_parse(url, scheme=None, allow_fragments=True): + """Parses a URL from a string into a :class:`URL` tuple. If the URL + is lacking a scheme it can be provided as second argument. Otherwise, + it is ignored. Optionally fragments can be stripped from the URL + by setting `allow_fragments` to `False`. + + The inverse of this function is :func:`url_unparse`. + + :param url: the URL to parse. + :param scheme: the default schema to use if the URL is schemaless. + :param allow_fragments: if set to `False` a fragment will be removed + from the URL. + """ + s = make_literal_wrapper(url) + is_text_based = isinstance(url, text_type) + + if scheme is None: + scheme = s("") + netloc = query = fragment = s("") + i = url.find(s(":")) + if i > 0 and _scheme_re.match(to_native(url[:i], errors="replace")): + # make sure "iri" is not actually a port number (in which case + # "scheme" is really part of the path) + rest = url[i + 1 :] + if not rest or any(c not in s("0123456789") for c in rest): + # not a port number + scheme, url = url[:i].lower(), rest + + if url[:2] == s("//"): + delim = len(url) + for c in s("/?#"): + wdelim = url.find(c, 2) + if wdelim >= 0: + delim = min(delim, wdelim) + netloc, url = url[2:delim], url[delim:] + if (s("[") in netloc and s("]") not in netloc) or ( + s("]") in netloc and s("[") not in netloc + ): + raise ValueError("Invalid IPv6 URL") + + if allow_fragments and s("#") in url: + url, fragment = url.split(s("#"), 1) + if s("?") in url: + url, query = url.split(s("?"), 1) + + result_type = URL if is_text_based else BytesURL + return result_type(scheme, netloc, url, query, fragment) + + +def _make_fast_url_quote(charset="utf-8", errors="strict", safe="/:", unsafe=""): + """Precompile the translation table for a URL encoding function. + + Unlike :func:`url_quote`, the generated function only takes the + string to quote. + + :param charset: The charset to encode the result with. + :param errors: How to handle encoding errors. + :param safe: An optional sequence of safe characters to never encode. + :param unsafe: An optional sequence of unsafe characters to always encode. + """ + if isinstance(safe, text_type): + safe = safe.encode(charset, errors) + + if isinstance(unsafe, text_type): + unsafe = unsafe.encode(charset, errors) + + safe = (frozenset(bytearray(safe)) | _always_safe) - frozenset(bytearray(unsafe)) + table = [chr(c) if c in safe else "%%%02X" % c for c in range(256)] + + if not PY2: + + def quote(string): + return "".join([table[c] for c in string]) + + else: + + def quote(string): + return "".join([table[c] for c in bytearray(string)]) + + return quote + + +_fast_url_quote = _make_fast_url_quote() +_fast_quote_plus = _make_fast_url_quote(safe=" ", unsafe="+") + + +def _fast_url_quote_plus(string): + return _fast_quote_plus(string).replace(" ", "+") + + +def url_quote(string, charset="utf-8", errors="strict", safe="/:", unsafe=""): + """URL encode a single string with a given encoding. + + :param s: the string to quote. + :param charset: the charset to be used. + :param safe: an optional sequence of safe characters. + :param unsafe: an optional sequence of unsafe characters. + + .. versionadded:: 0.9.2 + The `unsafe` parameter was added. + """ + if not isinstance(string, (text_type, bytes, bytearray)): + string = text_type(string) + if isinstance(string, text_type): + string = string.encode(charset, errors) + if isinstance(safe, text_type): + safe = safe.encode(charset, errors) + if isinstance(unsafe, text_type): + unsafe = unsafe.encode(charset, errors) + safe = (frozenset(bytearray(safe)) | _always_safe) - frozenset(bytearray(unsafe)) + rv = bytearray() + for char in bytearray(string): + if char in safe: + rv.append(char) + else: + rv.extend(_bytetohex[char]) + return to_native(bytes(rv)) + + +def url_quote_plus(string, charset="utf-8", errors="strict", safe=""): + """URL encode a single string with the given encoding and convert + whitespace to "+". + + :param s: The string to quote. + :param charset: The charset to be used. + :param safe: An optional sequence of safe characters. + """ + return url_quote(string, charset, errors, safe + " ", "+").replace(" ", "+") + + +def url_unparse(components): + """The reverse operation to :meth:`url_parse`. This accepts arbitrary + as well as :class:`URL` tuples and returns a URL as a string. + + :param components: the parsed URL as tuple which should be converted + into a URL string. + """ + scheme, netloc, path, query, fragment = normalize_string_tuple(components) + s = make_literal_wrapper(scheme) + url = s("") + + # We generally treat file:///x and file:/x the same which is also + # what browsers seem to do. This also allows us to ignore a schema + # register for netloc utilization or having to differenciate between + # empty and missing netloc. + if netloc or (scheme and path.startswith(s("/"))): + if path and path[:1] != s("/"): + path = s("/") + path + url = s("//") + (netloc or s("")) + path + elif path: + url += path + if scheme: + url = scheme + s(":") + url + if query: + url = url + s("?") + query + if fragment: + url = url + s("#") + fragment + return url + + +def url_unquote(string, charset="utf-8", errors="replace", unsafe=""): + """URL decode a single string with a given encoding. If the charset + is set to `None` no unicode decoding is performed and raw bytes + are returned. + + :param s: the string to unquote. + :param charset: the charset of the query string. If set to `None` + no unicode decoding will take place. + :param errors: the error handling for the charset decoding. + """ + rv = _unquote_to_bytes(string, unsafe) + if charset is not None: + rv = rv.decode(charset, errors) + return rv + + +def url_unquote_plus(s, charset="utf-8", errors="replace"): + """URL decode a single string with the given `charset` and decode "+" to + whitespace. + + Per default encoding errors are ignored. If you want a different behavior + you can set `errors` to ``'replace'`` or ``'strict'``. In strict mode a + :exc:`HTTPUnicodeError` is raised. + + :param s: The string to unquote. + :param charset: the charset of the query string. If set to `None` + no unicode decoding will take place. + :param errors: The error handling for the `charset` decoding. + """ + if isinstance(s, text_type): + s = s.replace(u"+", u" ") + else: + s = s.replace(b"+", b" ") + return url_unquote(s, charset, errors) + + +def url_fix(s, charset="utf-8"): + r"""Sometimes you get an URL by a user that just isn't a real URL because + it contains unsafe characters like ' ' and so on. This function can fix + some of the problems in a similar way browsers handle data entered by the + user: + + >>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffskl\xe4rung)') + 'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)' + + :param s: the string with the URL to fix. + :param charset: The target charset for the URL if the url was given as + unicode string. + """ + # First step is to switch to unicode processing and to convert + # backslashes (which are invalid in URLs anyways) to slashes. This is + # consistent with what Chrome does. + s = to_unicode(s, charset, "replace").replace("\\", "/") + + # For the specific case that we look like a malformed windows URL + # we want to fix this up manually: + if s.startswith("file://") and s[7:8].isalpha() and s[8:10] in (":/", "|/"): + s = "file:///" + s[7:] + + url = url_parse(s) + path = url_quote(url.path, charset, safe="/%+$!*'(),") + qs = url_quote_plus(url.query, charset, safe=":&%=+$!*'(),") + anchor = url_quote_plus(url.fragment, charset, safe=":&%=+$!*'(),") + return to_native(url_unparse((url.scheme, url.encode_netloc(), path, qs, anchor))) + + +# not-unreserved characters remain quoted when unquoting to IRI +_to_iri_unsafe = "".join([chr(c) for c in range(128) if c not in _always_safe]) + + +def _codec_error_url_quote(e): + """Used in :func:`uri_to_iri` after unquoting to re-quote any + invalid bytes. + """ + out = _fast_url_quote(e.object[e.start : e.end]) + + if PY2: + out = out.decode("utf-8") + + return out, e.end + + +codecs.register_error("werkzeug.url_quote", _codec_error_url_quote) + + +def uri_to_iri(uri, charset="utf-8", errors="werkzeug.url_quote"): + """Convert a URI to an IRI. All valid UTF-8 characters are unquoted, + leaving all reserved and invalid characters quoted. If the URL has + a domain, it is decoded from Punycode. + + >>> uri_to_iri("http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF") + 'http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF' + + :param uri: The URI to convert. + :param charset: The encoding to encode unquoted bytes with. + :param errors: Error handler to use during ``bytes.encode``. By + default, invalid bytes are left quoted. + + .. versionchanged:: 0.15 + All reserved and invalid characters remain quoted. Previously, + only some reserved characters were preserved, and invalid bytes + were replaced instead of left quoted. + + .. versionadded:: 0.6 + """ + if isinstance(uri, tuple): + uri = url_unparse(uri) + + uri = url_parse(to_unicode(uri, charset)) + path = url_unquote(uri.path, charset, errors, _to_iri_unsafe) + query = url_unquote(uri.query, charset, errors, _to_iri_unsafe) + fragment = url_unquote(uri.fragment, charset, errors, _to_iri_unsafe) + return url_unparse((uri.scheme, uri.decode_netloc(), path, query, fragment)) + + +# reserved characters remain unquoted when quoting to URI +_to_uri_safe = ":/?#[]@!$&'()*+,;=%" + + +def iri_to_uri(iri, charset="utf-8", errors="strict", safe_conversion=False): + """Convert an IRI to a URI. All non-ASCII and unsafe characters are + quoted. If the URL has a domain, it is encoded to Punycode. + + >>> iri_to_uri('http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF') + 'http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF' + + :param iri: The IRI to convert. + :param charset: The encoding of the IRI. + :param errors: Error handler to use during ``bytes.encode``. + :param safe_conversion: Return the URL unchanged if it only contains + ASCII characters and no whitespace. See the explanation below. + + There is a general problem with IRI conversion with some protocols + that are in violation of the URI specification. Consider the + following two IRIs:: + + magnet:?xt=uri:whatever + itms-services://?action=download-manifest + + After parsing, we don't know if the scheme requires the ``//``, + which is dropped if empty, but conveys different meanings in the + final URL if it's present or not. In this case, you can use + ``safe_conversion``, which will return the URL unchanged if it only + contains ASCII characters and no whitespace. This can result in a + URI with unquoted characters if it was not already quoted correctly, + but preserves the URL's semantics. Werkzeug uses this for the + ``Location`` header for redirects. + + .. versionchanged:: 0.15 + All reserved characters remain unquoted. Previously, only some + reserved characters were left unquoted. + + .. versionchanged:: 0.9.6 + The ``safe_conversion`` parameter was added. + + .. versionadded:: 0.6 + """ + if isinstance(iri, tuple): + iri = url_unparse(iri) + + if safe_conversion: + # If we're not sure if it's safe to convert the URL, and it only + # contains ASCII characters, return it unconverted. + try: + native_iri = to_native(iri) + ascii_iri = native_iri.encode("ascii") + + # Only return if it doesn't have whitespace. (Why?) + if len(ascii_iri.split()) == 1: + return native_iri + except UnicodeError: + pass + + iri = url_parse(to_unicode(iri, charset, errors)) + path = url_quote(iri.path, charset, errors, _to_uri_safe) + query = url_quote(iri.query, charset, errors, _to_uri_safe) + fragment = url_quote(iri.fragment, charset, errors, _to_uri_safe) + return to_native( + url_unparse((iri.scheme, iri.encode_netloc(), path, query, fragment)) + ) + + +def url_decode( + s, + charset="utf-8", + decode_keys=False, + include_empty=True, + errors="replace", + separator="&", + cls=None, +): + """ + Parse a querystring and return it as :class:`MultiDict`. There is a + difference in key decoding on different Python versions. On Python 3 + keys will always be fully decoded whereas on Python 2, keys will + remain bytestrings if they fit into ASCII. On 2.x keys can be forced + to be unicode by setting `decode_keys` to `True`. + + If the charset is set to `None` no unicode decoding will happen and + raw bytes will be returned. + + Per default a missing value for a key will default to an empty key. If + you don't want that behavior you can set `include_empty` to `False`. + + Per default encoding errors are ignored. If you want a different behavior + you can set `errors` to ``'replace'`` or ``'strict'``. In strict mode a + `HTTPUnicodeError` is raised. + + .. versionchanged:: 0.5 + In previous versions ";" and "&" could be used for url decoding. + This changed in 0.5 where only "&" is supported. If you want to + use ";" instead a different `separator` can be provided. + + The `cls` parameter was added. + + :param s: a string with the query string to decode. + :param charset: the charset of the query string. If set to `None` + no unicode decoding will take place. + :param decode_keys: Used on Python 2.x to control whether keys should + be forced to be unicode objects. If set to `True` + then keys will be unicode in all cases. Otherwise, + they remain `str` if they fit into ASCII. + :param include_empty: Set to `False` if you don't want empty values to + appear in the dict. + :param errors: the decoding error behavior. + :param separator: the pair separator to be used, defaults to ``&`` + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + """ + if cls is None: + cls = MultiDict + if isinstance(s, text_type) and not isinstance(separator, text_type): + separator = separator.decode(charset or "ascii") + elif isinstance(s, bytes) and not isinstance(separator, bytes): + separator = separator.encode(charset or "ascii") + return cls( + _url_decode_impl( + s.split(separator), charset, decode_keys, include_empty, errors + ) + ) + + +def url_decode_stream( + stream, + charset="utf-8", + decode_keys=False, + include_empty=True, + errors="replace", + separator="&", + cls=None, + limit=None, + return_iterator=False, +): + """Works like :func:`url_decode` but decodes a stream. The behavior + of stream and limit follows functions like + :func:`~werkzeug.wsgi.make_line_iter`. The generator of pairs is + directly fed to the `cls` so you can consume the data while it's + parsed. + + .. versionadded:: 0.8 + + :param stream: a stream with the encoded querystring + :param charset: the charset of the query string. If set to `None` + no unicode decoding will take place. + :param decode_keys: Used on Python 2.x to control whether keys should + be forced to be unicode objects. If set to `True`, + keys will be unicode in all cases. Otherwise, they + remain `str` if they fit into ASCII. + :param include_empty: Set to `False` if you don't want empty values to + appear in the dict. + :param errors: the decoding error behavior. + :param separator: the pair separator to be used, defaults to ``&`` + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param limit: the content length of the URL data. Not necessary if + a limited stream is provided. + :param return_iterator: if set to `True` the `cls` argument is ignored + and an iterator over all decoded pairs is + returned + """ + from .wsgi import make_chunk_iter + + pair_iter = make_chunk_iter(stream, separator, limit) + decoder = _url_decode_impl(pair_iter, charset, decode_keys, include_empty, errors) + + if return_iterator: + return decoder + + if cls is None: + cls = MultiDict + + return cls(decoder) + + +def _url_decode_impl(pair_iter, charset, decode_keys, include_empty, errors): + for pair in pair_iter: + if not pair: + continue + s = make_literal_wrapper(pair) + equal = s("=") + if equal in pair: + key, value = pair.split(equal, 1) + else: + if not include_empty: + continue + key = pair + value = s("") + key = url_unquote_plus(key, charset, errors) + if charset is not None and PY2 and not decode_keys: + key = try_coerce_native(key) + yield key, url_unquote_plus(value, charset, errors) + + +def url_encode( + obj, charset="utf-8", encode_keys=False, sort=False, key=None, separator=b"&" +): + """URL encode a dict/`MultiDict`. If a value is `None` it will not appear + in the result string. Per default only values are encoded into the target + charset strings. If `encode_keys` is set to ``True`` unicode keys are + supported too. + + If `sort` is set to `True` the items are sorted by `key` or the default + sorting algorithm. + + .. versionadded:: 0.5 + `sort`, `key`, and `separator` were added. + + :param obj: the object to encode into a query string. + :param charset: the charset of the query string. + :param encode_keys: set to `True` if you have unicode keys. (Ignored on + Python 3.x) + :param sort: set to `True` if you want parameters to be sorted by `key`. + :param separator: the separator to be used for the pairs. + :param key: an optional function to be used for sorting. For more details + check out the :func:`sorted` documentation. + """ + separator = to_native(separator, "ascii") + return separator.join(_url_encode_impl(obj, charset, encode_keys, sort, key)) + + +def url_encode_stream( + obj, + stream=None, + charset="utf-8", + encode_keys=False, + sort=False, + key=None, + separator=b"&", +): + """Like :meth:`url_encode` but writes the results to a stream + object. If the stream is `None` a generator over all encoded + pairs is returned. + + .. versionadded:: 0.8 + + :param obj: the object to encode into a query string. + :param stream: a stream to write the encoded object into or `None` if + an iterator over the encoded pairs should be returned. In + that case the separator argument is ignored. + :param charset: the charset of the query string. + :param encode_keys: set to `True` if you have unicode keys. (Ignored on + Python 3.x) + :param sort: set to `True` if you want parameters to be sorted by `key`. + :param separator: the separator to be used for the pairs. + :param key: an optional function to be used for sorting. For more details + check out the :func:`sorted` documentation. + """ + separator = to_native(separator, "ascii") + gen = _url_encode_impl(obj, charset, encode_keys, sort, key) + if stream is None: + return gen + for idx, chunk in enumerate(gen): + if idx: + stream.write(separator) + stream.write(chunk) + + +def url_join(base, url, allow_fragments=True): + """Join a base URL and a possibly relative URL to form an absolute + interpretation of the latter. + + :param base: the base URL for the join operation. + :param url: the URL to join. + :param allow_fragments: indicates whether fragments should be allowed. + """ + if isinstance(base, tuple): + base = url_unparse(base) + if isinstance(url, tuple): + url = url_unparse(url) + + base, url = normalize_string_tuple((base, url)) + s = make_literal_wrapper(base) + + if not base: + return url + if not url: + return base + + bscheme, bnetloc, bpath, bquery, bfragment = url_parse( + base, allow_fragments=allow_fragments + ) + scheme, netloc, path, query, fragment = url_parse(url, bscheme, allow_fragments) + if scheme != bscheme: + return url + if netloc: + return url_unparse((scheme, netloc, path, query, fragment)) + netloc = bnetloc + + if path[:1] == s("/"): + segments = path.split(s("/")) + elif not path: + segments = bpath.split(s("/")) + if not query: + query = bquery + else: + segments = bpath.split(s("/"))[:-1] + path.split(s("/")) + + # If the rightmost part is "./" we want to keep the slash but + # remove the dot. + if segments[-1] == s("."): + segments[-1] = s("") + + # Resolve ".." and "." + segments = [segment for segment in segments if segment != s(".")] + while 1: + i = 1 + n = len(segments) - 1 + while i < n: + if segments[i] == s("..") and segments[i - 1] not in (s(""), s("..")): + del segments[i - 1 : i + 1] + break + i += 1 + else: + break + + # Remove trailing ".." if the URL is absolute + unwanted_marker = [s(""), s("..")] + while segments[:2] == unwanted_marker: + del segments[1] + + path = s("/").join(segments) + return url_unparse((scheme, netloc, path, query, fragment)) + + +class Href(object): + """Implements a callable that constructs URLs with the given base. The + function can be called with any number of positional and keyword + arguments which than are used to assemble the URL. Works with URLs + and posix paths. + + Positional arguments are appended as individual segments to + the path of the URL: + + >>> href = Href('/foo') + >>> href('bar', 23) + '/foo/bar/23' + >>> href('foo', bar=23) + '/foo/foo?bar=23' + + If any of the arguments (positional or keyword) evaluates to `None` it + will be skipped. If no keyword arguments are given the last argument + can be a :class:`dict` or :class:`MultiDict` (or any other dict subclass), + otherwise the keyword arguments are used for the query parameters, cutting + off the first trailing underscore of the parameter name: + + >>> href(is_=42) + '/foo?is=42' + >>> href({'foo': 'bar'}) + '/foo?foo=bar' + + Combining of both methods is not allowed: + + >>> href({'foo': 'bar'}, bar=42) + Traceback (most recent call last): + ... + TypeError: keyword arguments and query-dicts can't be combined + + Accessing attributes on the href object creates a new href object with + the attribute name as prefix: + + >>> bar_href = href.bar + >>> bar_href("blub") + '/foo/bar/blub' + + If `sort` is set to `True` the items are sorted by `key` or the default + sorting algorithm: + + >>> href = Href("/", sort=True) + >>> href(a=1, b=2, c=3) + '/?a=1&b=2&c=3' + + .. versionadded:: 0.5 + `sort` and `key` were added. + """ + + def __init__(self, base="./", charset="utf-8", sort=False, key=None): + if not base: + base = "./" + self.base = base + self.charset = charset + self.sort = sort + self.key = key + + def __getattr__(self, name): + if name[:2] == "__": + raise AttributeError(name) + base = self.base + if base[-1:] != "/": + base += "/" + return Href(url_join(base, name), self.charset, self.sort, self.key) + + def __call__(self, *path, **query): + if path and isinstance(path[-1], dict): + if query: + raise TypeError("keyword arguments and query-dicts can't be combined") + query, path = path[-1], path[:-1] + elif query: + query = dict( + [(k.endswith("_") and k[:-1] or k, v) for k, v in query.items()] + ) + path = "/".join( + [ + to_unicode(url_quote(x, self.charset), "ascii") + for x in path + if x is not None + ] + ).lstrip("/") + rv = self.base + if path: + if not rv.endswith("/"): + rv += "/" + rv = url_join(rv, "./" + path) + if query: + rv += "?" + to_unicode( + url_encode(query, self.charset, sort=self.sort, key=self.key), "ascii" + ) + return to_native(rv) diff --git a/venv/lib/python3.7/site-packages/werkzeug/useragents.py b/venv/lib/python3.7/site-packages/werkzeug/useragents.py new file mode 100644 index 0000000..e265e09 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/useragents.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.useragents + ~~~~~~~~~~~~~~~~~~~ + + This module provides a helper to inspect user agent strings. This module + is far from complete but should work for most of the currently available + browsers. + + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import re +import warnings + + +class UserAgentParser(object): + """A simple user agent parser. Used by the `UserAgent`.""" + + platforms = ( + ("cros", "chromeos"), + ("iphone|ios", "iphone"), + ("ipad", "ipad"), + (r"darwin|mac|os\s*x", "macos"), + ("win", "windows"), + (r"android", "android"), + ("netbsd", "netbsd"), + ("openbsd", "openbsd"), + ("freebsd", "freebsd"), + ("dragonfly", "dragonflybsd"), + ("(sun|i86)os", "solaris"), + (r"x11|lin(\b|ux)?", "linux"), + (r"nintendo\s+wii", "wii"), + ("irix", "irix"), + ("hp-?ux", "hpux"), + ("aix", "aix"), + ("sco|unix_sv", "sco"), + ("bsd", "bsd"), + ("amiga", "amiga"), + ("blackberry|playbook", "blackberry"), + ("symbian", "symbian"), + ) + browsers = ( + ("googlebot", "google"), + ("msnbot", "msn"), + ("yahoo", "yahoo"), + ("ask jeeves", "ask"), + (r"aol|america\s+online\s+browser", "aol"), + ("opera", "opera"), + ("edge", "edge"), + ("chrome|crios", "chrome"), + ("seamonkey", "seamonkey"), + ("firefox|firebird|phoenix|iceweasel", "firefox"), + ("galeon", "galeon"), + ("safari|version", "safari"), + ("webkit", "webkit"), + ("camino", "camino"), + ("konqueror", "konqueror"), + ("k-meleon", "kmeleon"), + ("netscape", "netscape"), + (r"msie|microsoft\s+internet\s+explorer|trident/.+? rv:", "msie"), + ("lynx", "lynx"), + ("links", "links"), + ("Baiduspider", "baidu"), + ("bingbot", "bing"), + ("mozilla", "mozilla"), + ) + + _browser_version_re = r"(?:%s)[/\sa-z(]*(\d+[.\da-z]+)?" + _language_re = re.compile( + r"(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|" + r"(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)" + ) + + def __init__(self): + self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platforms] + self.browsers = [ + (b, re.compile(self._browser_version_re % a, re.I)) + for a, b in self.browsers + ] + + def __call__(self, user_agent): + for platform, regex in self.platforms: # noqa: B007 + match = regex.search(user_agent) + if match is not None: + break + else: + platform = None + for browser, regex in self.browsers: # noqa: B007 + match = regex.search(user_agent) + if match is not None: + version = match.group(1) + break + else: + browser = version = None + match = self._language_re.search(user_agent) + if match is not None: + language = match.group(1) or match.group(2) + else: + language = None + return platform, browser, version, language + + +class UserAgent(object): + """Represents a user agent. Pass it a WSGI environment or a user agent + string and you can inspect some of the details from the user agent + string via the attributes. The following attributes exist: + + .. attribute:: string + + the raw user agent string + + .. attribute:: platform + + the browser platform. The following platforms are currently + recognized: + + - `aix` + - `amiga` + - `android` + - `blackberry` + - `bsd` + - `chromeos` + - `dragonflybsd` + - `freebsd` + - `hpux` + - `ipad` + - `iphone` + - `irix` + - `linux` + - `macos` + - `netbsd` + - `openbsd` + - `sco` + - `solaris` + - `symbian` + - `wii` + - `windows` + + .. attribute:: browser + + the name of the browser. The following browsers are currently + recognized: + + - `aol` * + - `ask` * + - `baidu` * + - `bing` * + - `camino` + - `chrome` + - `edge` + - `firefox` + - `galeon` + - `google` * + - `kmeleon` + - `konqueror` + - `links` + - `lynx` + - `mozilla` + - `msie` + - `msn` + - `netscape` + - `opera` + - `safari` + - `seamonkey` + - `webkit` + - `yahoo` * + + (Browsers marked with a star (``*``) are crawlers.) + + .. attribute:: version + + the version of the browser + + .. attribute:: language + + the language of the browser + """ + + _parser = UserAgentParser() + + def __init__(self, environ_or_string): + if isinstance(environ_or_string, dict): + environ_or_string = environ_or_string.get("HTTP_USER_AGENT", "") + self.string = environ_or_string + self.platform, self.browser, self.version, self.language = self._parser( + environ_or_string + ) + + def to_header(self): + return self.string + + def __str__(self): + return self.string + + def __nonzero__(self): + return bool(self.browser) + + __bool__ = __nonzero__ + + def __repr__(self): + return "<%s %r/%s>" % (self.__class__.__name__, self.browser, self.version) + + +# DEPRECATED +from .wrappers import UserAgentMixin as _UserAgentMixin + + +class UserAgentMixin(_UserAgentMixin): + @property + def user_agent(self, *args, **kwargs): + warnings.warn( + "'werkzeug.useragents.UserAgentMixin' should be imported" + " from 'werkzeug.wrappers.UserAgentMixin'. This old import" + " will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + return super(_UserAgentMixin, self).user_agent diff --git a/venv/lib/python3.7/site-packages/werkzeug/utils.py b/venv/lib/python3.7/site-packages/werkzeug/utils.py new file mode 100644 index 0000000..2062057 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/utils.py @@ -0,0 +1,836 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.utils + ~~~~~~~~~~~~~~ + + This module implements various utilities for WSGI applications. Most of + them are used by the request and response wrappers but especially for + middleware development it makes sense to use them without the wrappers. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import codecs +import os +import pkgutil +import re +import sys +import warnings + +from ._compat import iteritems +from ._compat import PY2 +from ._compat import reraise +from ._compat import string_types +from ._compat import text_type +from ._compat import unichr +from ._internal import _DictAccessorProperty +from ._internal import _missing +from ._internal import _parse_signature + +try: + from html.entities import name2codepoint +except ImportError: + from htmlentitydefs import name2codepoint + + +_format_re = re.compile(r"\$(?:(%s)|\{(%s)\})" % (("[a-zA-Z_][a-zA-Z0-9_]*",) * 2)) +_entity_re = re.compile(r"&([^;]+);") +_filename_ascii_strip_re = re.compile(r"[^A-Za-z0-9_.-]") +_windows_device_files = ( + "CON", + "AUX", + "COM1", + "COM2", + "COM3", + "COM4", + "LPT1", + "LPT2", + "LPT3", + "PRN", + "NUL", +) + + +class cached_property(property): + """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:: + + class Foo(object): + + @cached_property + def foo(self): + # calculate something important here + return 42 + + The class has to have a `__dict__` in order for this property to + work. + """ + + # implementation detail: A subclass of python's builtin property + # decorator, we override __get__ to check for a cached value. If one + # chooses to invoke __get__ by hand the property will still work as + # expected because the lookup logic is replicated in __get__ for + # manual invocation. + + 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 + + def __set__(self, obj, value): + obj.__dict__[self.__name__] = value + + def __get__(self, obj, type=None): + if obj is None: + return self + value = obj.__dict__.get(self.__name__, _missing) + if value is _missing: + value = self.func(obj) + obj.__dict__[self.__name__] = value + return value + + +class environ_property(_DictAccessorProperty): + """Maps request attributes to environment variables. This works not only + for the Werzeug request object, but also any other class with an + environ attribute: + + >>> class Test(object): + ... environ = {'key': 'value'} + ... test = environ_property('key') + >>> var = Test() + >>> var.test + 'value' + + If you pass it a second value it's used as default if the key does not + exist, the third one can be a converter that takes a value and converts + it. If it raises :exc:`ValueError` or :exc:`TypeError` the default value + is used. If no default value is provided `None` is used. + + Per default the property is read only. You have to explicitly enable it + by passing ``read_only=False`` to the constructor. + """ + + read_only = True + + def lookup(self, obj): + return obj.environ + + +class header_property(_DictAccessorProperty): + """Like `environ_property` but for headers.""" + + def lookup(self, obj): + return obj.headers + + +class HTMLBuilder(object): + """Helper object for HTML generation. + + Per default there are two instances of that class. The `html` one, and + the `xhtml` one for those two dialects. The class uses keyword parameters + and positional parameters to generate small snippets of HTML. + + Keyword parameters are converted to XML/SGML attributes, positional + arguments are used as children. Because Python accepts positional + arguments before keyword arguments it's a good idea to use a list with the + star-syntax for some children: + + >>> html.p(class_='foo', *[html.a('foo', href='foo.html'), ' ', + ... html.a('bar', href='bar.html')]) + u'

    foo bar

    ' + + This class works around some browser limitations and can not be used for + arbitrary SGML/XML generation. For that purpose lxml and similar + libraries exist. + + Calling the builder escapes the string passed: + + >>> html.p(html("")) + u'

    <foo>

    ' + """ + + _entity_re = re.compile(r"&([^;]+);") + _entities = name2codepoint.copy() + _entities["apos"] = 39 + _empty_elements = { + "area", + "base", + "basefont", + "br", + "col", + "command", + "embed", + "frame", + "hr", + "img", + "input", + "keygen", + "isindex", + "link", + "meta", + "param", + "source", + "wbr", + } + _boolean_attributes = { + "selected", + "checked", + "compact", + "declare", + "defer", + "disabled", + "ismap", + "multiple", + "nohref", + "noresize", + "noshade", + "nowrap", + } + _plaintext_elements = {"textarea"} + _c_like_cdata = {"script", "style"} + + def __init__(self, dialect): + self._dialect = dialect + + def __call__(self, s): + return escape(s) + + def __getattr__(self, tag): + if tag[:2] == "__": + raise AttributeError(tag) + + def proxy(*children, **arguments): + buffer = "<" + tag + for key, value in iteritems(arguments): + if value is None: + continue + if key[-1] == "_": + key = key[:-1] + if key in self._boolean_attributes: + if not value: + continue + if self._dialect == "xhtml": + value = '="' + key + '"' + else: + value = "" + else: + value = '="' + escape(value) + '"' + buffer += " " + key + value + if not children and tag in self._empty_elements: + if self._dialect == "xhtml": + buffer += " />" + else: + buffer += ">" + return buffer + buffer += ">" + + children_as_string = "".join( + [text_type(x) for x in children if x is not None] + ) + + if children_as_string: + if tag in self._plaintext_elements: + children_as_string = escape(children_as_string) + elif tag in self._c_like_cdata and self._dialect == "xhtml": + children_as_string = ( + "/**/" + ) + buffer += children_as_string + "" + return buffer + + return proxy + + def __repr__(self): + return "<%s for %r>" % (self.__class__.__name__, self._dialect) + + +html = HTMLBuilder("html") +xhtml = HTMLBuilder("xhtml") + +# https://cgit.freedesktop.org/xdg/shared-mime-info/tree/freedesktop.org.xml.in +# https://www.iana.org/assignments/media-types/media-types.xhtml +# Types listed in the XDG mime info that have a charset in the IANA registration. +_charset_mimetypes = { + "application/ecmascript", + "application/javascript", + "application/sql", + "application/xml", + "application/xml-dtd", + "application/xml-external-parsed-entity", +} + + +def get_content_type(mimetype, charset): + """Returns the full content type string with charset for a mimetype. + + If the mimetype represents text, the charset parameter will be + appended, otherwise the mimetype is returned unchanged. + + :param mimetype: The mimetype to be used as content type. + :param charset: The charset to be appended for text mimetypes. + :return: The content type. + + .. verionchanged:: 0.15 + Any type that ends with ``+xml`` gets a charset, not just those + that start with ``application/``. Known text types such as + ``application/javascript`` are also given charsets. + """ + if ( + mimetype.startswith("text/") + or mimetype in _charset_mimetypes + or mimetype.endswith("+xml") + ): + mimetype += "; charset=" + charset + + return mimetype + + +def detect_utf_encoding(data): + """Detect which UTF encoding 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. + + :internal: + + :param data: Bytes in unknown UTF encoding. + :return: UTF encoding name + + .. versionadded:: 0.15 + """ + 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 format_string(string, context): + """String-template format a string: + + >>> format_string('$foo and ${foo}s', dict(foo=42)) + '42 and 42s' + + This does not do any attribute lookup etc. For more advanced string + formattings have a look at the `werkzeug.template` module. + + :param string: the format string. + :param context: a dict with the variables to insert. + """ + + def lookup_arg(match): + x = context[match.group(1) or match.group(2)] + if not isinstance(x, string_types): + x = type(string)(x) + return x + + return _format_re.sub(lookup_arg, string) + + +def secure_filename(filename): + r"""Pass it a filename and it will return a secure version of it. This + filename can then safely be stored on a regular file system and passed + to :func:`os.path.join`. The filename returned is an ASCII only string + for maximum portability. + + On windows systems the function also makes sure that the file is not + named after one of the special device files. + + >>> secure_filename("My cool movie.mov") + 'My_cool_movie.mov' + >>> secure_filename("../../../etc/passwd") + 'etc_passwd' + >>> secure_filename(u'i contain cool \xfcml\xe4uts.txt') + 'i_contain_cool_umlauts.txt' + + The function might return an empty filename. It's your responsibility + to ensure that the filename is unique and that you abort or + generate a random filename if the function returned an empty one. + + .. versionadded:: 0.5 + + :param filename: the filename to secure + """ + if isinstance(filename, text_type): + from unicodedata import normalize + + filename = normalize("NFKD", filename).encode("ascii", "ignore") + if not PY2: + filename = filename.decode("ascii") + for sep in os.path.sep, os.path.altsep: + if sep: + filename = filename.replace(sep, " ") + filename = str(_filename_ascii_strip_re.sub("", "_".join(filename.split()))).strip( + "._" + ) + + # on nt a couple of special files are present in each folder. We + # have to ensure that the target file is not such a filename. In + # this case we prepend an underline + if ( + os.name == "nt" + and filename + and filename.split(".")[0].upper() in _windows_device_files + ): + filename = "_" + filename + + return filename + + +def escape(s, quote=None): + """Replace special characters "&", "<", ">" and (") to HTML-safe sequences. + + There is a special handling for `None` which escapes to an empty string. + + .. versionchanged:: 0.9 + `quote` is now implicitly on. + + :param s: the string to escape. + :param quote: ignored. + """ + if s is None: + return "" + elif hasattr(s, "__html__"): + return text_type(s.__html__()) + elif not isinstance(s, string_types): + s = text_type(s) + if quote is not None: + from warnings import warn + + warn( + "The 'quote' parameter is no longer used as of version 0.9" + " and will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + s = ( + s.replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace('"', """) + ) + return s + + +def unescape(s): + """The reverse function of `escape`. This unescapes all the HTML + entities, not only the XML entities inserted by `escape`. + + :param s: the string to unescape. + """ + + def handle_match(m): + name = m.group(1) + if name in HTMLBuilder._entities: + return unichr(HTMLBuilder._entities[name]) + try: + if name[:2] in ("#x", "#X"): + return unichr(int(name[2:], 16)) + elif name.startswith("#"): + return unichr(int(name[1:])) + except ValueError: + pass + return u"" + + return _entity_re.sub(handle_match, s) + + +def redirect(location, code=302, Response=None): + """Returns a response object (a WSGI application) that, if called, + redirects the client to the target location. Supported codes are + 301, 302, 303, 305, 307, and 308. 300 is not supported because + it's not a real redirect and 304 because it's the answer for a + request with a request with defined If-Modified-Since headers. + + .. versionadded:: 0.6 + The location can now be a unicode string that is encoded using + the :func:`iri_to_uri` function. + + .. versionadded:: 0.10 + The class used for the Response object can now be passed in. + + :param location: the location the response should redirect to. + :param code: the redirect status code. defaults to 302. + :param class Response: a Response class to use when instantiating a + response. The default is :class:`werkzeug.wrappers.Response` if + unspecified. + """ + if Response is None: + from .wrappers import Response + + display_location = escape(location) + if isinstance(location, text_type): + # Safe conversion is necessary here as we might redirect + # to a broken URI scheme (for instance itms-services). + from .urls import iri_to_uri + + location = iri_to_uri(location, safe_conversion=True) + response = Response( + '\n' + "Redirecting...\n" + "

    Redirecting...

    \n" + "

    You should be redirected automatically to target URL: " + '%s. If not click the link.' + % (escape(location), display_location), + code, + mimetype="text/html", + ) + response.headers["Location"] = location + return response + + +def append_slash_redirect(environ, code=301): + """Redirects to the same URL but with a slash appended. The behavior + of this function is undefined if the path ends with a slash already. + + :param environ: the WSGI environment for the request that triggers + the redirect. + :param code: the status code for the redirect. + """ + new_path = environ["PATH_INFO"].strip("/") + "/" + query_string = environ.get("QUERY_STRING") + if query_string: + new_path += "?" + query_string + return redirect(new_path, code) + + +def import_string(import_name, silent=False): + """Imports an object based on a string. This is useful if you want to + use import paths as endpoints or something similar. An import path can + be specified either in dotted notation (``xml.sax.saxutils.escape``) + or with a colon as object delimiter (``xml.sax.saxutils:escape``). + + If `silent` is True the return value will be `None` if the import fails. + + :param import_name: the dotted name for the object to import. + :param silent: if set to `True` import errors are ignored and + `None` is returned instead. + :return: imported object + """ + # force the import name to automatically convert to strings + # __import__ is not able to handle unicode strings in the fromlist + # if the module is a package + import_name = str(import_name).replace(":", ".") + try: + try: + __import__(import_name) + except ImportError: + if "." not in import_name: + raise + else: + return sys.modules[import_name] + + module_name, obj_name = import_name.rsplit(".", 1) + module = __import__(module_name, globals(), locals(), [obj_name]) + try: + return getattr(module, obj_name) + except AttributeError as e: + raise ImportError(e) + + except ImportError as e: + if not silent: + reraise( + ImportStringError, ImportStringError(import_name, e), sys.exc_info()[2] + ) + + +def find_modules(import_path, include_packages=False, recursive=False): + """Finds all the modules below a package. This can be useful to + automatically import all views / controllers so that their metaclasses / + function decorators have a chance to register themselves on the + application. + + Packages are not returned unless `include_packages` is `True`. This can + also recursively list modules but in that case it will import all the + packages to get the correct load path of that module. + + :param import_path: the dotted name for the package to find child modules. + :param include_packages: set to `True` if packages should be returned, too. + :param recursive: set to `True` if recursion should happen. + :return: generator + """ + module = import_string(import_path) + path = getattr(module, "__path__", None) + if path is None: + raise ValueError("%r is not a package" % import_path) + basename = module.__name__ + "." + for _importer, modname, ispkg in pkgutil.iter_modules(path): + modname = basename + modname + if ispkg: + if include_packages: + yield modname + if recursive: + for item in find_modules(modname, include_packages, True): + yield item + else: + yield modname + + +def validate_arguments(func, args, kwargs, drop_extra=True): + """Checks if the function accepts the arguments and keyword arguments. + Returns a new ``(args, kwargs)`` tuple that can safely be passed to + the function without causing a `TypeError` because the function signature + is incompatible. If `drop_extra` is set to `True` (which is the default) + any extra positional or keyword arguments are dropped automatically. + + The exception raised provides three attributes: + + `missing` + A set of argument names that the function expected but where + missing. + + `extra` + A dict of keyword arguments that the function can not handle but + where provided. + + `extra_positional` + A list of values that where given by positional argument but the + function cannot accept. + + This can be useful for decorators that forward user submitted data to + a view function:: + + from werkzeug.utils import ArgumentValidationError, validate_arguments + + def sanitize(f): + def proxy(request): + data = request.values.to_dict() + try: + args, kwargs = validate_arguments(f, (request,), data) + except ArgumentValidationError: + raise BadRequest('The browser failed to transmit all ' + 'the data expected.') + return f(*args, **kwargs) + return proxy + + :param func: the function the validation is performed against. + :param args: a tuple of positional arguments. + :param kwargs: a dict of keyword arguments. + :param drop_extra: set to `False` if you don't want extra arguments + to be silently dropped. + :return: tuple in the form ``(args, kwargs)``. + """ + parser = _parse_signature(func) + args, kwargs, missing, extra, extra_positional = parser(args, kwargs)[:5] + if missing: + raise ArgumentValidationError(tuple(missing)) + elif (extra or extra_positional) and not drop_extra: + raise ArgumentValidationError(None, extra, extra_positional) + return tuple(args), kwargs + + +def bind_arguments(func, args, kwargs): + """Bind the arguments provided into a dict. When passed a function, + a tuple of arguments and a dict of keyword arguments `bind_arguments` + returns a dict of names as the function would see it. This can be useful + to implement a cache decorator that uses the function arguments to build + the cache key based on the values of the arguments. + + :param func: the function the arguments should be bound for. + :param args: tuple of positional arguments. + :param kwargs: a dict of keyword arguments. + :return: a :class:`dict` of bound keyword arguments. + """ + ( + args, + kwargs, + missing, + extra, + extra_positional, + arg_spec, + vararg_var, + kwarg_var, + ) = _parse_signature(func)(args, kwargs) + values = {} + for (name, _has_default, _default), value in zip(arg_spec, args): + values[name] = value + if vararg_var is not None: + values[vararg_var] = tuple(extra_positional) + elif extra_positional: + raise TypeError("too many positional arguments") + if kwarg_var is not None: + multikw = set(extra) & set([x[0] for x in arg_spec]) + if multikw: + raise TypeError( + "got multiple values for keyword argument " + repr(next(iter(multikw))) + ) + values[kwarg_var] = extra + elif extra: + raise TypeError("got unexpected keyword argument " + repr(next(iter(extra)))) + return values + + +class ArgumentValidationError(ValueError): + + """Raised if :func:`validate_arguments` fails to validate""" + + def __init__(self, missing=None, extra=None, extra_positional=None): + self.missing = set(missing or ()) + self.extra = extra or {} + self.extra_positional = extra_positional or [] + ValueError.__init__( + self, + "function arguments invalid. (%d missing, %d additional)" + % (len(self.missing), len(self.extra) + len(self.extra_positional)), + ) + + +class ImportStringError(ImportError): + """Provides information about a failed :func:`import_string` attempt.""" + + #: String in dotted notation that failed to be imported. + import_name = None + #: Wrapped exception. + exception = None + + def __init__(self, import_name, exception): + self.import_name = import_name + self.exception = exception + + msg = ( + "import_string() failed for %r. Possible reasons are:\n\n" + "- missing __init__.py in a package;\n" + "- package or module path not included in sys.path;\n" + "- duplicated package or module name taking precedence in " + "sys.path;\n" + "- missing module, class, function or variable;\n\n" + "Debugged import:\n\n%s\n\n" + "Original exception:\n\n%s: %s" + ) + + name = "" + tracked = [] + for part in import_name.replace(":", ".").split("."): + name += (name and ".") + part + imported = import_string(name, silent=True) + if imported: + tracked.append((name, getattr(imported, "__file__", None))) + else: + track = ["- %r found in %r." % (n, i) for n, i in tracked] + track.append("- %r not found." % name) + msg = msg % ( + import_name, + "\n".join(track), + exception.__class__.__name__, + str(exception), + ) + break + + ImportError.__init__(self, msg) + + def __repr__(self): + return "<%s(%r, %r)>" % ( + self.__class__.__name__, + self.import_name, + self.exception, + ) + + +# DEPRECATED +from .datastructures import CombinedMultiDict as _CombinedMultiDict +from .datastructures import EnvironHeaders as _EnvironHeaders +from .datastructures import Headers as _Headers +from .datastructures import MultiDict as _MultiDict +from .http import dump_cookie as _dump_cookie +from .http import parse_cookie as _parse_cookie + + +class MultiDict(_MultiDict): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.utils.MultiDict' has moved to 'werkzeug" + ".datastructures.MultiDict' as of version 0.5. This old" + " import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(MultiDict, self).__init__(*args, **kwargs) + + +class CombinedMultiDict(_CombinedMultiDict): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.utils.CombinedMultiDict' has moved to 'werkzeug" + ".datastructures.CombinedMultiDict' as of version 0.5. This" + " old import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(CombinedMultiDict, self).__init__(*args, **kwargs) + + +class Headers(_Headers): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.utils.Headers' has moved to 'werkzeug" + ".datastructures.Headers' as of version 0.5. This old" + " import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(Headers, self).__init__(*args, **kwargs) + + +class EnvironHeaders(_EnvironHeaders): + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.utils.EnvironHeaders' has moved to 'werkzeug" + ".datastructures.EnvironHeaders' as of version 0.5. This" + " old import will be removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(EnvironHeaders, self).__init__(*args, **kwargs) + + +def parse_cookie(*args, **kwargs): + warnings.warn( + "'werkzeug.utils.parse_cookie' as moved to 'werkzeug.http" + ".parse_cookie' as of version 0.5. This old import will be" + " removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + return _parse_cookie(*args, **kwargs) + + +def dump_cookie(*args, **kwargs): + warnings.warn( + "'werkzeug.utils.dump_cookie' as moved to 'werkzeug.http" + ".dump_cookie' as of version 0.5. This old import will be" + " removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + return _dump_cookie(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py new file mode 100644 index 0000000..56c764a --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__init__.py @@ -0,0 +1,36 @@ +""" +werkzeug.wrappers +~~~~~~~~~~~~~~~~~ + +The wrappers are simple request and response objects which you can +subclass to do whatever you want them to do. The request object contains +the information transmitted by the client (webbrowser) and the response +object contains all the information sent back to the browser. + +An important detail is that the request object is created with the WSGI +environ and will act as high-level proxy whereas the response object is an +actual WSGI application. + +Like everything else in Werkzeug these objects will work correctly with +unicode data. Incoming form data parsed by the response object will be +decoded into an unicode object if possible and if it makes sense. + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +from .accept import AcceptMixin +from .auth import AuthorizationMixin +from .auth import WWWAuthenticateMixin +from .base_request import BaseRequest +from .base_response import BaseResponse +from .common_descriptors import CommonRequestDescriptorsMixin +from .common_descriptors import CommonResponseDescriptorsMixin +from .etag import ETagRequestMixin +from .etag import ETagResponseMixin +from .request import PlainRequest +from .request import Request +from .request import StreamOnlyMixin +from .response import Response +from .response import ResponseStream +from .response import ResponseStreamMixin +from .user_agent import UserAgentMixin diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfaa166c49280cf68d12559173c7fc26bda66a26 GIT binary patch literal 1690 zcmaJ>O>Y}F5S47%l2>1r>?C!87IUl*@;V7pr$!OfPKqKxKZ4kSfJJ}>cbC>O;*uMZ zvMe9^a{~0A^f&0*OWSi#J$1+xq0}h4f{4fA%;U@(lIPuSP{Z%{4}ZPQw`#TD?8JW? z2)@C;{uPI;7S*zPw!!PgMzm44c$04yji}*p1Myb0;Am zQQP4b;!f0Yc!zh3Uet3qK-`b|4!8MkF^C2ZcMuPwp~GFod(oc5J-%Pui|#qxM|?lJ z@9-|-2hjtE2mF)bAUZ%iyr>=Skw3ApU{2Namd++eb4ALMDjocM_X~o{oPu8mq9|xq zl$?U1?`KpSAR=b22!JgQ>@$ioWl9Vi_zoJb53TO27lD? z_8!)k?XxtcrTKx~FoDzI+05ipv0EpVx9*R}W4nOuw<1z+Z=VxQUstCdgFDrxo(RJg(f(viEO`59+4m$IETvWK{NXTs8=5 zr8W_&1`bgtL78Gz>7?*Itwr6HsVYKkTiXy%56Ts1YoS!rlC*GGHtg5w81_e;ucqyaMO;8)Zji&;-9y>kYK1l%Lbp;Is@)6*%}g|(UGTFSP<`mEtLbnQ?h zb<%jNkp^wvnQn_T-)P;|p9UP;)wAvX6f;gm&-ZB}U}EPON0Ss!Xf@M5IXW3sqlbyy z?_ssyn^H_DgV%O_>`y825*8Jm~XW^-L=53 z5lh*1u$9j+-vGNwT57&Y+Ti`#1!EO9bh5Y z!TI+uF{iI7PvVGEn@011#nCyEi@_)rw2h#N7)_`^I1G`PQuONV>=fl;qC8BFFjqSd z)HQJIHD#9znoewj1?GaKzDOD6cJALfibogJ7aV;GuJLqKc$eQcrHsbouB}GC4#>zR z|0VT(c=&tJ3GF-WLjM8a`cW6=odEzCi}*O;0>xv9d`87>0uhU8z#;sAMgp!%l9<80 zg}*YodwpKAT>726CSP{9BpP0?-yfWwb!*H5$FfF&V`c(uOgasDP~$Wl|E#es82-(i zgavafs58gR8OI^y3U`t{C%kwn#NyfhXP12P1#4Q|z{0~77QFte-s?Amk`2~`09i|Rxw4roEsBP`>%cJEEn+TR{s1Pq zWKOdTeevN2bjqEZ!Fd30t|sW6uF~_D5*ix$F$to{IySiz+(u|nt%H7XE;&KjOld+U z9%dBz@hkyR@gR=S@<5*Ypm2^Riy(oMzLerGiJ0O!h2z3Fz66a|hZV(O9fR|gEPsC$ z-@&l|)fY#@!>*~)eF<<^--vCQc$JGEOK?@<)i)+ywQ)1H|0RAbYeWffSQP7x0Kb#` z*USDg`6~2m8_hv#zyjbLO(;Qo_I|YrTpdLSc$x=s%FCUFTi3u7MvP9<5VO@+?k!4r zMlQXPIU$?7M%8g|c=&bia8OjHB~{D>4({Qrg76c`ml8t@#IUJUR9lDLR@U^q2+yeJ zWo^%!#Uu@--SNDu6oWKyN90iBdHmlAGT zHKWt$v^q^SKkT;Mo%OGc61<9372&Kl6(Y$?w3Uh=^dR`0w literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/auth.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/auth.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f3ece7b99db54fb59660619bc51055dd02373f4 GIT binary patch literal 1706 zcmbW1&u`pB6vt<5@2(Se+Yl;LRUlbN9JW&I_D~w45H)ZhJ&+<;6v;yJPCT<&Ctll~ znaw8FmP;bw&!8714*WyDa)CQ1PP{jcm)+0DQxfG`a3^96|wfszcB?bv0!A;_0OQHdtm0| zl>9_FeNA6cZO!Qw1(&Vz;Q(~r)>H53CE1M!-YAz7KioVR48Dx^zZo37`09DMKY0G) zuy0o#k)0G`Nd_`Tgg@zV}U3WyGu)NC5$H7{>t*he!Fs`C}R^5Mb&x~O>#a>vE7ZLms6JB z%ygoN=W!HC+*;xx#@!|J7LK*Rw4oXWuH#r{t=#Mo@HlSnyN(hq$FgaylU;<%V%gPpf z15a#)sKs$eEgts{RON%26Lp`PgU;IWJ|4*FCnVdP6Zvos9KR-J%-V$)2#&T7%MI{# z3-i|mq};eIq;FN7nn)F{>3s2kgl-e3K9w$MS*QrCx z?Kh>sZ}w_*_`7KyvsCT*i>>}Gwr|T#*jaYaU?gC`D8Y!xH8gmI8hu6@dc5)?z6&c9 zB1W8U8wmgKKj{O^We@(5chKBLvjL`Zo2O0U^RYxT3Xulsx1nWHhUB{xkj9b2zFRqC rtqb!Q7;mc9R41u2H>7IUuo?W#4{zGLa(CeV8mw)=dKKtJrx!ix^7xPy{<86H6OHMB5=X|G~ ztMUJQ+v((Md57&nyU;1tif9-8iS|UNR4Yllg!W`@QreSfmuqEdm(iZ8O-XyIJ>8k9 z%}9G1?Mkg8?HRQ9)b>cbg7)6pUTN<^dtYszwD+PtTbq^kKD77O_Dg%VJ=Zx(tl0W)eo*T+-z*>Rj>?@46So0*y+Kt$H&IH(T7>LG?ZC zC73X-Z^+tlf4U#F6(rbeU(;)D1b)32g#c>8p=SfN+w8qL!l)T`lc1Z_+d+3d+2F%+ zw;x5ki(zrA%v&3wz+{%~R=3wT>u(a5=5G>>xABQxpfAYP96wjf`%bOk=W9j3P@C|J zwGuv)LAf>+OxI?DN^MWDx3&-WX8noUe&6#a{qk2%ZO)(ar$I3Xf`k5yU->F`AY z9P;=0d!>CC?S1~Nw2%0!{(gTBPaQ??1O7p|`?&v@e+VNy;UD&o;QuH6qyFRg|0zY8 zwWl>rKI1>*ySVQL$NXddae4N5@T~u=|J=QN?K#|i-hV;vK9BYZ|D?2E@SFa;|03o* zfxAEPPs!brXrK10(w;~AjDJ?zFQWaD|5IuI1nrmoSEPLk?N|NRqRe( zBlNlHeS|Lcd@5pGo^X+MoMhNc(4K*ZqdH-}Z};1AaR5ju!{Z!I%9Y zPP}hHJs$_rw!7-Zt)?5P+itjeD`+NF*In6Y#jYO)vD*z3x7F#jgARz)_59mpecz3f z{@R+`ZfyqBF8=UaE7^7vZ`~!^Kt{M>O0A$1-d%HkXTen&8a@V{WyQ4H+%j z2;7@D-o1)pMQ*66V|T3;#aKhM-dA_Je5T#Ts(iPV#6f$_O+wc^trs>jLZfkFD~L7+ zL4UofH+`bfaQoeM5XTtf#4f98^uk`hP0^{JXt;5ZaHh*%I}WPTGSSLL5CvEpKG<;| z0CU4Nx6``Q>c*~j+iSHc?XWnHQ1tm}QL=b#cdg%TswQBl0HAg;ik4H{8O8_1FmK3t z+8$Qj^xADeud%F<*l@QtT1^GWxW6iWfX7A#{SDUx=rN{c;uzVo8vyY^%WY7Zwy+NStdCmTJ+i^&hY;`*t&M zIpr>{c__m_1~iXoT$*FZE+km{HDlr5GsM-V*Zbg+L)lS(C|i%%ioe%)Hx}0021F5?m78 zNnF?>9!a^;Pu5Pq(UA27U78y{wsO54Kw3dotYLT%-hv-C7aAlnZIigo4X+37@18rO z@0@Q49dyD-ZO#u8FdYE58uk-Su&n_l6Ngz1HoV)dF!~X@Sj7%}Ebn_|j3qSt6{W>w80;Bzz1D}Ug{bJXe7_xRf%{^} zO3IRPxI@y(Dit$voidEj?CQ4bHJgx#T`I~826|SnVJ_-SqcpygTr}pYRaYCfpz7{= z;4dst0?3>YAQTX%DIf^u0HhHEp;#34FjmtSiE4Qk5T;td-ndtggBgaaSClrG5T;8f zqd;WG(&d#VT`&Ie{{lW2@rjS)vg7RJ>baeKbY!OxAKA(69TBMeap2E1bSpy=YSEHwK`**p>#ed)4In#?;x1n{<-1ed~ zYhjz7!)>v_vnk>qiqfm`>H}LRs}XLDcm+0b0ddVXHfzkDlQ$MVMx>pifpq9`82)Joy@aq*w1-)J+i@P)3~c$01{i)=B4uT)Kj&rvFa>(D$`{24;g$Mb&#hu~~z6l>X zJNe%_cP9qZI}`UoA`jsBqc!mWfFscWS`%IgOnp%dZP#BbiL_~8}By%^wP*kBUxcZO?*nqJzWCCanpjwGGV(n5W5}1}uLO({&NpT2UAwi%b zf%?gs(=fp?@fzHaeuTN2?G~iFU7?21Nn_n!l%E^(is(e)3UO)cSmF`zf)caJ_>>*W zSOHv%iZno$CrzyfxOjmQ6bzK07;0_|MuXCoC_*pO{4X+_-PjLbjO)G=G(93moCe@0yCaO#&;-_?<%-SI z$`hr!WnCTJqaH$SMxf9*yT^qn02;ds2K?HHwM&ht;=sEmDy6{`RdIW1zLXXT!{`jY zr3I)cxu4E37Ne;yooKehI6&7zvmHmL*t4_=dji6bkEtgnR~7ijWI{Sanyo8d`IqRe zMB;%;ey`}5yfd92l@po%O_3vb2+V9hF{O-=6MqJt|4r^U&TsN-1;5}IzbfC&C;6TH z*ZF&Skpp!MaS3re*l=Vd;}npxU=Q`eE+|G5b_Vf=-_T2(a0^UB42HkA!e}#=xB$`W zE^z#Xh8?*9UqR*u{lkJALA_lHkWHV7OphVV)W$O1H4Km?p|J-fLIB%ca0Yv~562bu zE4}9Jtd~gIe|uSZL{%t9Se0Vt+O4t!JRP^QU6-&Y`kd5rjd^_Rsff^B7MRAt$rD!s zSmy4{Flzh9PRtJ-%M0T08T$lw-%GE!S5{W84=rIZ8bs>I!odms^$kQ4y1rc>OjfW1 z11XS|3gWZ^X$pylx#q6HA%f(~NSg&=F?Vf2KrJyB0!D=@LW8WKwzRyZbjZj9b|Hqr z_HY~4erSS9<&W$)gU?}n;ybu}4b#YXj^^$;cby&Q&%bbT+mC+@!wA8C=TGxTVFs-^ zhjYKp-Oa;9I$O+ror8(=nUkYV9L(($?!zYF^A8;Mz*G3;mxWKX(X_*nV5f4V-@D`Goo{GN za)_d*H^E33OYybq0jBSAj+4HnSE>w(#VL%rm z!}CwhH%_S*$Tq+?OJa;CHR2%H#7(W=sYei7gYZ}lF~C-YjDXNF`*JjX8CgnT0~a>H zsT^CyyI?yP&N;kx4{opQr=`MNNeJh{u7&YU#zs|Gp9|P%t;6Qwdb;kbXV3op9Y{x` z^g4{#tVZD$vJMQf(p0fSX@d(Bj}1zD!9W%Ag1#WX%0f(EJBnTiq#RUdoY}JGc6n+n z8=(Zi$arQ$P}4v)=d&|Vz&-L$MRt@SX=HIzXN8QK7`4G4ITU{YJlFd$1OQ}3Zjj|z z3rtG89KA0MvwDJDk=jqE1@i&lOng$&BZeV1A9|iQ>DH)c&9~j3b=_+SYG5girLY^o z{4jeMTZ_Vl8d2lLm_4!vZSV;^xYd5#r(&|hnPJENmk5Kl&anz*Pi+OOV}xb6?E8ij zGg;O!+z6cYgS$~mS~ieLD_MxAd(AhsPq;*s9`h5*GkP2C=p9}z@N$tC*Ip>D(%Cwt zFh|$=6mpu=JSJpzAScP z>@rT~YSuOcs}10$2m2CARBsLBE9%<9Go!ZO1XTio#@rx#HW|ajz(aNxVnnY5^c;8S zi)5waZtmtAcCNH?@q?w6#if<{%BR;Cp&*K@Vc3>fN?HKqcK1Qk#~4biLx6OUwoSY` z^D}|J4-hh5>9H(GckMj_R~zDR0on3Dn-FL%selk6@`@qp9>`Gbi z`y?I>gQ*TLBaGtoV8^?oAlV5JXWp*I2%)BPygN$!>0!GjkTMj=Iugr_$~_849d9!j z$5C{II1)pmRCI>_1|#^|^+}5_;>s%XzrYutn96OIqP;%+0S2Y+IfyJEG!=b;YvDdp z$9@s<1t%d63$V%ZNofZ>^I86G0a1tC{mBQpyAy~nl+m7gz&IdGg9pXCrS3sIF^#)3 zxGUGS!rc zCPSwd&(OpXN+UnFke?WhTq}Wqw3X;ustT4Eh;Ej|yHj*N7GS%Gw^$MwT+^ckl5 z6tVv%3Ob|`GBDJoD{2s<|#in~>y8G0Ar%?4?a&n!iYpo|nwtXgF{ zA;6liFm^|XAkKH7PLC`~>d-uO9nOuekX0DVjo#&j27PpZmnB@%36V7EVG+`5WRkcD zAgnt2kUg*AGGA6ILbL-Vc3L)yJDt>#kF+GCMQM>jEOq>G<*~0$Q*+2eC&)YuDCef9 zonpS6FCp4E4U4=CR+>WuvgAxpl$^m6S>ZP}hGipK-d3F)#~0YdbSm=q3Upcg{N_~j zB$!E53kaTMT^Rf~v34o#K|2!0f&0vGipqg%`KBPFL&}CU6%>FAEJSQUVG&G0B;?hBl^`*sJQI#8S`;B zT6(kkvL(#4QdbYk)JxD%lUN6Xt5E?k6NKwfacw5ka}1Ty$LRbX(MRc(nx!GGeki=-J9C17M?-NHno4j6&qMMxkQE&*~+2>RKy z)i~>`u%(TA*palTV$N6VK7dwLWk|wbSsr6i0Ugh%j4gVQBHmpO zNm7tbfli?-3h~@cL~t3Phg5(YWXBOP1MxtQgZ2psyWdsy255rBln#}mIq~RW-XLi! zL1@tHHPolsv9!oYFbCxmM)cs3(Dk%sBP3}p?UYc;5G+#&b}Z&$Mb@z!Ly{ha6O@Ip z6@;i-k@&yHNw<3mAu%(AuB##RyxB53=EP;=hzfMLU{$;aYlDuaWcV3Lz+&vepqP=A zH+f&NOc+vNoKk7~tZzp{0Y!UQvvm(BbnRdn^TulC*_*K09uk8P|F{d zH!-H$LG&Y`YpjR{1cf9uu#_E3OckZkU8Zy*7-oRi^(a75MnBf!4UKLlyanYfyMjB_ z9oj-z7Du5GgnAGpH0e*_ru-o)wgR?_9_NK-%IbC5%I$pFnp8?c6+cpT7+55wJ zEiwTR(Qh(C7gudvu&wqT#s&dbB^y9_VjBrlne2i{5_F-dO&V2cFp?;!i+Mr2R1H|W z*-=kUih4Y2tU(Guz?#8@1?)hWrW?@eV;oV(8A8Yz5WSM;)^MjVvgLR~LQX3mezds! zY5m5^^3|nxqw6H)d|FaoslR;a#~Coi~I$CeUBHhvv*HYGk^7`B!7vt%;XWR zrn5Pi%`yR#TO*_dwWM??xr^3Sv^Rl$bU)Bv7;Oz0{*2!$l&QONRH zYn?FoPAPN|pZI-TGL8l^{%|zP(JMQJ$c5G7&}yNxLAw>6xr1N8zID_EL|1l-_az2{ z-zQbI09_LA-(zr*;}k0j534BTg}Xtuuf1D=mgXFAh-AC*D^v{Rl|_M6{2S$*VPoMo zVKDI_RF)6w)KuJQ&a>k@%zjBE%>z)tb4L`7C75tL+TsAN5x@PaEMj~2&_XX zF9Z+w8Tq-4>{|+vf;Fxk<>*ijP~~}TA_?W460k!@098i=#D{~qXZNB69;-po4g197 z!@)QJZ(0Ts@XDG5)wYUTc9EHe4^X6qQiZFl>`+`3qRRB);f;i~i=w)2jIowNs#GRo zFKV+A8g61*bRJ+ea`kTgjg9R^SZ!y;E#1E7$uzC_Oy78H36$3c<# z?GS}z!JQ3MY*0Ib9Z1C>L(dUqsO9&->f&Zh=cwvBvxm(YdAJdYYUjhsAM`}f#n?OAW@mQPG z>yI}0U_QD%=Hx}2xc@uKa_ZXLQ58#KVIZSPMd;1ZS~e4e8PS{8PpAE zgr8S3WTVY2kZMN4{(nPB9M_DYWT`;&$z~ArXh0xXOJ;-ik>HC;|LGi!@|NNF_FQHY zPf0zBwwmpD+Njm0poB#cPc|07uEaU&KiQEeTa9}|#;~s8*{aDLiMkO-hs+B@DI;XT ztM2s=Zmf)q$ISNik5*vrik*%02WR0Q!fe6_Q3BL*MkyCqy2 zd)6#r)d4G8@0_LCN77x(BaG&%LZbxrt?|hONdcw~P{9gwgcYn`&fP?9tBQ~!Db%`P zi`TZyfgH-ZjE(=$NkZrjqEhFQhcPyd9h#^r*l*Cq=zn#-B-I=d_nS_)pb438Y6j6h z+=!mzWeOKKixSwPH5~nd7uQ~np_P_IAH{!1kTGt=D%Lshei?D)QHN1=w7|my!-&(a zT>q~C-|uyKhMtZtXp^KQs032k;+=8Ekt8?u_ada5i%1ktT?YR16S?ykc+3cJHSeuA!n zh1kMZl27`f-GX z(?oKFP?h^&wRRj@^e{=XM~Ap`vDyT@RzN*0Y#BR$gs|mL|J4fHgAleOv2elrh`_Ls znj?6UPT**Y-Be-?J|4XUck@P`Qfl2qUJGdO>@*SFSxbF}g?nyWJ!ESgraZ zzNkH_B9-2(oDE^Qf00>66#hH+Cw!a+In2yRaqzE~mDYzl(eqFWfemZZ**G?;78jvM zh%$6T^W~$TP%{q>}o~MrdnO5I^I`BCeJ9V{NGpe-KAZ?tQCz*)sd@eMYOKs`Tr?U7JF z1ppE-1PI{>lMLZL?ZtfS{0x~h7Q04VQd*H;nZZQ&=mp%`U2vpRJeeSye8!ShVKm2O zd)N()5EcjjF2XWoB}DZ)8B6dbG^OK{DsCpyg3%Q24pKyFi52dvwV4|im#hjg0pr?wWU9e!xC_F^{C@*Z_83eJtX@27k7bCyH zx+GyKLHbKVX7^a^^Z4nMMfAjAUsguqz|hF<7%aSqPi&Hhw-A5@wdVc&H%wp`24B3- z1HsyCz~c>Za!gdrQmGNAPoFbf2RFS&m=BI=0!$A;11$iXS5MC@A&&*f}k77uPH@Cq|VJe~i{R z4l_D~=Si<)=`~;nN)Fj6IgE7i65=)UPeB zT>0QqT6lMHWdwp)i;@}46shnNBn8VJ(g~bUmp9=!cg6*A`CQxUtoq)0o*w$2crrIi zmgeWd0{39t1m${E-IJH$XP9?2;0+vD6JNT4oA^R!1mEU|iApZfBASM?ty!!p#e9^N zJP0bF^eV>_kvQdqBMO&t_fXw)Bj+>k!3xLs_^UiIaWuCszwyoknop&{T?8y~_8^q{ zJIH-yoMD-G9}(lYN-n_0!FL8(X+pPpd;0nv01|Ip2f9A5u-uIGD*q_|W$}hm zm_(fjVdMn!)w9uW@WdDbznwnEeIRnuJAVr!i+NhgjU7o5^9=F_C+ml2QiczvGs}zD zK3G|-U$}H>848UVbzngP{EHx`!%e+yEh?A4)jeFjusNq__Tef)&-XLZ=@l<~wZ zd1>1V=@UM!kb8hzy=>q2cq|4dV2Q&guy;3 zZ=ilrieYfkK1`XUwZ+MeBYxobh3uzXTY~Azk9E(fH)FHTh59L_V=GtTfOvgTWIiO_7Yp z@zJS|!y9{lbbK88k$I55u`nibLxxdKxwk$P&w-;}3!59QO-7^eh51CJtRYNT^v*y< zCVB$!`#5EflOP}vIj8>8urQNSXSa=*gqIDSaT>s<-;IKHOU_HNEZHuS<8;)q7yd{& z2f{M;a;v1Ed5bj&uPQ!y(kn)Ac&4Q2RIlR!1>8oJy}vRfcbqsH_c}c$J8a21P87iGI!t zb-z?NMLbs={X<^%@DlN|pO>q=&@qi#yd3A{G%jfw@Rv6?N)#rYk?6CsT%*_7i|MZD z5-(SHS>i=rP`Ab}C#$2J+$Ds~!^rC;lU#7t6 zio0ri(abPIZJ+tB39>eW8-^A$_M6LTj`8vYF0`EDzrm&alVSn?X5`;wv0N+`E5%YV zKV2&CsZ3R#sysLSWM!(nul#JeQl2Rn%7w~fIM6pyDpckwbJNdN4pe3;hw+)jXQEQZ z|5Lb5RVLNJKVHju(?%Ipp;DBM-DTSx7EYsaSi5H4 zXXIaa=*3R3Ho#EOc?=iveP&<`eclGIN0B#`Kt}PBqU&l1keN##HUD%Mphc if+8)SQ$pgrgKshUvy5{+l{`K_^j~52S2^?V$o~b?uv4@E literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2deddae60614ba5ff3ce446297147e5f4c479172 GIT binary patch literal 23323 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 DYLoRR literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/common_descriptors.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/common_descriptors.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06172b1beff1e26c49275dc7fd175a580f461814 GIT binary patch literal 12205 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 WRdh9^Zu%a?50OFNOKZ;h_x=sK1%zY( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/request.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/request.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72a393c22387a420c4976156a372482a3658211e GIT binary patch literal 1825 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc b/venv/lib/python3.7/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..544dc1dc98989fbf68a359c634921fe124976efb GIT binary patch literal 853 zcmYjP&u`N(6tOb z%u(oY9J<15FxNP2HF))d_e#j?SY-NbvP`n-$2I4QFfu41PMJvz2-8|7!%_>PbE3zB zNHHsg(j*^FM5M`LoJ8X;0gLiXvm{fts$fzHP7D&UNF*QG#8Bo76Vzj-2|&lOkWdK7 z7G#Ug43Uc{WlCKPJ}-p4t3(<14W5Nl{T=zihDyI-0V-QFYMJ#KmU;w^W9}G*KY_yc z_#RE1H3nVX>hUd%6_rxLz8xbwCex;r=MkmSh$|0`Go$Xgjyal-Xu8_g9nW)Y l(0FOyLYbC5_aB0a>@)xX literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py new file mode 100644 index 0000000..d0620a0 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/accept.py @@ -0,0 +1,50 @@ +from ..datastructures import CharsetAccept +from ..datastructures import LanguageAccept +from ..datastructures import MIMEAccept +from ..http import parse_accept_header +from ..utils import cached_property + + +class AcceptMixin(object): + """A mixin for classes with an :attr:`~BaseResponse.environ` attribute + to get all the HTTP accept headers as + :class:`~werkzeug.datastructures.Accept` objects (or subclasses + thereof). + """ + + @cached_property + def accept_mimetypes(self): + """List of mimetypes this client supports as + :class:`~werkzeug.datastructures.MIMEAccept` object. + """ + return parse_accept_header(self.environ.get("HTTP_ACCEPT"), MIMEAccept) + + @cached_property + def accept_charsets(self): + """List of charsets this client supports as + :class:`~werkzeug.datastructures.CharsetAccept` object. + """ + return parse_accept_header( + self.environ.get("HTTP_ACCEPT_CHARSET"), CharsetAccept + ) + + @cached_property + def accept_encodings(self): + """List of encodings this client accepts. Encodings in a HTTP term + are compression encodings such as gzip. For charsets have a look at + :attr:`accept_charset`. + """ + return parse_accept_header(self.environ.get("HTTP_ACCEPT_ENCODING")) + + @cached_property + def accept_languages(self): + """List of languages this client accepts as + :class:`~werkzeug.datastructures.LanguageAccept` object. + + .. versionchanged 0.5 + In previous versions this was a regular + :class:`~werkzeug.datastructures.Accept` object. + """ + return parse_accept_header( + self.environ.get("HTTP_ACCEPT_LANGUAGE"), LanguageAccept + ) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py new file mode 100644 index 0000000..714f755 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/auth.py @@ -0,0 +1,33 @@ +from ..http import parse_authorization_header +from ..http import parse_www_authenticate_header +from ..utils import cached_property + + +class AuthorizationMixin(object): + """Adds an :attr:`authorization` property that represents the parsed + value of the `Authorization` header as + :class:`~werkzeug.datastructures.Authorization` object. + """ + + @cached_property + def authorization(self): + """The `Authorization` object in parsed form.""" + header = self.environ.get("HTTP_AUTHORIZATION") + return parse_authorization_header(header) + + +class WWWAuthenticateMixin(object): + """Adds a :attr:`www_authenticate` property to a response object.""" + + @property + def www_authenticate(self): + """The `WWW-Authenticate` header in a parsed form.""" + + def on_update(www_auth): + if not www_auth and "www-authenticate" in self.headers: + del self.headers["www-authenticate"] + elif www_auth: + self.headers["WWW-Authenticate"] = www_auth.to_header() + + header = self.headers.get("www-authenticate") + return parse_www_authenticate_header(header, on_update) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py new file mode 100644 index 0000000..41e8aad --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_request.py @@ -0,0 +1,693 @@ +import warnings +from functools import update_wrapper +from io import BytesIO + +from .._compat import to_native +from .._compat import to_unicode +from .._compat import wsgi_decoding_dance +from .._compat import wsgi_get_bytes +from ..datastructures import CombinedMultiDict +from ..datastructures import EnvironHeaders +from ..datastructures import ImmutableList +from ..datastructures import ImmutableMultiDict +from ..datastructures import ImmutableTypeConversionDict +from ..datastructures import iter_multi_items +from ..datastructures import MultiDict +from ..formparser import default_stream_factory +from ..formparser import FormDataParser +from ..http import parse_cookie +from ..http import parse_options_header +from ..urls import url_decode +from ..utils import cached_property +from ..utils import environ_property +from ..wsgi import get_content_length +from ..wsgi import get_current_url +from ..wsgi import get_host +from ..wsgi import get_input_stream + + +class BaseRequest(object): + """Very basic request object. This does not implement advanced stuff like + entity tag parsing or cache controls. The request object is created with + the WSGI environment as first argument and will add itself to the WSGI + environment as ``'werkzeug.request'`` unless it's created with + `populate_request` set to False. + + There are a couple of mixins available that add additional functionality + to the request object, there is also a class called `Request` which + subclasses `BaseRequest` and all the important mixins. + + It's a good idea to create a custom subclass of the :class:`BaseRequest` + and add missing functionality either via mixins or direct implementation. + Here an example for such subclasses:: + + from werkzeug.wrappers import BaseRequest, ETagRequestMixin + + class Request(BaseRequest, ETagRequestMixin): + pass + + Request objects are **read only**. As of 0.5 modifications are not + allowed in any place. Unlike the lower level parsing functions the + request object will use immutable objects everywhere possible. + + Per default the request object will assume all the text data is `utf-8` + encoded. Please refer to :doc:`the unicode chapter ` for more + details about customizing the behavior. + + Per default the request object will be added to the WSGI + environment as `werkzeug.request` to support the debugging system. + If you don't want that, set `populate_request` to `False`. + + If `shallow` is `True` the environment is initialized as shallow + object around the environ. Every operation that would modify the + environ in any way (such as consuming form data) raises an exception + unless the `shallow` attribute is explicitly set to `False`. This + is useful for middlewares where you don't want to consume the form + data by accident. A shallow request is not populated to the WSGI + environment. + + .. versionchanged:: 0.5 + read-only mode was enforced by using immutables classes for all + data. + """ + + #: the charset for the request, defaults to utf-8 + charset = "utf-8" + + #: the error handling procedure for errors, defaults to 'replace' + encoding_errors = "replace" + + #: the maximum content length. This is forwarded to the form data + #: parsing function (:func:`parse_form_data`). When set and the + #: :attr:`form` or :attr:`files` attribute is accessed and the + #: parsing fails because more than the specified value is transmitted + #: a :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. + #: + #: Have a look at :ref:`dealing-with-request-data` for more details. + #: + #: .. versionadded:: 0.5 + max_content_length = None + + #: the maximum form field size. This is forwarded to the form data + #: parsing function (:func:`parse_form_data`). When set and the + #: :attr:`form` or :attr:`files` attribute is accessed and the + #: data in memory for post data is longer than the specified value a + #: :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. + #: + #: Have a look at :ref:`dealing-with-request-data` for more details. + #: + #: .. versionadded:: 0.5 + max_form_memory_size = None + + #: the class to use for `args` and `form`. The default is an + #: :class:`~werkzeug.datastructures.ImmutableMultiDict` which supports + #: multiple values per key. alternatively it makes sense to use an + #: :class:`~werkzeug.datastructures.ImmutableOrderedMultiDict` which + #: preserves order or a :class:`~werkzeug.datastructures.ImmutableDict` + #: which is the fastest but only remembers the last key. It is also + #: possible to use mutable structures, but this is not recommended. + #: + #: .. versionadded:: 0.6 + parameter_storage_class = ImmutableMultiDict + + #: the type to be used for list values from the incoming WSGI environment. + #: By default an :class:`~werkzeug.datastructures.ImmutableList` is used + #: (for example for :attr:`access_list`). + #: + #: .. versionadded:: 0.6 + list_storage_class = ImmutableList + + #: the type to be used for dict values from the incoming WSGI environment. + #: By default an + #: :class:`~werkzeug.datastructures.ImmutableTypeConversionDict` is used + #: (for example for :attr:`cookies`). + #: + #: .. versionadded:: 0.6 + dict_storage_class = ImmutableTypeConversionDict + + #: The form data parser that shoud be used. Can be replaced to customize + #: the form date parsing. + form_data_parser_class = FormDataParser + + #: Optionally a list of hosts that is trusted by this request. By default + #: all hosts are trusted which means that whatever the client sends the + #: host is will be accepted. + #: + #: Because `Host` and `X-Forwarded-Host` headers can be set to any value by + #: a malicious client, it is recommended to either set this property or + #: implement similar validation in the proxy (if application is being run + #: behind one). + #: + #: .. versionadded:: 0.9 + trusted_hosts = None + + #: Indicates whether the data descriptor should be allowed to read and + #: buffer up the input stream. By default it's enabled. + #: + #: .. versionadded:: 0.9 + disable_data_descriptor = False + + def __init__(self, environ, populate_request=True, shallow=False): + self.environ = environ + if populate_request and not shallow: + self.environ["werkzeug.request"] = self + self.shallow = shallow + + def __repr__(self): + # make sure the __repr__ even works if the request was created + # from an invalid WSGI environment. If we display the request + # in a debug session we don't want the repr to blow up. + args = [] + try: + args.append("'%s'" % to_native(self.url, self.url_charset)) + args.append("[%s]" % self.method) + except Exception: + args.append("(invalid WSGI environ)") + + return "<%s %s>" % (self.__class__.__name__, " ".join(args)) + + @property + def url_charset(self): + """The charset that is assumed for URLs. Defaults to the value + of :attr:`charset`. + + .. versionadded:: 0.6 + """ + return self.charset + + @classmethod + def from_values(cls, *args, **kwargs): + """Create a new request object based on the values provided. If + environ is given missing values are filled from there. This method is + useful for small scripts when you need to simulate a request from an URL. + Do not use this method for unittesting, there is a full featured client + object (:class:`Client`) that allows to create multipart requests, + support for cookies etc. + + This accepts the same options as the + :class:`~werkzeug.test.EnvironBuilder`. + + .. versionchanged:: 0.5 + This method now accepts the same arguments as + :class:`~werkzeug.test.EnvironBuilder`. Because of this the + `environ` parameter is now called `environ_overrides`. + + :return: request object + """ + from ..test import EnvironBuilder + + charset = kwargs.pop("charset", cls.charset) + kwargs["charset"] = charset + builder = EnvironBuilder(*args, **kwargs) + try: + return builder.get_request(cls) + finally: + builder.close() + + @classmethod + def application(cls, f): + """Decorate a function as responder that accepts the request as first + argument. This works like the :func:`responder` decorator but the + function is passed the request object as first argument and the + request object will be closed automatically:: + + @Request.application + def my_wsgi_app(request): + return Response('Hello World!') + + As of Werkzeug 0.14 HTTP exceptions are automatically caught and + converted to responses instead of failing. + + :param f: the WSGI callable to decorate + :return: a new WSGI callable + """ + #: return a callable that wraps the -2nd argument with the request + #: and calls the function with all the arguments up to that one and + #: the request. The return value is then called with the latest + #: two arguments. This makes it possible to use this decorator for + #: both methods and standalone WSGI functions. + from ..exceptions import HTTPException + + def application(*args): + request = cls(args[-2]) + with request: + try: + resp = f(*args[:-2] + (request,)) + except HTTPException as e: + resp = e.get_response(args[-2]) + return resp(*args[-2:]) + + return update_wrapper(application, f) + + def _get_file_stream( + self, total_content_length, content_type, filename=None, content_length=None + ): + """Called to get a stream for the file upload. + + This must provide a file-like class with `read()`, `readline()` + and `seek()` methods that is both writeable and readable. + + The default implementation returns a temporary file if the total + content length is higher than 500KB. Because many browsers do not + provide a content length for the files only the total content + length matters. + + :param total_content_length: the total content length of all the + data in the request combined. This value + is guaranteed to be there. + :param content_type: the mimetype of the uploaded file. + :param filename: the filename of the uploaded file. May be `None`. + :param content_length: the length of this file. This value is usually + not provided because webbrowsers do not provide + this value. + """ + return default_stream_factory( + total_content_length=total_content_length, + filename=filename, + content_type=content_type, + content_length=content_length, + ) + + @property + def want_form_data_parsed(self): + """Returns True if the request method carries content. As of + Werkzeug 0.9 this will be the case if a content type is transmitted. + + .. versionadded:: 0.8 + """ + return bool(self.environ.get("CONTENT_TYPE")) + + def make_form_data_parser(self): + """Creates the form data parser. Instantiates the + :attr:`form_data_parser_class` with some parameters. + + .. versionadded:: 0.8 + """ + return self.form_data_parser_class( + self._get_file_stream, + self.charset, + self.encoding_errors, + self.max_form_memory_size, + self.max_content_length, + self.parameter_storage_class, + ) + + def _load_form_data(self): + """Method used internally to retrieve submitted data. After calling + this sets `form` and `files` on the request object to multi dicts + filled with the incoming form data. As a matter of fact the input + stream will be empty afterwards. You can also call this method to + force the parsing of the form data. + + .. versionadded:: 0.8 + """ + # abort early if we have already consumed the stream + if "form" in self.__dict__: + return + + _assert_not_shallow(self) + + if self.want_form_data_parsed: + content_type = self.environ.get("CONTENT_TYPE", "") + content_length = get_content_length(self.environ) + mimetype, options = parse_options_header(content_type) + parser = self.make_form_data_parser() + data = parser.parse( + self._get_stream_for_parsing(), mimetype, content_length, options + ) + else: + data = ( + self.stream, + self.parameter_storage_class(), + self.parameter_storage_class(), + ) + + # inject the values into the instance dict so that we bypass + # our cached_property non-data descriptor. + d = self.__dict__ + d["stream"], d["form"], d["files"] = data + + def _get_stream_for_parsing(self): + """This is the same as accessing :attr:`stream` with the difference + that if it finds cached data from calling :meth:`get_data` first it + will create a new stream out of the cached data. + + .. versionadded:: 0.9.3 + """ + cached_data = getattr(self, "_cached_data", None) + if cached_data is not None: + return BytesIO(cached_data) + return self.stream + + def close(self): + """Closes associated resources of this request object. This + closes all file handles explicitly. You can also use the request + object in a with statement which will automatically close it. + + .. versionadded:: 0.9 + """ + files = self.__dict__.get("files") + for _key, value in iter_multi_items(files or ()): + value.close() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + self.close() + + @cached_property + def stream(self): + """ + If the incoming form data was not encoded with a known mimetype + the data is stored unmodified in this stream for consumption. Most + of the time it is a better idea to use :attr:`data` which will give + you that data as a string. The stream only returns the data once. + + Unlike :attr:`input_stream` this stream is properly guarded that you + can't accidentally read past the length of the input. Werkzeug will + internally always refer to this stream to read data which makes it + possible to wrap this object with a stream that does filtering. + + .. versionchanged:: 0.9 + This stream is now always available but might be consumed by the + form parser later on. Previously the stream was only set if no + parsing happened. + """ + _assert_not_shallow(self) + return get_input_stream(self.environ) + + input_stream = environ_property( + "wsgi.input", + """The WSGI input stream. + + In general it's a bad idea to use this one because you can + easily read past the boundary. Use the :attr:`stream` + instead.""", + ) + + @cached_property + def args(self): + """The parsed URL parameters (the part in the URL after the question + mark). + + By default an + :class:`~werkzeug.datastructures.ImmutableMultiDict` + is returned from this function. This can be changed by setting + :attr:`parameter_storage_class` to a different type. This might + be necessary if the order of the form data is important. + """ + return url_decode( + wsgi_get_bytes(self.environ.get("QUERY_STRING", "")), + self.url_charset, + errors=self.encoding_errors, + cls=self.parameter_storage_class, + ) + + @cached_property + def data(self): + """ + Contains the incoming request data as string in case it came with + a mimetype Werkzeug does not handle. + """ + + if self.disable_data_descriptor: + raise AttributeError("data descriptor is disabled") + # XXX: this should eventually be deprecated. + + # We trigger form data parsing first which means that the descriptor + # will not cache the data that would otherwise be .form or .files + # data. This restores the behavior that was there in Werkzeug + # before 0.9. New code should use :meth:`get_data` explicitly as + # this will make behavior explicit. + return self.get_data(parse_form_data=True) + + def get_data(self, cache=True, as_text=False, parse_form_data=False): + """This reads the buffered incoming data from the client into one + bytestring. By default this is cached but that behavior can be + changed by setting `cache` to `False`. + + Usually it's a bad idea to call this method without checking the + content length first as a client could send dozens of megabytes or more + to cause memory problems on the server. + + Note that if the form data was already parsed this method will not + return anything as form data parsing does not cache the data like + this method does. To implicitly invoke form data parsing function + set `parse_form_data` to `True`. When this is done the return value + of this method will be an empty string if the form parser handles + the data. This generally is not necessary as if the whole data is + cached (which is the default) the form parser will used the cached + data to parse the form data. Please be generally aware of checking + the content length first in any case before calling this method + to avoid exhausting server memory. + + If `as_text` is set to `True` the return value will be a decoded + unicode string. + + .. versionadded:: 0.9 + """ + rv = getattr(self, "_cached_data", None) + if rv is None: + if parse_form_data: + self._load_form_data() + rv = self.stream.read() + if cache: + self._cached_data = rv + if as_text: + rv = rv.decode(self.charset, self.encoding_errors) + return rv + + @cached_property + def form(self): + """The form parameters. By default an + :class:`~werkzeug.datastructures.ImmutableMultiDict` + is returned from this function. This can be changed by setting + :attr:`parameter_storage_class` to a different type. This might + be necessary if the order of the form data is important. + + Please keep in mind that file uploads will not end up here, but instead + in the :attr:`files` attribute. + + .. versionchanged:: 0.9 + + Previous to Werkzeug 0.9 this would only contain form data for POST + and PUT requests. + """ + self._load_form_data() + return self.form + + @cached_property + def values(self): + """A :class:`werkzeug.datastructures.CombinedMultiDict` that combines + :attr:`args` and :attr:`form`.""" + args = [] + for d in self.args, self.form: + if not isinstance(d, MultiDict): + d = MultiDict(d) + args.append(d) + return CombinedMultiDict(args) + + @cached_property + def files(self): + """:class:`~werkzeug.datastructures.MultiDict` object containing + all uploaded files. Each key in :attr:`files` is the name from the + ````. Each value in :attr:`files` is a + Werkzeug :class:`~werkzeug.datastructures.FileStorage` object. + + It basically behaves like a standard file object you know from Python, + with the difference that it also has a + :meth:`~werkzeug.datastructures.FileStorage.save` function that can + store the file on the filesystem. + + Note that :attr:`files` will only contain data if the request method was + POST, PUT or PATCH and the ``

    `` that posted to the request had + ``enctype="multipart/form-data"``. It will be empty otherwise. + + See the :class:`~werkzeug.datastructures.MultiDict` / + :class:`~werkzeug.datastructures.FileStorage` documentation for + more details about the used data structure. + """ + self._load_form_data() + return self.files + + @cached_property + def cookies(self): + """A :class:`dict` with the contents of all cookies transmitted with + the request.""" + return parse_cookie( + self.environ, + self.charset, + self.encoding_errors, + cls=self.dict_storage_class, + ) + + @cached_property + def headers(self): + """The headers from the WSGI environ as immutable + :class:`~werkzeug.datastructures.EnvironHeaders`. + """ + return EnvironHeaders(self.environ) + + @cached_property + def path(self): + """Requested path as unicode. This works a bit like the regular path + info in the WSGI environment but will always include a leading slash, + even if the URL root is accessed. + """ + raw_path = wsgi_decoding_dance( + self.environ.get("PATH_INFO") or "", self.charset, self.encoding_errors + ) + return "/" + raw_path.lstrip("/") + + @cached_property + def full_path(self): + """Requested path as unicode, including the query string.""" + return self.path + u"?" + to_unicode(self.query_string, self.url_charset) + + @cached_property + def script_root(self): + """The root path of the script without the trailing slash.""" + raw_path = wsgi_decoding_dance( + self.environ.get("SCRIPT_NAME") or "", self.charset, self.encoding_errors + ) + return raw_path.rstrip("/") + + @cached_property + def url(self): + """The reconstructed current URL as IRI. + See also: :attr:`trusted_hosts`. + """ + return get_current_url(self.environ, trusted_hosts=self.trusted_hosts) + + @cached_property + def base_url(self): + """Like :attr:`url` but without the querystring + See also: :attr:`trusted_hosts`. + """ + return get_current_url( + self.environ, strip_querystring=True, trusted_hosts=self.trusted_hosts + ) + + @cached_property + def url_root(self): + """The full URL root (with hostname), this is the application + root as IRI. + See also: :attr:`trusted_hosts`. + """ + return get_current_url(self.environ, True, trusted_hosts=self.trusted_hosts) + + @cached_property + def host_url(self): + """Just the host with scheme as IRI. + See also: :attr:`trusted_hosts`. + """ + return get_current_url( + self.environ, host_only=True, trusted_hosts=self.trusted_hosts + ) + + @cached_property + def host(self): + """Just the host including the port if available. + See also: :attr:`trusted_hosts`. + """ + return get_host(self.environ, trusted_hosts=self.trusted_hosts) + + query_string = environ_property( + "QUERY_STRING", + "", + read_only=True, + load_func=wsgi_get_bytes, + doc="The URL parameters as raw bytestring.", + ) + method = environ_property( + "REQUEST_METHOD", + "GET", + read_only=True, + load_func=lambda x: x.upper(), + doc="The request method. (For example ``'GET'`` or ``'POST'``).", + ) + + @cached_property + def access_route(self): + """If a forwarded header exists this is a list of all ip addresses + from the client ip to the last proxy server. + """ + if "HTTP_X_FORWARDED_FOR" in self.environ: + addr = self.environ["HTTP_X_FORWARDED_FOR"].split(",") + return self.list_storage_class([x.strip() for x in addr]) + elif "REMOTE_ADDR" in self.environ: + return self.list_storage_class([self.environ["REMOTE_ADDR"]]) + return self.list_storage_class() + + @property + def remote_addr(self): + """The remote address of the client.""" + return self.environ.get("REMOTE_ADDR") + + remote_user = environ_property( + "REMOTE_USER", + doc="""If the server supports user authentication, and the + script is protected, this attribute contains the username the + user has authenticated as.""", + ) + + scheme = environ_property( + "wsgi.url_scheme", + doc=""" + URL scheme (http or https). + + .. versionadded:: 0.7""", + ) + + @property + def is_xhr(self): + """True if the request was triggered via a JavaScript XMLHttpRequest. + This only works with libraries that support the ``X-Requested-With`` + header and set it to "XMLHttpRequest". Libraries that do that are + prototype, jQuery and Mochikit and probably some more. + + .. deprecated:: 0.13 + ``X-Requested-With`` is not standard and is unreliable. You + may be able to use :attr:`AcceptMixin.accept_mimetypes` + instead. + """ + warnings.warn( + "'Request.is_xhr' is deprecated as of version 0.13 and will" + " be removed in version 1.0. The 'X-Requested-With' header" + " is not standard and is unreliable. You may be able to use" + " 'accept_mimetypes' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self.environ.get("HTTP_X_REQUESTED_WITH", "").lower() == "xmlhttprequest" + + is_secure = property( + lambda self: self.environ["wsgi.url_scheme"] == "https", + doc="`True` if the request is secure.", + ) + is_multithread = environ_property( + "wsgi.multithread", + doc="""boolean that is `True` if the application is served by a + multithreaded WSGI server.""", + ) + is_multiprocess = environ_property( + "wsgi.multiprocess", + doc="""boolean that is `True` if the application is served by a + WSGI server that spawns multiple processes.""", + ) + is_run_once = environ_property( + "wsgi.run_once", + doc="""boolean that is `True` if the application will be + executed only once in a process lifetime. This is the case for + CGI for example, but it's not guaranteed that the execution only + happens one time.""", + ) + + +def _assert_not_shallow(request): + if request.shallow: + raise RuntimeError( + "A shallow request tried to consume form data. If you really" + " want to do that, set `shallow` to False." + ) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py new file mode 100644 index 0000000..d944a7d --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py @@ -0,0 +1,702 @@ +import warnings + +from .._compat import integer_types +from .._compat import string_types +from .._compat import text_type +from .._compat import to_bytes +from .._compat import to_native +from ..datastructures import Headers +from ..http import dump_cookie +from ..http import HTTP_STATUS_CODES +from ..http import remove_entity_headers +from ..urls import iri_to_uri +from ..urls import url_join +from ..utils import get_content_type +from ..wsgi import ClosingIterator +from ..wsgi import get_current_url + + +def _run_wsgi_app(*args): + """This function replaces itself to ensure that the test module is not + imported unless required. DO NOT USE! + """ + global _run_wsgi_app + from ..test import run_wsgi_app as _run_wsgi_app + + return _run_wsgi_app(*args) + + +def _warn_if_string(iterable): + """Helper for the response objects to check if the iterable returned + to the WSGI server is not a string. + """ + if isinstance(iterable, string_types): + warnings.warn( + "Response iterable was set to a string. This will appear to" + " work but means that the server will send the data to the" + " client one character at a time. This is almost never" + " intended behavior, use 'response.data' to assign strings" + " to the response object.", + stacklevel=2, + ) + + +def _iter_encoded(iterable, charset): + for item in iterable: + if isinstance(item, text_type): + yield item.encode(charset) + else: + yield item + + +def _clean_accept_ranges(accept_ranges): + if accept_ranges is True: + return "bytes" + elif accept_ranges is False: + return "none" + elif isinstance(accept_ranges, text_type): + return to_native(accept_ranges) + raise ValueError("Invalid accept_ranges value") + + +class BaseResponse(object): + """Base response class. The most important fact about a response object + is that it's a regular WSGI application. It's initialized with a couple + of response parameters (headers, body, status code etc.) and will start a + valid WSGI response when called with the environ and start response + callable. + + Because it's a WSGI application itself processing usually ends before the + actual response is sent to the server. This helps debugging systems + because they can catch all the exceptions before responses are started. + + Here a small example WSGI application that takes advantage of the + response objects:: + + from werkzeug.wrappers import BaseResponse as Response + + def index(): + return Response('Index page') + + def application(environ, start_response): + path = environ.get('PATH_INFO') or '/' + if path == '/': + response = index() + else: + response = Response('Not Found', status=404) + return response(environ, start_response) + + Like :class:`BaseRequest` which object is lacking a lot of functionality + implemented in mixins. This gives you a better control about the actual + API of your response objects, so you can create subclasses and add custom + functionality. A full featured response object is available as + :class:`Response` which implements a couple of useful mixins. + + To enforce a new type of already existing responses you can use the + :meth:`force_type` method. This is useful if you're working with different + subclasses of response objects and you want to post process them with a + known interface. + + Per default the response object will assume all the text data is `utf-8` + encoded. Please refer to :doc:`the unicode chapter ` for more + details about customizing the behavior. + + Response can be any kind of iterable or string. If it's a string it's + considered being an iterable with one item which is the string passed. + Headers can be a list of tuples or a + :class:`~werkzeug.datastructures.Headers` object. + + Special note for `mimetype` and `content_type`: For most mime types + `mimetype` and `content_type` work the same, the difference affects + only 'text' mimetypes. If the mimetype passed with `mimetype` is a + mimetype starting with `text/`, the charset parameter of the response + object is appended to it. In contrast the `content_type` parameter is + always added as header unmodified. + + .. versionchanged:: 0.5 + the `direct_passthrough` parameter was added. + + :param response: a string or response iterable. + :param status: a string with a status or an integer with the status code. + :param headers: a list of headers or a + :class:`~werkzeug.datastructures.Headers` object. + :param mimetype: the mimetype for the response. See notice above. + :param content_type: the content type for the response. See notice above. + :param direct_passthrough: if set to `True` :meth:`iter_encoded` is not + called before iteration which makes it + possible to pass special iterators through + unchanged (see :func:`wrap_file` for more + details.) + """ + + #: the charset of the response. + charset = "utf-8" + + #: the default status if none is provided. + default_status = 200 + + #: the default mimetype if none is provided. + default_mimetype = "text/plain" + + #: if set to `False` accessing properties on the response object will + #: not try to consume the response iterator and convert it into a list. + #: + #: .. versionadded:: 0.6.2 + #: + #: That attribute was previously called `implicit_seqence_conversion`. + #: (Notice the typo). If you did use this feature, you have to adapt + #: your code to the name change. + implicit_sequence_conversion = True + + #: Should this response object correct the location header to be RFC + #: conformant? This is true by default. + #: + #: .. versionadded:: 0.8 + autocorrect_location_header = True + + #: Should this response object automatically set the content-length + #: header if possible? This is true by default. + #: + #: .. versionadded:: 0.8 + automatically_set_content_length = True + + #: Warn if a cookie header exceeds this size. The default, 4093, should be + #: safely `supported by most browsers `_. A cookie larger than + #: this size will still be sent, but it may be ignored or handled + #: incorrectly by some browsers. Set to 0 to disable this check. + #: + #: .. versionadded:: 0.13 + #: + #: .. _`cookie`: http://browsercookielimits.squawky.net/ + max_cookie_size = 4093 + + def __init__( + self, + response=None, + status=None, + headers=None, + mimetype=None, + content_type=None, + direct_passthrough=False, + ): + if isinstance(headers, Headers): + self.headers = headers + elif not headers: + self.headers = Headers() + else: + self.headers = Headers(headers) + + if content_type is None: + if mimetype is None and "content-type" not in self.headers: + mimetype = self.default_mimetype + if mimetype is not None: + mimetype = get_content_type(mimetype, self.charset) + content_type = mimetype + if content_type is not None: + self.headers["Content-Type"] = content_type + if status is None: + status = self.default_status + if isinstance(status, integer_types): + self.status_code = status + else: + self.status = status + + self.direct_passthrough = direct_passthrough + self._on_close = [] + + # we set the response after the headers so that if a class changes + # the charset attribute, the data is set in the correct charset. + if response is None: + self.response = [] + elif isinstance(response, (text_type, bytes, bytearray)): + self.set_data(response) + else: + self.response = response + + def call_on_close(self, func): + """Adds a function to the internal list of functions that should + be called as part of closing down the response. Since 0.7 this + function also returns the function that was passed so that this + can be used as a decorator. + + .. versionadded:: 0.6 + """ + self._on_close.append(func) + return func + + def __repr__(self): + if self.is_sequence: + body_info = "%d bytes" % sum(map(len, self.iter_encoded())) + else: + body_info = "streamed" if self.is_streamed else "likely-streamed" + return "<%s %s [%s]>" % (self.__class__.__name__, body_info, self.status) + + @classmethod + def force_type(cls, response, environ=None): + """Enforce that the WSGI response is a response object of the current + type. Werkzeug will use the :class:`BaseResponse` internally in many + situations like the exceptions. If you call :meth:`get_response` on an + exception you will get back a regular :class:`BaseResponse` object, even + if you are using a custom subclass. + + This method can enforce a given response type, and it will also + convert arbitrary WSGI callables into response objects if an environ + is provided:: + + # convert a Werkzeug response object into an instance of the + # MyResponseClass subclass. + response = MyResponseClass.force_type(response) + + # convert any WSGI application into a response object + response = MyResponseClass.force_type(response, environ) + + This is especially useful if you want to post-process responses in + the main dispatcher and use functionality provided by your subclass. + + Keep in mind that this will modify response objects in place if + possible! + + :param response: a response object or wsgi application. + :param environ: a WSGI environment object. + :return: a response object. + """ + if not isinstance(response, BaseResponse): + if environ is None: + raise TypeError( + "cannot convert WSGI application into response" + " objects without an environ" + ) + response = BaseResponse(*_run_wsgi_app(response, environ)) + response.__class__ = cls + return response + + @classmethod + def from_app(cls, app, environ, buffered=False): + """Create a new response object from an application output. This + works best if you pass it an application that returns a generator all + the time. Sometimes applications may use the `write()` callable + returned by the `start_response` function. This tries to resolve such + edge cases automatically. But if you don't get the expected output + you should set `buffered` to `True` which enforces buffering. + + :param app: the WSGI application to execute. + :param environ: the WSGI environment to execute against. + :param buffered: set to `True` to enforce buffering. + :return: a response object. + """ + return cls(*_run_wsgi_app(app, environ, buffered)) + + def _get_status_code(self): + return self._status_code + + def _set_status_code(self, code): + self._status_code = code + try: + self._status = "%d %s" % (code, HTTP_STATUS_CODES[code].upper()) + except KeyError: + self._status = "%d UNKNOWN" % code + + status_code = property( + _get_status_code, _set_status_code, doc="The HTTP Status code as number" + ) + del _get_status_code, _set_status_code + + def _get_status(self): + return self._status + + def _set_status(self, value): + try: + self._status = to_native(value) + except AttributeError: + raise TypeError("Invalid status argument") + + try: + self._status_code = int(self._status.split(None, 1)[0]) + except ValueError: + self._status_code = 0 + self._status = "0 %s" % self._status + except IndexError: + raise ValueError("Empty status argument") + + status = property(_get_status, _set_status, doc="The HTTP Status code") + del _get_status, _set_status + + def get_data(self, as_text=False): + """The string representation of the request body. Whenever you call + this property the request iterable is encoded and flattened. This + can lead to unwanted behavior if you stream big data. + + This behavior can be disabled by setting + :attr:`implicit_sequence_conversion` to `False`. + + If `as_text` is set to `True` the return value will be a decoded + unicode string. + + .. versionadded:: 0.9 + """ + self._ensure_sequence() + rv = b"".join(self.iter_encoded()) + if as_text: + rv = rv.decode(self.charset) + return rv + + def set_data(self, value): + """Sets a new string as response. The value set must either by a + unicode or bytestring. If a unicode string is set it's encoded + automatically to the charset of the response (utf-8 by default). + + .. versionadded:: 0.9 + """ + # if an unicode string is set, it's encoded directly so that we + # can set the content length + if isinstance(value, text_type): + value = value.encode(self.charset) + else: + value = bytes(value) + self.response = [value] + if self.automatically_set_content_length: + self.headers["Content-Length"] = str(len(value)) + + data = property( + get_data, + set_data, + doc="A descriptor that calls :meth:`get_data` and :meth:`set_data`.", + ) + + def calculate_content_length(self): + """Returns the content length if available or `None` otherwise.""" + try: + self._ensure_sequence() + except RuntimeError: + return None + return sum(len(x) for x in self.iter_encoded()) + + def _ensure_sequence(self, mutable=False): + """This method can be called by methods that need a sequence. If + `mutable` is true, it will also ensure that the response sequence + is a standard Python list. + + .. versionadded:: 0.6 + """ + if self.is_sequence: + # if we need a mutable object, we ensure it's a list. + if mutable and not isinstance(self.response, list): + self.response = list(self.response) + return + if self.direct_passthrough: + raise RuntimeError( + "Attempted implicit sequence conversion but the" + " response object is in direct passthrough mode." + ) + if not self.implicit_sequence_conversion: + raise RuntimeError( + "The response object required the iterable to be a" + " sequence, but the implicit conversion was disabled." + " Call make_sequence() yourself." + ) + self.make_sequence() + + def make_sequence(self): + """Converts the response iterator in a list. By default this happens + automatically if required. If `implicit_sequence_conversion` is + disabled, this method is not automatically called and some properties + might raise exceptions. This also encodes all the items. + + .. versionadded:: 0.6 + """ + if not self.is_sequence: + # if we consume an iterable we have to ensure that the close + # method of the iterable is called if available when we tear + # down the response + close = getattr(self.response, "close", None) + self.response = list(self.iter_encoded()) + if close is not None: + self.call_on_close(close) + + def iter_encoded(self): + """Iter the response encoded with the encoding of the response. + If the response object is invoked as WSGI application the return + value of this method is used as application iterator unless + :attr:`direct_passthrough` was activated. + """ + if __debug__: + _warn_if_string(self.response) + # Encode in a separate function so that self.response is fetched + # early. This allows us to wrap the response with the return + # value from get_app_iter or iter_encoded. + return _iter_encoded(self.response, self.charset) + + def set_cookie( + self, + key, + value="", + max_age=None, + expires=None, + path="/", + domain=None, + secure=False, + httponly=False, + samesite=None, + ): + """Sets a cookie. The parameters are the same as in the cookie `Morsel` + object in the Python standard library but it accepts unicode data, too. + + A warning is raised if the size of the cookie header exceeds + :attr:`max_cookie_size`, but the header will still be set. + + :param key: the key (name) of the cookie to be set. + :param value: the value of the cookie. + :param max_age: should be a number of seconds, or `None` (default) if + the cookie should last only as long as the client's + browser session. + :param expires: should be a `datetime` object or UNIX timestamp. + :param path: limits the cookie to a given path, per default it will + span the whole domain. + :param domain: if you want to set a cross-domain cookie. For example, + ``domain=".example.com"`` will set a cookie that is + readable by the domain ``www.example.com``, + ``foo.example.com`` etc. Otherwise, a cookie will only + be readable by the domain that set it. + :param secure: If `True`, the cookie will only be available via HTTPS + :param httponly: disallow JavaScript to access the cookie. This is an + extension to the cookie standard and probably not + supported by all browsers. + :param samesite: Limits the scope of the cookie such that it will only + be attached to requests if those requests are + "same-site". + """ + self.headers.add( + "Set-Cookie", + dump_cookie( + key, + value=value, + max_age=max_age, + expires=expires, + path=path, + domain=domain, + secure=secure, + httponly=httponly, + charset=self.charset, + max_size=self.max_cookie_size, + samesite=samesite, + ), + ) + + def delete_cookie(self, key, path="/", domain=None): + """Delete a cookie. Fails silently if key doesn't exist. + + :param key: the key (name) of the cookie to be deleted. + :param path: if the cookie that should be deleted was limited to a + path, the path has to be defined here. + :param domain: if the cookie that should be deleted was limited to a + domain, that domain has to be defined here. + """ + self.set_cookie(key, expires=0, max_age=0, path=path, domain=domain) + + @property + def is_streamed(self): + """If the response is streamed (the response is not an iterable with + a length information) this property is `True`. In this case streamed + means that there is no information about the number of iterations. + This is usually `True` if a generator is passed to the response object. + + This is useful for checking before applying some sort of post + filtering that should not take place for streamed responses. + """ + try: + len(self.response) + except (TypeError, AttributeError): + return True + return False + + @property + def is_sequence(self): + """If the iterator is buffered, this property will be `True`. A + response object will consider an iterator to be buffered if the + response attribute is a list or tuple. + + .. versionadded:: 0.6 + """ + return isinstance(self.response, (tuple, list)) + + def close(self): + """Close the wrapped response if possible. You can also use the object + in a with statement which will automatically close it. + + .. versionadded:: 0.9 + Can now be used in a with statement. + """ + if hasattr(self.response, "close"): + self.response.close() + for func in self._on_close: + func() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + self.close() + + def freeze(self): + """Call this method if you want to make your response object ready for + being pickled. This buffers the generator if there is one. It will + also set the `Content-Length` header to the length of the body. + + .. versionchanged:: 0.6 + The `Content-Length` header is now set. + """ + # we explicitly set the length to a list of the *encoded* response + # iterator. Even if the implicit sequence conversion is disabled. + self.response = list(self.iter_encoded()) + self.headers["Content-Length"] = str(sum(map(len, self.response))) + + def get_wsgi_headers(self, environ): + """This is automatically called right before the response is started + and returns headers modified for the given environment. It returns a + copy of the headers from the response with some modifications applied + if necessary. + + For example the location header (if present) is joined with the root + URL of the environment. Also the content length is automatically set + to zero here for certain status codes. + + .. versionchanged:: 0.6 + Previously that function was called `fix_headers` and modified + the response object in place. Also since 0.6, IRIs in location + and content-location headers are handled properly. + + Also starting with 0.6, Werkzeug will attempt to set the content + length if it is able to figure it out on its own. This is the + case if all the strings in the response iterable are already + encoded and the iterable is buffered. + + :param environ: the WSGI environment of the request. + :return: returns a new :class:`~werkzeug.datastructures.Headers` + object. + """ + headers = Headers(self.headers) + location = None + content_location = None + content_length = None + status = self.status_code + + # iterate over the headers to find all values in one go. Because + # get_wsgi_headers is used each response that gives us a tiny + # speedup. + for key, value in headers: + ikey = key.lower() + if ikey == u"location": + location = value + elif ikey == u"content-location": + content_location = value + elif ikey == u"content-length": + content_length = value + + # make sure the location header is an absolute URL + if location is not None: + old_location = location + if isinstance(location, text_type): + # Safe conversion is necessary here as we might redirect + # to a broken URI scheme (for instance itms-services). + location = iri_to_uri(location, safe_conversion=True) + + if self.autocorrect_location_header: + current_url = get_current_url(environ, strip_querystring=True) + if isinstance(current_url, text_type): + current_url = iri_to_uri(current_url) + location = url_join(current_url, location) + if location != old_location: + headers["Location"] = location + + # make sure the content location is a URL + if content_location is not None and isinstance(content_location, text_type): + headers["Content-Location"] = iri_to_uri(content_location) + + if 100 <= status < 200 or status == 204: + # Per section 3.3.2 of RFC 7230, "a server MUST NOT send a + # Content-Length header field in any response with a status + # code of 1xx (Informational) or 204 (No Content)." + headers.remove("Content-Length") + elif status == 304: + remove_entity_headers(headers) + + # if we can determine the content length automatically, we + # should try to do that. But only if this does not involve + # flattening the iterator or encoding of unicode strings in + # the response. We however should not do that if we have a 304 + # response. + if ( + self.automatically_set_content_length + and self.is_sequence + and content_length is None + and status not in (204, 304) + and not (100 <= status < 200) + ): + try: + content_length = sum(len(to_bytes(x, "ascii")) for x in self.response) + except UnicodeError: + # aha, something non-bytestringy in there, too bad, we + # can't safely figure out the length of the response. + pass + else: + headers["Content-Length"] = str(content_length) + + return headers + + def get_app_iter(self, environ): + """Returns the application iterator for the given environ. Depending + on the request method and the current status code the return value + might be an empty response rather than the one from the response. + + If the request method is `HEAD` or the status code is in a range + where the HTTP specification requires an empty response, an empty + iterable is returned. + + .. versionadded:: 0.6 + + :param environ: the WSGI environment of the request. + :return: a response iterable. + """ + status = self.status_code + if ( + environ["REQUEST_METHOD"] == "HEAD" + or 100 <= status < 200 + or status in (204, 304) + ): + iterable = () + elif self.direct_passthrough: + if __debug__: + _warn_if_string(self.response) + return self.response + else: + iterable = self.iter_encoded() + return ClosingIterator(iterable, self.close) + + def get_wsgi_response(self, environ): + """Returns the final WSGI response as tuple. The first item in + the tuple is the application iterator, the second the status and + the third the list of headers. The response returned is created + specially for the given environment. For example if the request + method in the WSGI environment is ``'HEAD'`` the response will + be empty and only the headers and status code will be present. + + .. versionadded:: 0.6 + + :param environ: the WSGI environment of the request. + :return: an ``(app_iter, status, headers)`` tuple. + """ + headers = self.get_wsgi_headers(environ) + app_iter = self.get_app_iter(environ) + return app_iter, self.status, headers.to_wsgi_list() + + def __call__(self, environ, start_response): + """Process this response as WSGI application. + + :param environ: the WSGI environment. + :param start_response: the response callable provided by the WSGI + server. + :return: an application iterator + """ + app_iter, status, headers = self.get_wsgi_response(environ) + start_response(status, headers) + return app_iter diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py new file mode 100644 index 0000000..e4107ee --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/common_descriptors.py @@ -0,0 +1,322 @@ +from datetime import datetime +from datetime import timedelta + +from .._compat import string_types +from ..datastructures import CallbackDict +from ..http import dump_age +from ..http import dump_header +from ..http import dump_options_header +from ..http import http_date +from ..http import parse_age +from ..http import parse_date +from ..http import parse_options_header +from ..http import parse_set_header +from ..utils import cached_property +from ..utils import environ_property +from ..utils import get_content_type +from ..utils import header_property +from ..wsgi import get_content_length + + +class CommonRequestDescriptorsMixin(object): + """A mixin for :class:`BaseRequest` subclasses. Request objects that + mix this class in will automatically get descriptors for a couple of + HTTP headers with automatic type conversion. + + .. versionadded:: 0.5 + """ + + content_type = environ_property( + "CONTENT_TYPE", + doc="""The Content-Type entity-header field indicates the media + type of the entity-body sent to the recipient or, in the case of + the HEAD method, the media type that would have been sent had + the request been a GET.""", + ) + + @cached_property + def content_length(self): + """The Content-Length entity-header field indicates the size of the + entity-body in bytes or, in the case of the HEAD method, the size of + the entity-body that would have been sent had the request been a + GET. + """ + return get_content_length(self.environ) + + content_encoding = environ_property( + "HTTP_CONTENT_ENCODING", + doc="""The Content-Encoding entity-header field is used as a + modifier to the media-type. When present, its value indicates + what additional content codings have been applied to the + entity-body, and thus what decoding mechanisms must be applied + in order to obtain the media-type referenced by the Content-Type + header field. + + .. versionadded:: 0.9""", + ) + content_md5 = environ_property( + "HTTP_CONTENT_MD5", + doc="""The Content-MD5 entity-header field, as defined in + RFC 1864, is an MD5 digest of the entity-body for the purpose of + providing an end-to-end message integrity check (MIC) of the + entity-body. (Note: a MIC is good for detecting accidental + modification of the entity-body in transit, but is not proof + against malicious attacks.) + + .. versionadded:: 0.9""", + ) + referrer = environ_property( + "HTTP_REFERER", + doc="""The Referer[sic] request-header field allows the client + to specify, for the server's benefit, the address (URI) of the + resource from which the Request-URI was obtained (the + "referrer", although the header field is misspelled).""", + ) + date = environ_property( + "HTTP_DATE", + None, + parse_date, + doc="""The Date general-header field represents the date and + time at which the message was originated, having the same + semantics as orig-date in RFC 822.""", + ) + max_forwards = environ_property( + "HTTP_MAX_FORWARDS", + None, + int, + doc="""The Max-Forwards request-header field provides a + mechanism with the TRACE and OPTIONS methods to limit the number + of proxies or gateways that can forward the request to the next + inbound server.""", + ) + + def _parse_content_type(self): + if not hasattr(self, "_parsed_content_type"): + self._parsed_content_type = parse_options_header( + self.environ.get("CONTENT_TYPE", "") + ) + + @property + def mimetype(self): + """Like :attr:`content_type`, but without parameters (eg, without + charset, type etc.) and always lowercase. For example if the content + type is ``text/HTML; charset=utf-8`` the mimetype would be + ``'text/html'``. + """ + self._parse_content_type() + return self._parsed_content_type[0].lower() + + @property + def mimetype_params(self): + """The mimetype parameters as dict. For example if the content + type is ``text/html; charset=utf-8`` the params would be + ``{'charset': 'utf-8'}``. + """ + self._parse_content_type() + return self._parsed_content_type[1] + + @cached_property + def pragma(self): + """The Pragma general-header field is used to include + implementation-specific directives that might apply to any recipient + along the request/response chain. All pragma directives specify + optional behavior from the viewpoint of the protocol; however, some + systems MAY require that behavior be consistent with the directives. + """ + return parse_set_header(self.environ.get("HTTP_PRAGMA", "")) + + +class CommonResponseDescriptorsMixin(object): + """A mixin for :class:`BaseResponse` subclasses. Response objects that + mix this class in will automatically get descriptors for a couple of + HTTP headers with automatic type conversion. + """ + + @property + def mimetype(self): + """The mimetype (content type without charset etc.)""" + ct = self.headers.get("content-type") + if ct: + return ct.split(";")[0].strip() + + @mimetype.setter + def mimetype(self, value): + self.headers["Content-Type"] = get_content_type(value, self.charset) + + @property + def mimetype_params(self): + """The mimetype parameters as dict. For example if the + content type is ``text/html; charset=utf-8`` the params would be + ``{'charset': 'utf-8'}``. + + .. versionadded:: 0.5 + """ + + def on_update(d): + self.headers["Content-Type"] = dump_options_header(self.mimetype, d) + + d = parse_options_header(self.headers.get("content-type", ""))[1] + return CallbackDict(d, on_update) + + location = header_property( + "Location", + doc="""The Location response-header field is used to redirect + the recipient to a location other than the Request-URI for + completion of the request or identification of a new + resource.""", + ) + age = header_property( + "Age", + None, + parse_age, + dump_age, + doc="""The Age response-header field conveys the sender's + estimate of the amount of time since the response (or its + revalidation) was generated at the origin server. + + Age values are non-negative decimal integers, representing time + in seconds.""", + ) + content_type = header_property( + "Content-Type", + doc="""The Content-Type entity-header field indicates the media + type of the entity-body sent to the recipient or, in the case of + the HEAD method, the media type that would have been sent had + the request been a GET.""", + ) + content_length = header_property( + "Content-Length", + None, + int, + str, + doc="""The Content-Length entity-header field indicates the size + of the entity-body, in decimal number of OCTETs, sent to the + recipient or, in the case of the HEAD method, the size of the + entity-body that would have been sent had the request been a + GET.""", + ) + content_location = header_property( + "Content-Location", + doc="""The Content-Location entity-header field MAY be used to + supply the resource location for the entity enclosed in the + message when that entity is accessible from a location separate + from the requested resource's URI.""", + ) + content_encoding = header_property( + "Content-Encoding", + doc="""The Content-Encoding entity-header field is used as a + modifier to the media-type. When present, its value indicates + what additional content codings have been applied to the + entity-body, and thus what decoding mechanisms must be applied + in order to obtain the media-type referenced by the Content-Type + header field.""", + ) + content_md5 = header_property( + "Content-MD5", + doc="""The Content-MD5 entity-header field, as defined in + RFC 1864, is an MD5 digest of the entity-body for the purpose of + providing an end-to-end message integrity check (MIC) of the + entity-body. (Note: a MIC is good for detecting accidental + modification of the entity-body in transit, but is not proof + against malicious attacks.)""", + ) + date = header_property( + "Date", + None, + parse_date, + http_date, + doc="""The Date general-header field represents the date and + time at which the message was originated, having the same + semantics as orig-date in RFC 822.""", + ) + expires = header_property( + "Expires", + None, + parse_date, + http_date, + doc="""The Expires entity-header field gives the date/time after + which the response is considered stale. A stale cache entry may + not normally be returned by a cache.""", + ) + last_modified = header_property( + "Last-Modified", + None, + parse_date, + http_date, + doc="""The Last-Modified entity-header field indicates the date + and time at which the origin server believes the variant was + last modified.""", + ) + + @property + def retry_after(self): + """The Retry-After response-header field can be used with a + 503 (Service Unavailable) response to indicate how long the + service is expected to be unavailable to the requesting client. + + Time in seconds until expiration or date. + """ + value = self.headers.get("retry-after") + if value is None: + return + elif value.isdigit(): + return datetime.utcnow() + timedelta(seconds=int(value)) + return parse_date(value) + + @retry_after.setter + def retry_after(self, value): + if value is None: + if "retry-after" in self.headers: + del self.headers["retry-after"] + return + elif isinstance(value, datetime): + value = http_date(value) + else: + value = str(value) + self.headers["Retry-After"] = value + + def _set_property(name, doc=None): # noqa: B902 + def fget(self): + def on_update(header_set): + if not header_set and name in self.headers: + del self.headers[name] + elif header_set: + self.headers[name] = header_set.to_header() + + return parse_set_header(self.headers.get(name), on_update) + + def fset(self, value): + if not value: + del self.headers[name] + elif isinstance(value, string_types): + self.headers[name] = value + else: + self.headers[name] = dump_header(value) + + return property(fget, fset, doc=doc) + + vary = _set_property( + "Vary", + doc="""The Vary field value indicates the set of request-header + fields that fully determines, while the response is fresh, + whether a cache is permitted to use the response to reply to a + subsequent request without revalidation.""", + ) + content_language = _set_property( + "Content-Language", + doc="""The Content-Language entity-header field describes the + natural language(s) of the intended audience for the enclosed + entity. Note that this might not be equivalent to all the + languages used within the entity-body.""", + ) + allow = _set_property( + "Allow", + doc="""The Allow entity-header field lists the set of methods + supported by the resource identified by the Request-URI. The + purpose of this field is strictly to inform the recipient of + valid methods associated with the resource. An Allow header + field MUST be present in a 405 (Method Not Allowed) + response.""", + ) + + del _set_property diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py new file mode 100644 index 0000000..0733506 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/etag.py @@ -0,0 +1,304 @@ +from .._compat import string_types +from .._internal import _get_environ +from ..datastructures import ContentRange +from ..datastructures import RequestCacheControl +from ..datastructures import ResponseCacheControl +from ..http import generate_etag +from ..http import http_date +from ..http import is_resource_modified +from ..http import parse_cache_control_header +from ..http import parse_content_range_header +from ..http import parse_date +from ..http import parse_etags +from ..http import parse_if_range_header +from ..http import parse_range_header +from ..http import quote_etag +from ..http import unquote_etag +from ..utils import cached_property +from ..utils import header_property +from ..wrappers.base_response import _clean_accept_ranges +from ..wsgi import _RangeWrapper + + +class ETagRequestMixin(object): + """Add entity tag and cache descriptors to a request object or object with + a WSGI environment available as :attr:`~BaseRequest.environ`. This not + only provides access to etags but also to the cache control header. + """ + + @cached_property + def cache_control(self): + """A :class:`~werkzeug.datastructures.RequestCacheControl` object + for the incoming cache control headers. + """ + cache_control = self.environ.get("HTTP_CACHE_CONTROL") + return parse_cache_control_header(cache_control, None, RequestCacheControl) + + @cached_property + def if_match(self): + """An object containing all the etags in the `If-Match` header. + + :rtype: :class:`~werkzeug.datastructures.ETags` + """ + return parse_etags(self.environ.get("HTTP_IF_MATCH")) + + @cached_property + def if_none_match(self): + """An object containing all the etags in the `If-None-Match` header. + + :rtype: :class:`~werkzeug.datastructures.ETags` + """ + return parse_etags(self.environ.get("HTTP_IF_NONE_MATCH")) + + @cached_property + def if_modified_since(self): + """The parsed `If-Modified-Since` header as datetime object.""" + return parse_date(self.environ.get("HTTP_IF_MODIFIED_SINCE")) + + @cached_property + def if_unmodified_since(self): + """The parsed `If-Unmodified-Since` header as datetime object.""" + return parse_date(self.environ.get("HTTP_IF_UNMODIFIED_SINCE")) + + @cached_property + def if_range(self): + """The parsed `If-Range` header. + + .. versionadded:: 0.7 + + :rtype: :class:`~werkzeug.datastructures.IfRange` + """ + return parse_if_range_header(self.environ.get("HTTP_IF_RANGE")) + + @cached_property + def range(self): + """The parsed `Range` header. + + .. versionadded:: 0.7 + + :rtype: :class:`~werkzeug.datastructures.Range` + """ + return parse_range_header(self.environ.get("HTTP_RANGE")) + + +class ETagResponseMixin(object): + """Adds extra functionality to a response object for etag and cache + handling. This mixin requires an object with at least a `headers` + object that implements a dict like interface similar to + :class:`~werkzeug.datastructures.Headers`. + + If you want the :meth:`freeze` method to automatically add an etag, you + have to mixin this method before the response base class. The default + response class does not do that. + """ + + @property + def cache_control(self): + """The Cache-Control general-header field is used to specify + directives that MUST be obeyed by all caching mechanisms along the + request/response chain. + """ + + def on_update(cache_control): + if not cache_control and "cache-control" in self.headers: + del self.headers["cache-control"] + elif cache_control: + self.headers["Cache-Control"] = cache_control.to_header() + + return parse_cache_control_header( + self.headers.get("cache-control"), on_update, ResponseCacheControl + ) + + def _wrap_response(self, start, length): + """Wrap existing Response in case of Range Request context.""" + if self.status_code == 206: + self.response = _RangeWrapper(self.response, start, length) + + def _is_range_request_processable(self, environ): + """Return ``True`` if `Range` header is present and if underlying + resource is considered unchanged when compared with `If-Range` header. + """ + return ( + "HTTP_IF_RANGE" not in environ + or not is_resource_modified( + environ, + self.headers.get("etag"), + None, + self.headers.get("last-modified"), + ignore_if_range=False, + ) + ) and "HTTP_RANGE" in environ + + def _process_range_request(self, environ, complete_length=None, accept_ranges=None): + """Handle Range Request related headers (RFC7233). If `Accept-Ranges` + header is valid, and Range Request is processable, we set the headers + as described by the RFC, and wrap the underlying response in a + RangeWrapper. + + Returns ``True`` if Range Request can be fulfilled, ``False`` otherwise. + + :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` + if `Range` header could not be parsed or satisfied. + """ + from ..exceptions import RequestedRangeNotSatisfiable + + if accept_ranges is None: + return False + self.headers["Accept-Ranges"] = accept_ranges + if not self._is_range_request_processable(environ) or complete_length is None: + return False + parsed_range = parse_range_header(environ.get("HTTP_RANGE")) + if parsed_range is None: + raise RequestedRangeNotSatisfiable(complete_length) + range_tuple = parsed_range.range_for_length(complete_length) + content_range_header = parsed_range.to_content_range_header(complete_length) + if range_tuple is None or content_range_header is None: + raise RequestedRangeNotSatisfiable(complete_length) + content_length = range_tuple[1] - range_tuple[0] + # Be sure not to send 206 response + # if requested range is the full content. + if content_length != complete_length: + self.headers["Content-Length"] = content_length + self.content_range = content_range_header + self.status_code = 206 + self._wrap_response(range_tuple[0], content_length) + return True + return False + + def make_conditional( + self, request_or_environ, accept_ranges=False, complete_length=None + ): + """Make the response conditional to the request. This method works + best if an etag was defined for the response already. The `add_etag` + method can be used to do that. If called without etag just the date + header is set. + + This does nothing if the request method in the request or environ is + anything but GET or HEAD. + + For optimal performance when handling range requests, it's recommended + that your response data object implements `seekable`, `seek` and `tell` + methods as described by :py:class:`io.IOBase`. Objects returned by + :meth:`~werkzeug.wsgi.wrap_file` automatically implement those methods. + + It does not remove the body of the response because that's something + the :meth:`__call__` function does for us automatically. + + Returns self so that you can do ``return resp.make_conditional(req)`` + but modifies the object in-place. + + :param request_or_environ: a request object or WSGI environment to be + used to make the response conditional + against. + :param accept_ranges: This parameter dictates the value of + `Accept-Ranges` header. If ``False`` (default), + the header is not set. If ``True``, it will be set + to ``"bytes"``. If ``None``, it will be set to + ``"none"``. If it's a string, it will use this + value. + :param complete_length: Will be used only in valid Range Requests. + It will set `Content-Range` complete length + value and compute `Content-Length` real value. + This parameter is mandatory for successful + Range Requests completion. + :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` + if `Range` header could not be parsed or satisfied. + """ + environ = _get_environ(request_or_environ) + if environ["REQUEST_METHOD"] in ("GET", "HEAD"): + # if the date is not in the headers, add it now. We however + # will not override an already existing header. Unfortunately + # this header will be overriden by many WSGI servers including + # wsgiref. + if "date" not in self.headers: + self.headers["Date"] = http_date() + accept_ranges = _clean_accept_ranges(accept_ranges) + is206 = self._process_range_request(environ, complete_length, accept_ranges) + if not is206 and not is_resource_modified( + environ, + self.headers.get("etag"), + None, + self.headers.get("last-modified"), + ): + if parse_etags(environ.get("HTTP_IF_MATCH")): + self.status_code = 412 + else: + self.status_code = 304 + if ( + self.automatically_set_content_length + and "content-length" not in self.headers + ): + length = self.calculate_content_length() + if length is not None: + self.headers["Content-Length"] = length + return self + + def add_etag(self, overwrite=False, weak=False): + """Add an etag for the current response if there is none yet.""" + if overwrite or "etag" not in self.headers: + self.set_etag(generate_etag(self.get_data()), weak) + + def set_etag(self, etag, weak=False): + """Set the etag, and override the old one if there was one.""" + self.headers["ETag"] = quote_etag(etag, weak) + + def get_etag(self): + """Return a tuple in the form ``(etag, is_weak)``. If there is no + ETag the return value is ``(None, None)``. + """ + return unquote_etag(self.headers.get("ETag")) + + def freeze(self, no_etag=False): + """Call this method if you want to make your response object ready for + pickeling. This buffers the generator if there is one. This also + sets the etag unless `no_etag` is set to `True`. + """ + if not no_etag: + self.add_etag() + super(ETagResponseMixin, self).freeze() + + accept_ranges = header_property( + "Accept-Ranges", + doc="""The `Accept-Ranges` header. Even though the name would + indicate that multiple values are supported, it must be one + string token only. + + The values ``'bytes'`` and ``'none'`` are common. + + .. versionadded:: 0.7""", + ) + + def _get_content_range(self): + def on_update(rng): + if not rng: + del self.headers["content-range"] + else: + self.headers["Content-Range"] = rng.to_header() + + rv = parse_content_range_header(self.headers.get("content-range"), on_update) + # always provide a content range object to make the descriptor + # more user friendly. It provides an unset() method that can be + # used to remove the header quickly. + if rv is None: + rv = ContentRange(None, None, None, on_update=on_update) + return rv + + def _set_content_range(self, value): + if not value: + del self.headers["content-range"] + elif isinstance(value, string_types): + self.headers["Content-Range"] = value + else: + self.headers["Content-Range"] = value.to_header() + + content_range = property( + _get_content_range, + _set_content_range, + doc="""The ``Content-Range`` header as + :class:`~werkzeug.datastructures.ContentRange` object. Even if + the header is not set it wil provide such an object for easier + manipulation. + + .. versionadded:: 0.7""", + ) + del _get_content_range, _set_content_range diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py new file mode 100644 index 0000000..6d5dc33 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/json.py @@ -0,0 +1,145 @@ +from __future__ import absolute_import + +import datetime +import uuid + +from .._compat import text_type +from ..exceptions import BadRequest +from ..utils import detect_utf_encoding + +try: + import simplejson as _json +except ImportError: + import json as _json + + +class _JSONModule(object): + @staticmethod + def _default(o): + if isinstance(o, datetime.date): + return o.isoformat() + + if isinstance(o, uuid.UUID): + return str(o) + + if hasattr(o, "__html__"): + return text_type(o.__html__()) + + raise TypeError() + + @classmethod + def dumps(cls, obj, **kw): + kw.setdefault("separators", (",", ":")) + kw.setdefault("default", cls._default) + kw.setdefault("sort_keys", True) + return _json.dumps(obj, **kw) + + @staticmethod + def loads(s, **kw): + if isinstance(s, bytes): + # Needed for Python < 3.6 + encoding = detect_utf_encoding(s) + s = s.decode(encoding) + + return _json.loads(s, **kw) + + +class JSONMixin(object): + """Mixin to parse :attr:`data` as JSON. Can be mixed in for both + :class:`~werkzeug.wrappers.Request` and + :class:`~werkzeug.wrappers.Response` classes. + + If `simplejson`_ is installed it is preferred over Python's built-in + :mod:`json` module. + + .. _simplejson: https://simplejson.readthedocs.io/en/latest/ + """ + + #: A module or other object that has ``dumps`` and ``loads`` + #: functions that match the API of the built-in :mod:`json` module. + json_module = _JSONModule + + @property + def json(self): + """The parsed JSON data if :attr:`mimetype` indicates JSON + (:mimetype:`application/json`, see :meth:`is_json`). + + Calls :meth:`get_json` with default arguments. + """ + return self.get_json() + + @property + def is_json(self): + """Check if the mimetype indicates JSON data, either + :mimetype:`application/json` or :mimetype:`application/*+json`. + """ + mt = self.mimetype + return ( + mt == "application/json" + or mt.startswith("application/") + and mt.endswith("+json") + ) + + def _get_data_for_json(self, cache): + try: + return self.get_data(cache=cache) + except TypeError: + # Response doesn't have cache param. + return self.get_data() + + # Cached values for ``(silent=False, silent=True)``. Initialized + # with sentinel values. + _cached_json = (Ellipsis, Ellipsis) + + def get_json(self, force=False, silent=False, cache=True): + """Parse :attr:`data` as JSON. + + If the mimetype does not indicate JSON + (:mimetype:`application/json`, see :meth:`is_json`), this + returns ``None``. + + If parsing fails, :meth:`on_json_loading_failed` is called and + its return value is used as the return value. + + :param force: Ignore the mimetype and always try to parse JSON. + :param silent: Silence parsing errors and return ``None`` + instead. + :param cache: Store the parsed JSON to return for subsequent + calls. + """ + if cache and self._cached_json[silent] is not Ellipsis: + return self._cached_json[silent] + + if not (force or self.is_json): + return None + + data = self._get_data_for_json(cache=cache) + + try: + rv = self.json_module.loads(data) + except ValueError as e: + if silent: + rv = None + + if cache: + normal_rv, _ = self._cached_json + self._cached_json = (normal_rv, rv) + else: + rv = self.on_json_loading_failed(e) + + if cache: + _, silent_rv = self._cached_json + self._cached_json = (rv, silent_rv) + else: + if cache: + self._cached_json = (rv, rv) + + return rv + + def on_json_loading_failed(self, e): + """Called if :meth:`get_json` parsing fails and isn't silenced. + If this method returns a value, it is used as the return value + for :meth:`get_json`. The default implementation raises + :exc:`~werkzeug.exceptions.BadRequest`. + """ + raise BadRequest("Failed to decode JSON object: {0}".format(e)) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py new file mode 100644 index 0000000..d1c71b6 --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/request.py @@ -0,0 +1,44 @@ +from .accept import AcceptMixin +from .auth import AuthorizationMixin +from .base_request import BaseRequest +from .common_descriptors import CommonRequestDescriptorsMixin +from .etag import ETagRequestMixin +from .user_agent import UserAgentMixin + + +class Request( + BaseRequest, + AcceptMixin, + ETagRequestMixin, + UserAgentMixin, + AuthorizationMixin, + CommonRequestDescriptorsMixin, +): + """Full featured request object implementing the following mixins: + + - :class:`AcceptMixin` for accept header parsing + - :class:`ETagRequestMixin` for etag and cache control handling + - :class:`UserAgentMixin` for user agent introspection + - :class:`AuthorizationMixin` for http auth handling + - :class:`CommonRequestDescriptorsMixin` for common headers + """ + + +class StreamOnlyMixin(object): + """If mixed in before the request object this will change the bahavior + of it to disable handling of form parsing. This disables the + :attr:`files`, :attr:`form` attributes and will just provide a + :attr:`stream` attribute that however is always available. + + .. versionadded:: 0.9 + """ + + disable_data_descriptor = True + want_form_data_parsed = False + + +class PlainRequest(StreamOnlyMixin, Request): + """A request object without special form parsing capabilities. + + .. versionadded:: 0.9 + """ diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py new file mode 100644 index 0000000..cd86cac --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/response.py @@ -0,0 +1,78 @@ +from ..utils import cached_property +from .auth import WWWAuthenticateMixin +from .base_response import BaseResponse +from .common_descriptors import CommonResponseDescriptorsMixin +from .etag import ETagResponseMixin + + +class ResponseStream(object): + """A file descriptor like object used by the :class:`ResponseStreamMixin` to + represent the body of the stream. It directly pushes into the response + iterable of the response object. + """ + + mode = "wb+" + + def __init__(self, response): + self.response = response + self.closed = False + + def write(self, value): + if self.closed: + raise ValueError("I/O operation on closed file") + self.response._ensure_sequence(mutable=True) + self.response.response.append(value) + self.response.headers.pop("Content-Length", None) + return len(value) + + def writelines(self, seq): + for item in seq: + self.write(item) + + def close(self): + self.closed = True + + def flush(self): + if self.closed: + raise ValueError("I/O operation on closed file") + + def isatty(self): + if self.closed: + raise ValueError("I/O operation on closed file") + return False + + def tell(self): + self.response._ensure_sequence() + return sum(map(len, self.response.response)) + + @property + def encoding(self): + return self.response.charset + + +class ResponseStreamMixin(object): + """Mixin for :class:`BaseRequest` subclasses. Classes that inherit from + this mixin will automatically get a :attr:`stream` property that provides + a write-only interface to the response iterable. + """ + + @cached_property + def stream(self): + """The response iterable as write-only stream.""" + return ResponseStream(self) + + +class Response( + BaseResponse, + ETagResponseMixin, + ResponseStreamMixin, + CommonResponseDescriptorsMixin, + WWWAuthenticateMixin, +): + """Full featured response object implementing the following mixins: + + - :class:`ETagResponseMixin` for etag and cache control handling + - :class:`ResponseStreamMixin` to add support for the `stream` property + - :class:`CommonResponseDescriptorsMixin` for various HTTP descriptors + - :class:`WWWAuthenticateMixin` for HTTP authentication support + """ diff --git a/venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py b/venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py new file mode 100644 index 0000000..72588dd --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wrappers/user_agent.py @@ -0,0 +1,15 @@ +from ..utils import cached_property + + +class UserAgentMixin(object): + """Adds a `user_agent` attribute to the request object which + contains the parsed user agent of the browser that triggered the + request as a :class:`~werkzeug.useragents.UserAgent` object. + """ + + @cached_property + def user_agent(self): + """The current user agent.""" + from ..useragents import UserAgent + + return UserAgent(self.environ) diff --git a/venv/lib/python3.7/site-packages/werkzeug/wsgi.py b/venv/lib/python3.7/site-packages/werkzeug/wsgi.py new file mode 100644 index 0000000..f069f2d --- /dev/null +++ b/venv/lib/python3.7/site-packages/werkzeug/wsgi.py @@ -0,0 +1,1067 @@ +# -*- coding: utf-8 -*- +""" + werkzeug.wsgi + ~~~~~~~~~~~~~ + + This module implements WSGI related helpers. + + :copyright: 2007 Pallets + :license: BSD-3-Clause +""" +import io +import re +import warnings +from functools import partial +from functools import update_wrapper +from itertools import chain + +from ._compat import BytesIO +from ._compat import implements_iterator +from ._compat import make_literal_wrapper +from ._compat import string_types +from ._compat import text_type +from ._compat import to_bytes +from ._compat import to_unicode +from ._compat import try_coerce_native +from ._compat import wsgi_get_bytes +from ._internal import _encode_idna +from .urls import uri_to_iri +from .urls import url_join +from .urls import url_parse +from .urls import url_quote + + +def responder(f): + """Marks a function as responder. Decorate a function with it and it + will automatically call the return value as WSGI application. + + Example:: + + @responder + def application(environ, start_response): + return Response('Hello World!') + """ + return update_wrapper(lambda *a: f(*a)(*a[-2:]), f) + + +def get_current_url( + environ, + root_only=False, + strip_querystring=False, + host_only=False, + trusted_hosts=None, +): + """A handy helper function that recreates the full URL as IRI for the + current request or parts of it. Here's an example: + + >>> from werkzeug.test import create_environ + >>> env = create_environ("/?param=foo", "http://localhost/script") + >>> get_current_url(env) + 'http://localhost/script/?param=foo' + >>> get_current_url(env, root_only=True) + 'http://localhost/script/' + >>> get_current_url(env, host_only=True) + 'http://localhost/' + >>> get_current_url(env, strip_querystring=True) + 'http://localhost/script/' + + This optionally it verifies that the host is in a list of trusted hosts. + If the host is not in there it will raise a + :exc:`~werkzeug.exceptions.SecurityError`. + + Note that the string returned might contain unicode characters as the + representation is an IRI not an URI. If you need an ASCII only + representation you can use the :func:`~werkzeug.urls.iri_to_uri` + function: + + >>> from werkzeug.urls import iri_to_uri + >>> iri_to_uri(get_current_url(env)) + 'http://localhost/script/?param=foo' + + :param environ: the WSGI environment to get the current URL from. + :param root_only: set `True` if you only want the root URL. + :param strip_querystring: set to `True` if you don't want the querystring. + :param host_only: set to `True` if the host URL should be returned. + :param trusted_hosts: a list of trusted hosts, see :func:`host_is_trusted` + for more information. + """ + tmp = [environ["wsgi.url_scheme"], "://", get_host(environ, trusted_hosts)] + cat = tmp.append + if host_only: + return uri_to_iri("".join(tmp) + "/") + cat(url_quote(wsgi_get_bytes(environ.get("SCRIPT_NAME", ""))).rstrip("/")) + cat("/") + if not root_only: + cat(url_quote(wsgi_get_bytes(environ.get("PATH_INFO", "")).lstrip(b"/"))) + if not strip_querystring: + qs = get_query_string(environ) + if qs: + cat("?" + qs) + return uri_to_iri("".join(tmp)) + + +def host_is_trusted(hostname, trusted_list): + """Checks if a host is trusted against a list. This also takes care + of port normalization. + + .. versionadded:: 0.9 + + :param hostname: the hostname to check + :param trusted_list: a list of hostnames to check against. If a + hostname starts with a dot it will match against + all subdomains as well. + """ + if not hostname: + return False + + if isinstance(trusted_list, string_types): + trusted_list = [trusted_list] + + def _normalize(hostname): + if ":" in hostname: + hostname = hostname.rsplit(":", 1)[0] + return _encode_idna(hostname) + + try: + hostname = _normalize(hostname) + except UnicodeError: + return False + for ref in trusted_list: + if ref.startswith("."): + ref = ref[1:] + suffix_match = True + else: + suffix_match = False + try: + ref = _normalize(ref) + except UnicodeError: + return False + if ref == hostname: + return True + if suffix_match and hostname.endswith(b"." + ref): + return True + return False + + +def get_host(environ, trusted_hosts=None): + """Return the host for the given WSGI environment. This first checks + the ``Host`` header. If it's not present, then ``SERVER_NAME`` and + ``SERVER_PORT`` are used. The host will only contain the port if it + is different than the standard port for the protocol. + + Optionally, verify that the host is trusted using + :func:`host_is_trusted` and raise a + :exc:`~werkzeug.exceptions.SecurityError` if it is not. + + :param environ: The WSGI environment to get the host from. + :param trusted_hosts: A list of trusted hosts. + :return: Host, with port if necessary. + :raise ~werkzeug.exceptions.SecurityError: If the host is not + trusted. + """ + if "HTTP_HOST" in environ: + rv = environ["HTTP_HOST"] + if environ["wsgi.url_scheme"] == "http" and rv.endswith(":80"): + rv = rv[:-3] + elif environ["wsgi.url_scheme"] == "https" and rv.endswith(":443"): + rv = rv[:-4] + else: + rv = environ["SERVER_NAME"] + if (environ["wsgi.url_scheme"], environ["SERVER_PORT"]) not in ( + ("https", "443"), + ("http", "80"), + ): + rv += ":" + environ["SERVER_PORT"] + if trusted_hosts is not None: + if not host_is_trusted(rv, trusted_hosts): + from .exceptions import SecurityError + + raise SecurityError('Host "%s" is not trusted' % rv) + return rv + + +def get_content_length(environ): + """Returns the content length from the WSGI environment as + integer. If it's not available or chunked transfer encoding is used, + ``None`` is returned. + + .. versionadded:: 0.9 + + :param environ: the WSGI environ to fetch the content length from. + """ + if environ.get("HTTP_TRANSFER_ENCODING", "") == "chunked": + return None + + content_length = environ.get("CONTENT_LENGTH") + if content_length is not None: + try: + return max(0, int(content_length)) + except (ValueError, TypeError): + pass + + +def get_input_stream(environ, safe_fallback=True): + """Returns the input stream from the WSGI environment and wraps it + in the most sensible way possible. The stream returned is not the + raw WSGI stream in most cases but one that is safe to read from + without taking into account the content length. + + If content length is not set, the stream will be empty for safety reasons. + If the WSGI server supports chunked or infinite streams, it should set + the ``wsgi.input_terminated`` value in the WSGI environ to indicate that. + + .. versionadded:: 0.9 + + :param environ: the WSGI environ to fetch the stream from. + :param safe_fallback: use an empty stream as a safe fallback when the + content length is not set. Disabling this allows infinite streams, + which can be a denial-of-service risk. + """ + stream = environ["wsgi.input"] + content_length = get_content_length(environ) + + # A wsgi extension that tells us if the input is terminated. In + # that case we return the stream unchanged as we know we can safely + # read it until the end. + if environ.get("wsgi.input_terminated"): + return stream + + # If the request doesn't specify a content length, returning the stream is + # potentially dangerous because it could be infinite, malicious or not. If + # safe_fallback is true, return an empty stream instead for safety. + if content_length is None: + return BytesIO() if safe_fallback else stream + + # Otherwise limit the stream to the content length + return LimitedStream(stream, content_length) + + +def get_query_string(environ): + """Returns the `QUERY_STRING` from the WSGI environment. This also takes + care about the WSGI decoding dance on Python 3 environments as a + native string. The string returned will be restricted to ASCII + characters. + + .. versionadded:: 0.9 + + :param environ: the WSGI environment object to get the query string from. + """ + qs = wsgi_get_bytes(environ.get("QUERY_STRING", "")) + # QUERY_STRING really should be ascii safe but some browsers + # will send us some unicode stuff (I am looking at you IE). + # In that case we want to urllib quote it badly. + return try_coerce_native(url_quote(qs, safe=":&%=+$!*'(),")) + + +def get_path_info(environ, charset="utf-8", errors="replace"): + """Returns the `PATH_INFO` from the WSGI environment and properly + decodes it. This also takes care about the WSGI decoding dance + on Python 3 environments. if the `charset` is set to `None` a + bytestring is returned. + + .. versionadded:: 0.9 + + :param environ: the WSGI environment object to get the path from. + :param charset: the charset for the path info, or `None` if no + decoding should be performed. + :param errors: the decoding error handling. + """ + path = wsgi_get_bytes(environ.get("PATH_INFO", "")) + return to_unicode(path, charset, errors, allow_none_charset=True) + + +def get_script_name(environ, charset="utf-8", errors="replace"): + """Returns the `SCRIPT_NAME` from the WSGI environment and properly + decodes it. This also takes care about the WSGI decoding dance + on Python 3 environments. if the `charset` is set to `None` a + bytestring is returned. + + .. versionadded:: 0.9 + + :param environ: the WSGI environment object to get the path from. + :param charset: the charset for the path, or `None` if no + decoding should be performed. + :param errors: the decoding error handling. + """ + path = wsgi_get_bytes(environ.get("SCRIPT_NAME", "")) + return to_unicode(path, charset, errors, allow_none_charset=True) + + +def pop_path_info(environ, charset="utf-8", errors="replace"): + """Removes and returns the next segment of `PATH_INFO`, pushing it onto + `SCRIPT_NAME`. Returns `None` if there is nothing left on `PATH_INFO`. + + If the `charset` is set to `None` a bytestring is returned. + + If there are empty segments (``'/foo//bar``) these are ignored but + properly pushed to the `SCRIPT_NAME`: + + >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} + >>> pop_path_info(env) + 'a' + >>> env['SCRIPT_NAME'] + '/foo/a' + >>> pop_path_info(env) + 'b' + >>> env['SCRIPT_NAME'] + '/foo/a/b' + + .. versionadded:: 0.5 + + .. versionchanged:: 0.9 + The path is now decoded and a charset and encoding + parameter can be provided. + + :param environ: the WSGI environment that is modified. + """ + path = environ.get("PATH_INFO") + if not path: + return None + + script_name = environ.get("SCRIPT_NAME", "") + + # shift multiple leading slashes over + old_path = path + path = path.lstrip("/") + if path != old_path: + script_name += "/" * (len(old_path) - len(path)) + + if "/" not in path: + environ["PATH_INFO"] = "" + environ["SCRIPT_NAME"] = script_name + path + rv = wsgi_get_bytes(path) + else: + segment, path = path.split("/", 1) + environ["PATH_INFO"] = "/" + path + environ["SCRIPT_NAME"] = script_name + segment + rv = wsgi_get_bytes(segment) + + return to_unicode(rv, charset, errors, allow_none_charset=True) + + +def peek_path_info(environ, charset="utf-8", errors="replace"): + """Returns the next segment on the `PATH_INFO` or `None` if there + is none. Works like :func:`pop_path_info` without modifying the + environment: + + >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} + >>> peek_path_info(env) + 'a' + >>> peek_path_info(env) + 'a' + + If the `charset` is set to `None` a bytestring is returned. + + .. versionadded:: 0.5 + + .. versionchanged:: 0.9 + The path is now decoded and a charset and encoding + parameter can be provided. + + :param environ: the WSGI environment that is checked. + """ + segments = environ.get("PATH_INFO", "").lstrip("/").split("/", 1) + if segments: + return to_unicode( + wsgi_get_bytes(segments[0]), charset, errors, allow_none_charset=True + ) + + +def extract_path_info( + environ_or_baseurl, + path_or_url, + charset="utf-8", + errors="werkzeug.url_quote", + collapse_http_schemes=True, +): + """Extracts the path info from the given URL (or WSGI environment) and + path. The path info returned is a unicode string, not a bytestring + suitable for a WSGI environment. The URLs might also be IRIs. + + If the path info could not be determined, `None` is returned. + + Some examples: + + >>> extract_path_info('http://example.com/app', '/app/hello') + u'/hello' + >>> extract_path_info('http://example.com/app', + ... 'https://example.com/app/hello') + u'/hello' + >>> extract_path_info('http://example.com/app', + ... 'https://example.com/app/hello', + ... collapse_http_schemes=False) is None + True + + Instead of providing a base URL you can also pass a WSGI environment. + + :param environ_or_baseurl: a WSGI environment dict, a base URL or + base IRI. This is the root of the + application. + :param path_or_url: an absolute path from the server root, a + relative path (in which case it's the path info) + or a full URL. Also accepts IRIs and unicode + parameters. + :param charset: the charset for byte data in URLs + :param errors: the error handling on decode + :param collapse_http_schemes: if set to `False` the algorithm does + not assume that http and https on the + same server point to the same + resource. + + .. versionchanged:: 0.15 + The ``errors`` parameter defaults to leaving invalid bytes + quoted instead of replacing them. + + .. versionadded:: 0.6 + """ + + def _normalize_netloc(scheme, netloc): + parts = netloc.split(u"@", 1)[-1].split(u":", 1) + if len(parts) == 2: + netloc, port = parts + if (scheme == u"http" and port == u"80") or ( + scheme == u"https" and port == u"443" + ): + port = None + else: + netloc = parts[0] + port = None + if port is not None: + netloc += u":" + port + return netloc + + # make sure whatever we are working on is a IRI and parse it + path = uri_to_iri(path_or_url, charset, errors) + if isinstance(environ_or_baseurl, dict): + environ_or_baseurl = get_current_url(environ_or_baseurl, root_only=True) + base_iri = uri_to_iri(environ_or_baseurl, charset, errors) + base_scheme, base_netloc, base_path = url_parse(base_iri)[:3] + cur_scheme, cur_netloc, cur_path, = url_parse(url_join(base_iri, path))[:3] + + # normalize the network location + base_netloc = _normalize_netloc(base_scheme, base_netloc) + cur_netloc = _normalize_netloc(cur_scheme, cur_netloc) + + # is that IRI even on a known HTTP scheme? + if collapse_http_schemes: + for scheme in base_scheme, cur_scheme: + if scheme not in (u"http", u"https"): + return None + else: + if not (base_scheme in (u"http", u"https") and base_scheme == cur_scheme): + return None + + # are the netlocs compatible? + if base_netloc != cur_netloc: + return None + + # are we below the application path? + base_path = base_path.rstrip(u"/") + if not cur_path.startswith(base_path): + return None + + return u"/" + cur_path[len(base_path) :].lstrip(u"/") + + +@implements_iterator +class ClosingIterator(object): + """The WSGI specification requires that all middlewares and gateways + respect the `close` callback of the iterable returned by the application. + Because it is useful to add another close action to a returned iterable + and adding a custom iterable is a boring task this class can be used for + that:: + + return ClosingIterator(app(environ, start_response), [cleanup_session, + cleanup_locals]) + + If there is just one close function it can be passed instead of the list. + + A closing iterator is not needed if the application uses response objects + and finishes the processing if the response is started:: + + try: + return response(environ, start_response) + finally: + cleanup_session() + cleanup_locals() + """ + + def __init__(self, iterable, callbacks=None): + iterator = iter(iterable) + self._next = partial(next, iterator) + if callbacks is None: + callbacks = [] + elif callable(callbacks): + callbacks = [callbacks] + else: + callbacks = list(callbacks) + iterable_close = getattr(iterable, "close", None) + if iterable_close: + callbacks.insert(0, iterable_close) + self._callbacks = callbacks + + def __iter__(self): + return self + + def __next__(self): + return self._next() + + def close(self): + for callback in self._callbacks: + callback() + + +def wrap_file(environ, file, buffer_size=8192): + """Wraps a file. This uses the WSGI server's file wrapper if available + or otherwise the generic :class:`FileWrapper`. + + .. versionadded:: 0.5 + + If the file wrapper from the WSGI server is used it's important to not + iterate over it from inside the application but to pass it through + unchanged. If you want to pass out a file wrapper inside a response + object you have to set :attr:`~BaseResponse.direct_passthrough` to `True`. + + More information about file wrappers are available in :pep:`333`. + + :param file: a :class:`file`-like object with a :meth:`~file.read` method. + :param buffer_size: number of bytes for one iteration. + """ + return environ.get("wsgi.file_wrapper", FileWrapper)(file, buffer_size) + + +@implements_iterator +class FileWrapper(object): + """This class can be used to convert a :class:`file`-like object into + an iterable. It yields `buffer_size` blocks until the file is fully + read. + + You should not use this class directly but rather use the + :func:`wrap_file` function that uses the WSGI server's file wrapper + support if it's available. + + .. versionadded:: 0.5 + + If you're using this object together with a :class:`BaseResponse` you have + to use the `direct_passthrough` mode. + + :param file: a :class:`file`-like object with a :meth:`~file.read` method. + :param buffer_size: number of bytes for one iteration. + """ + + def __init__(self, file, buffer_size=8192): + self.file = file + self.buffer_size = buffer_size + + def close(self): + if hasattr(self.file, "close"): + self.file.close() + + def seekable(self): + if hasattr(self.file, "seekable"): + return self.file.seekable() + if hasattr(self.file, "seek"): + return True + return False + + def seek(self, *args): + if hasattr(self.file, "seek"): + self.file.seek(*args) + + def tell(self): + if hasattr(self.file, "tell"): + return self.file.tell() + return None + + def __iter__(self): + return self + + def __next__(self): + data = self.file.read(self.buffer_size) + if data: + return data + raise StopIteration() + + +@implements_iterator +class _RangeWrapper(object): + # private for now, but should we make it public in the future ? + + """This class can be used to convert an iterable object into + an iterable that will only yield a piece of the underlying content. + It yields blocks until the underlying stream range is fully read. + The yielded blocks will have a size that can't exceed the original + iterator defined block size, but that can be smaller. + + If you're using this object together with a :class:`BaseResponse` you have + to use the `direct_passthrough` mode. + + :param iterable: an iterable object with a :meth:`__next__` method. + :param start_byte: byte from which read will start. + :param byte_range: how many bytes to read. + """ + + def __init__(self, iterable, start_byte=0, byte_range=None): + self.iterable = iter(iterable) + self.byte_range = byte_range + self.start_byte = start_byte + self.end_byte = None + if byte_range is not None: + self.end_byte = self.start_byte + self.byte_range + self.read_length = 0 + self.seekable = hasattr(iterable, "seekable") and iterable.seekable() + self.end_reached = False + + def __iter__(self): + return self + + def _next_chunk(self): + try: + chunk = next(self.iterable) + self.read_length += len(chunk) + return chunk + except StopIteration: + self.end_reached = True + raise + + def _first_iteration(self): + chunk = None + if self.seekable: + self.iterable.seek(self.start_byte) + self.read_length = self.iterable.tell() + contextual_read_length = self.read_length + else: + while self.read_length <= self.start_byte: + chunk = self._next_chunk() + if chunk is not None: + chunk = chunk[self.start_byte - self.read_length :] + contextual_read_length = self.start_byte + return chunk, contextual_read_length + + def _next(self): + if self.end_reached: + raise StopIteration() + chunk = None + contextual_read_length = self.read_length + if self.read_length == 0: + chunk, contextual_read_length = self._first_iteration() + if chunk is None: + chunk = self._next_chunk() + if self.end_byte is not None and self.read_length >= self.end_byte: + self.end_reached = True + return chunk[: self.end_byte - contextual_read_length] + return chunk + + def __next__(self): + chunk = self._next() + if chunk: + return chunk + self.end_reached = True + raise StopIteration() + + def close(self): + if hasattr(self.iterable, "close"): + self.iterable.close() + + +def _make_chunk_iter(stream, limit, buffer_size): + """Helper for the line and chunk iter functions.""" + if isinstance(stream, (bytes, bytearray, text_type)): + raise TypeError( + "Passed a string or byte object instead of true iterator or stream." + ) + if not hasattr(stream, "read"): + for item in stream: + if item: + yield item + return + if not isinstance(stream, LimitedStream) and limit is not None: + stream = LimitedStream(stream, limit) + _read = stream.read + while 1: + item = _read(buffer_size) + if not item: + break + yield item + + +def make_line_iter(stream, limit=None, buffer_size=10 * 1024, cap_at_buffer=False): + """Safely iterates line-based over an input stream. If the input stream + is not a :class:`LimitedStream` the `limit` parameter is mandatory. + + This uses the stream's :meth:`~file.read` method internally as opposite + to the :meth:`~file.readline` method that is unsafe and can only be used + in violation of the WSGI specification. The same problem applies to the + `__iter__` function of the input stream which calls :meth:`~file.readline` + without arguments. + + If you need line-by-line processing it's strongly recommended to iterate + over the input stream using this helper function. + + .. versionchanged:: 0.8 + This function now ensures that the limit was reached. + + .. versionadded:: 0.9 + added support for iterators as input stream. + + .. versionadded:: 0.11.10 + added support for the `cap_at_buffer` parameter. + + :param stream: the stream or iterate to iterate over. + :param limit: the limit in bytes for the stream. (Usually + content length. Not necessary if the `stream` + is a :class:`LimitedStream`. + :param buffer_size: The optional buffer size. + :param cap_at_buffer: if this is set chunks are split if they are longer + than the buffer size. Internally this is implemented + that the buffer size might be exhausted by a factor + of two however. + """ + _iter = _make_chunk_iter(stream, limit, buffer_size) + + first_item = next(_iter, "") + if not first_item: + return + + s = make_literal_wrapper(first_item) + empty = s("") + cr = s("\r") + lf = s("\n") + crlf = s("\r\n") + + _iter = chain((first_item,), _iter) + + def _iter_basic_lines(): + _join = empty.join + buffer = [] + while 1: + new_data = next(_iter, "") + if not new_data: + break + new_buf = [] + buf_size = 0 + for item in chain(buffer, new_data.splitlines(True)): + new_buf.append(item) + buf_size += len(item) + if item and item[-1:] in crlf: + yield _join(new_buf) + new_buf = [] + elif cap_at_buffer and buf_size >= buffer_size: + rv = _join(new_buf) + while len(rv) >= buffer_size: + yield rv[:buffer_size] + rv = rv[buffer_size:] + new_buf = [rv] + buffer = new_buf + if buffer: + yield _join(buffer) + + # This hackery is necessary to merge 'foo\r' and '\n' into one item + # of 'foo\r\n' if we were unlucky and we hit a chunk boundary. + previous = empty + for item in _iter_basic_lines(): + if item == lf and previous[-1:] == cr: + previous += item + item = empty + if previous: + yield previous + previous = item + if previous: + yield previous + + +def make_chunk_iter( + stream, separator, limit=None, buffer_size=10 * 1024, cap_at_buffer=False +): + """Works like :func:`make_line_iter` but accepts a separator + which divides chunks. If you want newline based processing + you should use :func:`make_line_iter` instead as it + supports arbitrary newline markers. + + .. versionadded:: 0.8 + + .. versionadded:: 0.9 + added support for iterators as input stream. + + .. versionadded:: 0.11.10 + added support for the `cap_at_buffer` parameter. + + :param stream: the stream or iterate to iterate over. + :param separator: the separator that divides chunks. + :param limit: the limit in bytes for the stream. (Usually + content length. Not necessary if the `stream` + is otherwise already limited). + :param buffer_size: The optional buffer size. + :param cap_at_buffer: if this is set chunks are split if they are longer + than the buffer size. Internally this is implemented + that the buffer size might be exhausted by a factor + of two however. + """ + _iter = _make_chunk_iter(stream, limit, buffer_size) + + first_item = next(_iter, "") + if not first_item: + return + + _iter = chain((first_item,), _iter) + if isinstance(first_item, text_type): + separator = to_unicode(separator) + _split = re.compile(r"(%s)" % re.escape(separator)).split + _join = u"".join + else: + separator = to_bytes(separator) + _split = re.compile(b"(" + re.escape(separator) + b")").split + _join = b"".join + + buffer = [] + while 1: + new_data = next(_iter, "") + if not new_data: + break + chunks = _split(new_data) + new_buf = [] + buf_size = 0 + for item in chain(buffer, chunks): + if item == separator: + yield _join(new_buf) + new_buf = [] + buf_size = 0 + else: + buf_size += len(item) + new_buf.append(item) + + if cap_at_buffer and buf_size >= buffer_size: + rv = _join(new_buf) + while len(rv) >= buffer_size: + yield rv[:buffer_size] + rv = rv[buffer_size:] + new_buf = [rv] + buf_size = len(rv) + + buffer = new_buf + if buffer: + yield _join(buffer) + + +@implements_iterator +class LimitedStream(io.IOBase): + """Wraps a stream so that it doesn't read more than n bytes. If the + stream is exhausted and the caller tries to get more bytes from it + :func:`on_exhausted` is called which by default returns an empty + string. The return value of that function is forwarded + to the reader function. So if it returns an empty string + :meth:`read` will return an empty string as well. + + The limit however must never be higher than what the stream can + output. Otherwise :meth:`readlines` will try to read past the + limit. + + .. admonition:: Note on WSGI compliance + + calls to :meth:`readline` and :meth:`readlines` are not + WSGI compliant because it passes a size argument to the + readline methods. Unfortunately the WSGI PEP is not safely + implementable without a size argument to :meth:`readline` + because there is no EOF marker in the stream. As a result + of that the use of :meth:`readline` is discouraged. + + For the same reason iterating over the :class:`LimitedStream` + is not portable. It internally calls :meth:`readline`. + + We strongly suggest using :meth:`read` only or using the + :func:`make_line_iter` which safely iterates line-based + over a WSGI input stream. + + :param stream: the stream to wrap. + :param limit: the limit for the stream, must not be longer than + what the string can provide if the stream does not + end with `EOF` (like `wsgi.input`) + """ + + def __init__(self, stream, limit): + self._read = stream.read + self._readline = stream.readline + self._pos = 0 + self.limit = limit + + def __iter__(self): + return self + + @property + def is_exhausted(self): + """If the stream is exhausted this attribute is `True`.""" + return self._pos >= self.limit + + def on_exhausted(self): + """This is called when the stream tries to read past the limit. + The return value of this function is returned from the reading + function. + """ + # Read null bytes from the stream so that we get the + # correct end of stream marker. + return self._read(0) + + def on_disconnect(self): + """What should happen if a disconnect is detected? The return + value of this function is returned from read functions in case + the client went away. By default a + :exc:`~werkzeug.exceptions.ClientDisconnected` exception is raised. + """ + from .exceptions import ClientDisconnected + + raise ClientDisconnected() + + def exhaust(self, chunk_size=1024 * 64): + """Exhaust the stream. This consumes all the data left until the + limit is reached. + + :param chunk_size: the size for a chunk. It will read the chunk + until the stream is exhausted and throw away + the results. + """ + to_read = self.limit - self._pos + chunk = chunk_size + while to_read > 0: + chunk = min(to_read, chunk) + self.read(chunk) + to_read -= chunk + + def read(self, size=None): + """Read `size` bytes or if size is not provided everything is read. + + :param size: the number of bytes read. + """ + if self._pos >= self.limit: + return self.on_exhausted() + if size is None or size == -1: # -1 is for consistence with file + size = self.limit + to_read = min(self.limit - self._pos, size) + try: + read = self._read(to_read) + except (IOError, ValueError): + return self.on_disconnect() + if to_read and len(read) != to_read: + return self.on_disconnect() + self._pos += len(read) + return read + + def readline(self, size=None): + """Reads one line from the stream.""" + if self._pos >= self.limit: + return self.on_exhausted() + if size is None: + size = self.limit - self._pos + else: + size = min(size, self.limit - self._pos) + try: + line = self._readline(size) + except (ValueError, IOError): + return self.on_disconnect() + if size and not line: + return self.on_disconnect() + self._pos += len(line) + return line + + def readlines(self, size=None): + """Reads a file into a list of strings. It calls :meth:`readline` + until the file is read to the end. It does support the optional + `size` argument if the underlaying stream supports it for + `readline`. + """ + last_pos = self._pos + result = [] + if size is not None: + end = min(self.limit, last_pos + size) + else: + end = self.limit + while 1: + if size is not None: + size -= last_pos - self._pos + if self._pos >= end: + break + result.append(self.readline(size)) + if size is not None: + last_pos = self._pos + return result + + def tell(self): + """Returns the position of the stream. + + .. versionadded:: 0.9 + """ + return self._pos + + def __next__(self): + line = self.readline() + if not line: + raise StopIteration() + return line + + def readable(self): + return True + + +# DEPRECATED +from .middleware.dispatcher import DispatcherMiddleware as _DispatcherMiddleware +from .middleware.http_proxy import ProxyMiddleware as _ProxyMiddleware +from .middleware.shared_data import SharedDataMiddleware as _SharedDataMiddleware + + +class ProxyMiddleware(_ProxyMiddleware): + """ + .. deprecated:: 0.15 + ``werkzeug.wsgi.ProxyMiddleware`` has moved to + :mod:`werkzeug.middleware.http_proxy`. This import will be + removed in 1.0. + """ + + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.wsgi.ProxyMiddleware' has moved to 'werkzeug" + ".middleware.http_proxy.ProxyMiddleware'. This import is" + " deprecated as of version 0.15 and will be removed in" + " version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(ProxyMiddleware, self).__init__(*args, **kwargs) + + +class SharedDataMiddleware(_SharedDataMiddleware): + """ + .. deprecated:: 0.15 + ``werkzeug.wsgi.SharedDataMiddleware`` has moved to + :mod:`werkzeug.middleware.shared_data`. This import will be + removed in 1.0. + """ + + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.wsgi.SharedDataMiddleware' has moved to" + " 'werkzeug.middleware.shared_data.SharedDataMiddleware'." + " This import is deprecated as of version 0.15 and will be" + " removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(SharedDataMiddleware, self).__init__(*args, **kwargs) + + +class DispatcherMiddleware(_DispatcherMiddleware): + """ + .. deprecated:: 0.15 + ``werkzeug.wsgi.DispatcherMiddleware`` has moved to + :mod:`werkzeug.middleware.dispatcher`. This import will be + removed in 1.0. + """ + + def __init__(self, *args, **kwargs): + warnings.warn( + "'werkzeug.wsgi.DispatcherMiddleware' has moved to" + " 'werkzeug.middleware.dispatcher.DispatcherMiddleware'." + " This import is deprecated as of version 0.15 and will be" + " removed in version 1.0.", + DeprecationWarning, + stacklevel=2, + ) + super(DispatcherMiddleware, self).__init__(*args, **kwargs) diff --git a/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/PKG-INFO b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/PKG-INFO new file mode 100644 index 0000000..6ff1ef8 --- /dev/null +++ b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/PKG-INFO @@ -0,0 +1,166 @@ +Metadata-Version: 1.1 +Name: wrapt +Version: 1.11.1 +Summary: Module for decorators, wrappers and monkey patching. +Home-page: https://github.com/GrahamDumpleton/wrapt +Author: Graham Dumpleton +Author-email: Graham.Dumpleton@gmail.com +License: BSD +Description: wrapt + ===== + + |Travis| |AppVeyor| |Coveralls| |PyPI| + + The aim of the **wrapt** module is to provide a transparent object proxy + for Python, which can be used as the basis for the construction of function + wrappers and decorator functions. + + The **wrapt** module focuses very much on correctness. It therefore goes + way beyond existing mechanisms such as ``functools.wraps()`` to ensure that + decorators preserve introspectability, signatures, type checking abilities + etc. The decorators that can be constructed using this module will work in + far more scenarios than typical decorators and provide more predictable and + consistent behaviour. + + To ensure that the overhead is as minimal as possible, a C extension module + is used for performance critical components. An automatic fallback to a + pure Python implementation is also provided where a target system does not + have a compiler to allow the C extension to be compiled. + + Documentation + ------------- + + For further information on the **wrapt** module see: + + * http://wrapt.readthedocs.org/ + + Quick Start + ----------- + + To implement your decorator you need to first define a wrapper function. + This will be called each time a decorated function is called. The wrapper + function needs to take four positional arguments: + + * ``wrapped`` - The wrapped function which in turns needs to be called by your wrapper function. + * ``instance`` - The object to which the wrapped function was bound when it was called. + * ``args`` - The list of positional arguments supplied when the decorated function was called. + * ``kwargs`` - The dictionary of keyword arguments supplied when the decorated function was called. + + The wrapper function would do whatever it needs to, but would usually in + turn call the wrapped function that is passed in via the ``wrapped`` + argument. + + The decorator ``@wrapt.decorator`` then needs to be applied to the wrapper + function to convert it into a decorator which can in turn be applied to + other functions. + + :: + + import wrapt + + @wrapt.decorator + def pass_through(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + @pass_through + def function(): + pass + + If you wish to implement a decorator which accepts arguments, then wrap the + definition of the decorator in a function closure. Any arguments supplied + to the outer function when the decorator is applied, will be available to + the inner wrapper when the wrapped function is called. + + :: + + import wrapt + + def with_arguments(myarg1, myarg2): + @wrapt.decorator + def wrapper(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + return wrapper + + @with_arguments(1, 2) + def function(): + pass + + When applied to a normal function or static method, the wrapper function + when called will be passed ``None`` as the ``instance`` argument. + + When applied to an instance method, the wrapper function when called will + be passed the instance of the class the method is being called on as the + ``instance`` argument. This will be the case even when the instance method + was called explicitly via the class and the instance passed as the first + argument. That is, the instance will never be passed as part of ``args``. + + When applied to a class method, the wrapper function when called will be + passed the class type as the ``instance`` argument. + + When applied to a class, the wrapper function when called will be passed + ``None`` as the ``instance`` argument. The ``wrapped`` argument in this + case will be the class. + + The above rules can be summarised with the following example. + + :: + + import inspect + + @wrapt.decorator + def universal(wrapped, instance, args, kwargs): + if instance is None: + if inspect.isclass(wrapped): + # Decorator was applied to a class. + return wrapped(*args, **kwargs) + else: + # Decorator was applied to a function or staticmethod. + return wrapped(*args, **kwargs) + else: + if inspect.isclass(instance): + # Decorator was applied to a classmethod. + return wrapped(*args, **kwargs) + else: + # Decorator was applied to an instancemethod. + return wrapped(*args, **kwargs) + + Using these checks it is therefore possible to create a universal decorator + that can be applied in all situations. It is no longer necessary to create + different variants of decorators for normal functions and instance methods, + or use additional wrappers to convert a function decorator into one that + will work for instance methods. + + In all cases, the wrapped function passed to the wrapper function is called + in the same way, with ``args`` and ``kwargs`` being passed. The + ``instance`` argument doesn't need to be used in calling the wrapped + function. + + Repository + ---------- + + Full source code for the **wrapt** module, including documentation files + and unit tests, can be obtained from github. + + * https://github.com/GrahamDumpleton/wrapt + + .. |Travis| image:: https://travis-ci.org/GrahamDumpleton/wrapt.svg?branch=develop + :target: https://travis-ci.org/GrahamDumpleton/wrapt + .. |Appveyor| image:: https://ci.appveyor.com/api/projects/status/32r7s2skrgm9ubva?svg=true + :target: https://ci.appveyor.com/project/GrahamDumpleton/wrapt/branch/develop + .. |Coveralls| image:: https://img.shields.io/coveralls/GrahamDumpleton/wrapt/develop.svg + :target: https://coveralls.io/github/GrahamDumpleton/wrapt?branch=develop + .. |PyPI| image:: https://img.shields.io/pypi/v/wrapt.svg + :target: https://pypi.python.org/pypi/wrapt + +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: BSD License +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 diff --git a/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/SOURCES.txt b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/SOURCES.txt new file mode 100644 index 0000000..29b22c5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/SOURCES.txt @@ -0,0 +1,11 @@ +README.rst +setup.py +src/wrapt/__init__.py +src/wrapt/_wrappers.c +src/wrapt/decorators.py +src/wrapt/importer.py +src/wrapt/wrappers.py +src/wrapt.egg-info/PKG-INFO +src/wrapt.egg-info/SOURCES.txt +src/wrapt.egg-info/dependency_links.txt +src/wrapt.egg-info/top_level.txt \ No newline at end of file diff --git a/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/dependency_links.txt b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/installed-files.txt b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/installed-files.txt new file mode 100644 index 0000000..20386bf --- /dev/null +++ b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/installed-files.txt @@ -0,0 +1,13 @@ +../wrapt/__init__.py +../wrapt/__pycache__/__init__.cpython-37.pyc +../wrapt/__pycache__/decorators.cpython-37.pyc +../wrapt/__pycache__/importer.cpython-37.pyc +../wrapt/__pycache__/wrappers.cpython-37.pyc +../wrapt/_wrappers.cpython-37m-darwin.so +../wrapt/decorators.py +../wrapt/importer.py +../wrapt/wrappers.py +PKG-INFO +SOURCES.txt +dependency_links.txt +top_level.txt diff --git a/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/top_level.txt b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/top_level.txt new file mode 100644 index 0000000..ba11553 --- /dev/null +++ b/venv/lib/python3.7/site-packages/wrapt-1.11.1-py3.7.egg-info/top_level.txt @@ -0,0 +1 @@ +wrapt diff --git a/venv/lib/python3.7/site-packages/wrapt/__init__.py b/venv/lib/python3.7/site-packages/wrapt/__init__.py new file mode 100644 index 0000000..ce87412 --- /dev/null +++ b/venv/lib/python3.7/site-packages/wrapt/__init__.py @@ -0,0 +1,16 @@ +__version_info__ = ('1', '11', '1') +__version__ = '.'.join(__version_info__) + +from .wrappers import (ObjectProxy, CallableObjectProxy, FunctionWrapper, + BoundFunctionWrapper, WeakFunctionProxy, PartialCallableObjectProxy, + resolve_path, apply_patch, wrap_object, wrap_object_attribute, + function_wrapper, wrap_function_wrapper, patch_function_wrapper, + transient_function_wrapper) + +from .decorators import (adapter_factory, AdapterFactory, decorator, + synchronized) + +from .importer import (register_post_import_hook, when_imported, + notify_module_loaded, discover_post_import_hooks) + +from inspect import getcallargs diff --git a/venv/lib/python3.7/site-packages/wrapt/__pycache__/__init__.cpython-37.pyc b/venv/lib/python3.7/site-packages/wrapt/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9875213e40b25560116ec45f276ccbf38a4700fa GIT binary patch literal 992 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 Bm>vKC literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/wrapt/__pycache__/importer.cpython-37.pyc b/venv/lib/python3.7/site-packages/wrapt/__pycache__/importer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6b467550abe534a76721f6507c437ce90e238a3 GIT binary patch literal 4248 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 Y^1*U$WVo_*WVk$x9TSD}-twmZ4`uK7Y5)KL literal 0 HcmV?d00001 diff --git a/venv/lib/python3.7/site-packages/wrapt/_wrappers.cpython-37m-darwin.so b/venv/lib/python3.7/site-packages/wrapt/_wrappers.cpython-37m-darwin.so new file mode 100755 index 0000000000000000000000000000000000000000..27a0e8d785902d8f76670ae820eb9accabb8b942 GIT binary patch literal 53260 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'.format( + type(self).__name__, id(self), + type(self.__wrapped__).__name__, + id(self.__wrapped__)) + + def __reversed__(self): + return reversed(self.__wrapped__) + + if PY3: + def __round__(self): + return round(self.__wrapped__) + + def __lt__(self, other): + return self.__wrapped__ < other + + def __le__(self, other): + return self.__wrapped__ <= other + + def __eq__(self, other): + return self.__wrapped__ == other + + def __ne__(self, other): + return self.__wrapped__ != other + + def __gt__(self, other): + return self.__wrapped__ > other + + def __ge__(self, other): + return self.__wrapped__ >= other + + def __hash__(self): + return hash(self.__wrapped__) + + def __nonzero__(self): + return bool(self.__wrapped__) + + def __bool__(self): + return bool(self.__wrapped__) + + def __setattr__(self, name, value): + if name.startswith('_self_'): + object.__setattr__(self, name, value) + + elif name == '__wrapped__': + object.__setattr__(self, name, value) + try: + object.__delattr__(self, '__qualname__') + except AttributeError: + pass + try: + object.__setattr__(self, '__qualname__', value.__qualname__) + except AttributeError: + pass + + elif name == '__qualname__': + setattr(self.__wrapped__, name, value) + object.__setattr__(self, name, value) + + elif hasattr(type(self), name): + object.__setattr__(self, name, value) + + else: + setattr(self.__wrapped__, name, value) + + def __getattr__(self, name): + # If we are being to lookup '__wrapped__' then the + # '__init__()' method cannot have been called. + + if name == '__wrapped__': + raise ValueError('wrapper has not been initialised') + + return getattr(self.__wrapped__, name) + + def __delattr__(self, name): + if name.startswith('_self_'): + object.__delattr__(self, name) + + elif name == '__wrapped__': + raise TypeError('__wrapped__ must be an object') + + elif name == '__qualname__': + object.__delattr__(self, name) + delattr(self.__wrapped__, name) + + elif hasattr(type(self), name): + object.__delattr__(self, name) + + else: + delattr(self.__wrapped__, name) + + def __add__(self, other): + return self.__wrapped__ + other + + def __sub__(self, other): + return self.__wrapped__ - other + + def __mul__(self, other): + return self.__wrapped__ * other + + def __div__(self, other): + return operator.div(self.__wrapped__, other) + + def __truediv__(self, other): + return operator.truediv(self.__wrapped__, other) + + def __floordiv__(self, other): + return self.__wrapped__ // other + + def __mod__(self, other): + return self.__wrapped__ % other + + def __divmod__(self, other): + return divmod(self.__wrapped__, other) + + def __pow__(self, other, *args): + return pow(self.__wrapped__, other, *args) + + def __lshift__(self, other): + return self.__wrapped__ << other + + def __rshift__(self, other): + return self.__wrapped__ >> other + + def __and__(self, other): + return self.__wrapped__ & other + + def __xor__(self, other): + return self.__wrapped__ ^ other + + def __or__(self, other): + return self.__wrapped__ | other + + def __radd__(self, other): + return other + self.__wrapped__ + + def __rsub__(self, other): + return other - self.__wrapped__ + + def __rmul__(self, other): + return other * self.__wrapped__ + + def __rdiv__(self, other): + return operator.div(other, self.__wrapped__) + + def __rtruediv__(self, other): + return operator.truediv(other, self.__wrapped__) + + def __rfloordiv__(self, other): + return other // self.__wrapped__ + + def __rmod__(self, other): + return other % self.__wrapped__ + + def __rdivmod__(self, other): + return divmod(other, self.__wrapped__) + + def __rpow__(self, other, *args): + return pow(other, self.__wrapped__, *args) + + def __rlshift__(self, other): + return other << self.__wrapped__ + + def __rrshift__(self, other): + return other >> self.__wrapped__ + + def __rand__(self, other): + return other & self.__wrapped__ + + def __rxor__(self, other): + return other ^ self.__wrapped__ + + def __ror__(self, other): + return other | self.__wrapped__ + + def __iadd__(self, other): + self.__wrapped__ += other + return self + + def __isub__(self, other): + self.__wrapped__ -= other + return self + + def __imul__(self, other): + self.__wrapped__ *= other + return self + + def __idiv__(self, other): + self.__wrapped__ = operator.idiv(self.__wrapped__, other) + return self + + def __itruediv__(self, other): + self.__wrapped__ = operator.itruediv(self.__wrapped__, other) + return self + + def __ifloordiv__(self, other): + self.__wrapped__ //= other + return self + + def __imod__(self, other): + self.__wrapped__ %= other + return self + + def __ipow__(self, other): + self.__wrapped__ **= other + return self + + def __ilshift__(self, other): + self.__wrapped__ <<= other + return self + + def __irshift__(self, other): + self.__wrapped__ >>= other + return self + + def __iand__(self, other): + self.__wrapped__ &= other + return self + + def __ixor__(self, other): + self.__wrapped__ ^= other + return self + + def __ior__(self, other): + self.__wrapped__ |= other + return self + + def __neg__(self): + return -self.__wrapped__ + + def __pos__(self): + return +self.__wrapped__ + + def __abs__(self): + return abs(self.__wrapped__) + + def __invert__(self): + return ~self.__wrapped__ + + def __int__(self): + return int(self.__wrapped__) + + def __long__(self): + return long(self.__wrapped__) + + def __float__(self): + return float(self.__wrapped__) + + def __complex__(self): + return complex(self.__wrapped__) + + def __oct__(self): + return oct(self.__wrapped__) + + def __hex__(self): + return hex(self.__wrapped__) + + def __index__(self): + return operator.index(self.__wrapped__) + + def __len__(self): + return len(self.__wrapped__) + + def __contains__(self, value): + return value in self.__wrapped__ + + def __getitem__(self, key): + return self.__wrapped__[key] + + def __setitem__(self, key, value): + self.__wrapped__[key] = value + + def __delitem__(self, key): + del self.__wrapped__[key] + + def __getslice__(self, i, j): + return self.__wrapped__[i:j] + + def __setslice__(self, i, j, value): + self.__wrapped__[i:j] = value + + def __delslice__(self, i, j): + del self.__wrapped__[i:j] + + def __enter__(self): + return self.__wrapped__.__enter__() + + def __exit__(self, *args, **kwargs): + return self.__wrapped__.__exit__(*args, **kwargs) + + def __iter__(self): + return iter(self.__wrapped__) + + def __copy__(self): + raise NotImplementedError('object proxy must define __copy__()') + + def __deepcopy__(self, memo): + raise NotImplementedError('object proxy must define __deepcopy__()') + + def __reduce__(self): + raise NotImplementedError( + 'object proxy must define __reduce_ex__()') + + def __reduce_ex__(self, protocol): + raise NotImplementedError( + 'object proxy must define __reduce_ex__()') + +class CallableObjectProxy(ObjectProxy): + + def __call__(self, *args, **kwargs): + return self.__wrapped__(*args, **kwargs) + +class PartialCallableObjectProxy(ObjectProxy): + + def __init__(self, *args, **kwargs): + if len(args) < 1: + raise TypeError('partial type takes at least one argument') + + wrapped, args = args[0], args[1:] + + if not callable(wrapped): + raise TypeError('the first argument must be callable') + + super(PartialCallableObjectProxy, self).__init__(wrapped) + + self._self_args = args + self._self_kwargs = kwargs + + def __call__(self, *args, **kwargs): + _args = self._self_args + args + + _kwargs = dict(self._self_kwargs) + _kwargs.update(kwargs) + + return self.__wrapped__(*_args, **_kwargs) + +class _FunctionWrapperBase(ObjectProxy): + + __slots__ = ('_self_instance', '_self_wrapper', '_self_enabled', + '_self_binding', '_self_parent') + + def __init__(self, wrapped, instance, wrapper, enabled=None, + binding='function', parent=None): + + super(_FunctionWrapperBase, self).__init__(wrapped) + + object.__setattr__(self, '_self_instance', instance) + object.__setattr__(self, '_self_wrapper', wrapper) + object.__setattr__(self, '_self_enabled', enabled) + object.__setattr__(self, '_self_binding', binding) + object.__setattr__(self, '_self_parent', parent) + + def __get__(self, instance, owner): + # This method is actually doing double duty for both unbound and + # bound derived wrapper classes. It should possibly be broken up + # and the distinct functionality moved into the derived classes. + # Can't do that straight away due to some legacy code which is + # relying on it being here in this base class. + # + # The distinguishing attribute which determines whether we are + # being called in an unbound or bound wrapper is the parent + # attribute. If binding has never occurred, then the parent will + # be None. + # + # First therefore, is if we are called in an unbound wrapper. In + # this case we perform the binding. + # + # We have one special case to worry about here. This is where we + # are decorating a nested class. In this case the wrapped class + # would not have a __get__() method to call. In that case we + # simply return self. + # + # Note that we otherwise still do binding even if instance is + # None and accessing an unbound instance method from a class. + # This is because we need to be able to later detect that + # specific case as we will need to extract the instance from the + # first argument of those passed in. + + if self._self_parent is None: + if not inspect.isclass(self.__wrapped__): + descriptor = self.__wrapped__.__get__(instance, owner) + + return self.__bound_function_wrapper__(descriptor, instance, + self._self_wrapper, self._self_enabled, + self._self_binding, self) + + return self + + # Now we have the case of binding occurring a second time on what + # was already a bound function. In this case we would usually + # return ourselves again. This mirrors what Python does. + # + # The special case this time is where we were originally bound + # with an instance of None and we were likely an instance + # method. In that case we rebind against the original wrapped + # function from the parent again. + + if self._self_instance is None and self._self_binding == 'function': + descriptor = self._self_parent.__wrapped__.__get__( + instance, owner) + + return self._self_parent.__bound_function_wrapper__( + descriptor, instance, self._self_wrapper, + self._self_enabled, self._self_binding, + self._self_parent) + + return self + + def __call__(self, *args, **kwargs): + # If enabled has been specified, then evaluate it at this point + # and if the wrapper is not to be executed, then simply return + # the bound function rather than a bound wrapper for the bound + # function. When evaluating enabled, if it is callable we call + # it, otherwise we evaluate it as a boolean. + + if self._self_enabled is not None: + if callable(self._self_enabled): + if not self._self_enabled(): + return self.__wrapped__(*args, **kwargs) + elif not self._self_enabled: + return self.__wrapped__(*args, **kwargs) + + # This can occur where initial function wrapper was applied to + # a function that was already bound to an instance. In that case + # we want to extract the instance from the function and use it. + + if self._self_binding == 'function': + if self._self_instance is None: + instance = getattr(self.__wrapped__, '__self__', None) + if instance is not None: + return self._self_wrapper(self.__wrapped__, instance, + args, kwargs) + + # This is generally invoked when the wrapped function is being + # called as a normal function and is not bound to a class as an + # instance method. This is also invoked in the case where the + # wrapped function was a method, but this wrapper was in turn + # wrapped using the staticmethod decorator. + + return self._self_wrapper(self.__wrapped__, self._self_instance, + args, kwargs) + +class BoundFunctionWrapper(_FunctionWrapperBase): + + def __call__(self, *args, **kwargs): + # If enabled has been specified, then evaluate it at this point + # and if the wrapper is not to be executed, then simply return + # the bound function rather than a bound wrapper for the bound + # function. When evaluating enabled, if it is callable we call + # it, otherwise we evaluate it as a boolean. + + if self._self_enabled is not None: + if callable(self._self_enabled): + if not self._self_enabled(): + return self.__wrapped__(*args, **kwargs) + elif not self._self_enabled: + return self.__wrapped__(*args, **kwargs) + + # We need to do things different depending on whether we are + # likely wrapping an instance method vs a static method or class + # method. + + if self._self_binding == 'function': + if self._self_instance is None: + # This situation can occur where someone is calling the + # instancemethod via the class type and passing the instance + # as the first argument. We need to shift the args before + # making the call to the wrapper and effectively bind the + # instance to the wrapped function using a partial so the + # wrapper doesn't see anything as being different. + + if not args: + raise TypeError('missing 1 required positional argument') + + instance, args = args[0], args[1:] + wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) + return self._self_wrapper(wrapped, instance, args, kwargs) + + return self._self_wrapper(self.__wrapped__, self._self_instance, + args, kwargs) + + else: + # As in this case we would be dealing with a classmethod or + # staticmethod, then _self_instance will only tell us whether + # when calling the classmethod or staticmethod they did it via an + # instance of the class it is bound to and not the case where + # done by the class type itself. We thus ignore _self_instance + # and use the __self__ attribute of the bound function instead. + # For a classmethod, this means instance will be the class type + # and for a staticmethod it will be None. This is probably the + # more useful thing we can pass through even though we loose + # knowledge of whether they were called on the instance vs the + # class type, as it reflects what they have available in the + # decoratored function. + + instance = getattr(self.__wrapped__, '__self__', None) + + return self._self_wrapper(self.__wrapped__, instance, args, + kwargs) + +class FunctionWrapper(_FunctionWrapperBase): + + __bound_function_wrapper__ = BoundFunctionWrapper + + def __init__(self, wrapped, wrapper, enabled=None): + # What it is we are wrapping here could be anything. We need to + # try and detect specific cases though. In particular, we need + # to detect when we are given something that is a method of a + # class. Further, we need to know when it is likely an instance + # method, as opposed to a class or static method. This can + # become problematic though as there isn't strictly a fool proof + # method of knowing. + # + # The situations we could encounter when wrapping a method are: + # + # 1. The wrapper is being applied as part of a decorator which + # is a part of the class definition. In this case what we are + # given is the raw unbound function, classmethod or staticmethod + # wrapper objects. + # + # The problem here is that we will not know we are being applied + # in the context of the class being set up. This becomes + # important later for the case of an instance method, because in + # that case we just see it as a raw function and can't + # distinguish it from wrapping a normal function outside of + # a class context. + # + # 2. The wrapper is being applied when performing monkey + # patching of the class type afterwards and the method to be + # wrapped was retrieved direct from the __dict__ of the class + # type. This is effectively the same as (1) above. + # + # 3. The wrapper is being applied when performing monkey + # patching of the class type afterwards and the method to be + # wrapped was retrieved from the class type. In this case + # binding will have been performed where the instance against + # which the method is bound will be None at that point. + # + # This case is a problem because we can no longer tell if the + # method was a static method, plus if using Python3, we cannot + # tell if it was an instance method as the concept of an + # unnbound method no longer exists. + # + # 4. The wrapper is being applied when performing monkey + # patching of an instance of a class. In this case binding will + # have been perfomed where the instance was not None. + # + # This case is a problem because we can no longer tell if the + # method was a static method. + # + # Overall, the best we can do is look at the original type of the + # object which was wrapped prior to any binding being done and + # see if it is an instance of classmethod or staticmethod. In + # the case where other decorators are between us and them, if + # they do not propagate the __class__ attribute so that the + # isinstance() checks works, then likely this will do the wrong + # thing where classmethod and staticmethod are used. + # + # Since it is likely to be very rare that anyone even puts + # decorators around classmethod and staticmethod, likelihood of + # that being an issue is very small, so we accept it and suggest + # that those other decorators be fixed. It is also only an issue + # if a decorator wants to actually do things with the arguments. + # + # As to not being able to identify static methods properly, we + # just hope that that isn't something people are going to want + # to wrap, or if they do suggest they do it the correct way by + # ensuring that it is decorated in the class definition itself, + # or patch it in the __dict__ of the class type. + # + # So to get the best outcome we can, whenever we aren't sure what + # it is, we label it as a 'function'. If it was already bound and + # that is rebound later, we assume that it will be an instance + # method and try an cope with the possibility that the 'self' + # argument it being passed as an explicit argument and shuffle + # the arguments around to extract 'self' for use as the instance. + + if isinstance(wrapped, classmethod): + binding = 'classmethod' + + elif isinstance(wrapped, staticmethod): + binding = 'staticmethod' + + elif hasattr(wrapped, '__self__'): + if inspect.isclass(wrapped.__self__): + binding = 'classmethod' + else: + binding = 'function' + + else: + binding = 'function' + + super(FunctionWrapper, self).__init__(wrapped, None, wrapper, + enabled, binding) + +try: + if not os.environ.get('WRAPT_DISABLE_EXTENSIONS'): + from ._wrappers import (ObjectProxy, CallableObjectProxy, + PartialCallableObjectProxy, FunctionWrapper, + BoundFunctionWrapper, _FunctionWrapperBase) +except ImportError: + pass + +# Helper functions for applying wrappers to existing functions. + +def resolve_path(module, name): + if isinstance(module, string_types): + __import__(module) + module = sys.modules[module] + + parent = module + + path = name.split('.') + attribute = path[0] + + original = getattr(parent, attribute) + for attribute in path[1:]: + parent = original + + # We can't just always use getattr() because in doing + # that on a class it will cause binding to occur which + # will complicate things later and cause some things not + # to work. For the case of a class we therefore access + # the __dict__ directly. To cope though with the wrong + # class being given to us, or a method being moved into + # a base class, we need to walk the class hierarchy to + # work out exactly which __dict__ the method was defined + # in, as accessing it from __dict__ will fail if it was + # not actually on the class given. Fallback to using + # getattr() if we can't find it. If it truly doesn't + # exist, then that will fail. + + if inspect.isclass(original): + for cls in inspect.getmro(original): + if attribute in vars(cls): + original = vars(cls)[attribute] + break + else: + original = getattr(original, attribute) + + else: + original = getattr(original, attribute) + + return (parent, attribute, original) + +def apply_patch(parent, attribute, replacement): + setattr(parent, attribute, replacement) + +def wrap_object(module, name, factory, args=(), kwargs={}): + (parent, attribute, original) = resolve_path(module, name) + wrapper = factory(original, *args, **kwargs) + apply_patch(parent, attribute, wrapper) + return wrapper + +# Function for applying a proxy object to an attribute of a class +# instance. The wrapper works by defining an attribute of the same name +# on the class which is a descriptor and which intercepts access to the +# instance attribute. Note that this cannot be used on attributes which +# are themselves defined by a property object. + +class AttributeWrapper(object): + + def __init__(self, attribute, factory, args, kwargs): + self.attribute = attribute + self.factory = factory + self.args = args + self.kwargs = kwargs + + def __get__(self, instance, owner): + value = instance.__dict__[self.attribute] + return self.factory(value, *self.args, **self.kwargs) + + def __set__(self, instance, value): + instance.__dict__[self.attribute] = value + + def __delete__(self, instance): + del instance.__dict__[self.attribute] + +def wrap_object_attribute(module, name, factory, args=(), kwargs={}): + path, attribute = name.rsplit('.', 1) + parent = resolve_path(module, path)[2] + wrapper = AttributeWrapper(attribute, factory, args, kwargs) + apply_patch(parent, attribute, wrapper) + return wrapper + +# Functions for creating a simple decorator using a FunctionWrapper, +# plus short cut functions for applying wrappers to functions. These are +# for use when doing monkey patching. For a more featured way of +# creating decorators see the decorator decorator instead. + +def function_wrapper(wrapper): + def _wrapper(wrapped, instance, args, kwargs): + target_wrapped = args[0] + if instance is None: + target_wrapper = wrapper + elif inspect.isclass(instance): + target_wrapper = wrapper.__get__(None, instance) + else: + target_wrapper = wrapper.__get__(instance, type(instance)) + return FunctionWrapper(target_wrapped, target_wrapper) + return FunctionWrapper(wrapper, _wrapper) + +def wrap_function_wrapper(module, name, wrapper): + return wrap_object(module, name, FunctionWrapper, (wrapper,)) + +def patch_function_wrapper(module, name): + def _wrapper(wrapper): + return wrap_object(module, name, FunctionWrapper, (wrapper,)) + return _wrapper + +def transient_function_wrapper(module, name): + def _decorator(wrapper): + def _wrapper(wrapped, instance, args, kwargs): + target_wrapped = args[0] + if instance is None: + target_wrapper = wrapper + elif inspect.isclass(instance): + target_wrapper = wrapper.__get__(None, instance) + else: + target_wrapper = wrapper.__get__(instance, type(instance)) + def _execute(wrapped, instance, args, kwargs): + (parent, attribute, original) = resolve_path(module, name) + replacement = FunctionWrapper(original, target_wrapper) + setattr(parent, attribute, replacement) + try: + return wrapped(*args, **kwargs) + finally: + setattr(parent, attribute, original) + return FunctionWrapper(target_wrapped, _execute) + return FunctionWrapper(wrapper, _wrapper) + return _decorator + +# A weak function proxy. This will work on instance methods, class +# methods, static methods and regular functions. Special treatment is +# needed for the method types because the bound method is effectively a +# transient object and applying a weak reference to one will immediately +# result in it being destroyed and the weakref callback called. The weak +# reference is therefore applied to the instance the method is bound to +# and the original function. The function is then rebound at the point +# of a call via the weak function proxy. + +def _weak_function_proxy_callback(ref, proxy, callback): + if proxy._self_expired: + return + + proxy._self_expired = True + + # This could raise an exception. We let it propagate back and let + # the weakref.proxy() deal with it, at which point it generally + # prints out a short error message direct to stderr and keeps going. + + if callback is not None: + callback(proxy) + +class WeakFunctionProxy(ObjectProxy): + + __slots__ = ('_self_expired', '_self_instance') + + def __init__(self, wrapped, callback=None): + # We need to determine if the wrapped function is actually a + # bound method. In the case of a bound method, we need to keep a + # reference to the original unbound function and the instance. + # This is necessary because if we hold a reference to the bound + # function, it will be the only reference and given it is a + # temporary object, it will almost immediately expire and + # the weakref callback triggered. So what is done is that we + # hold a reference to the instance and unbound function and + # when called bind the function to the instance once again and + # then call it. Note that we avoid using a nested function for + # the callback here so as not to cause any odd reference cycles. + + _callback = callback and functools.partial( + _weak_function_proxy_callback, proxy=self, + callback=callback) + + self._self_expired = False + + if isinstance(wrapped, _FunctionWrapperBase): + self._self_instance = weakref.ref(wrapped._self_instance, + _callback) + + if wrapped._self_parent is not None: + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped._self_parent, _callback)) + + else: + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped, _callback)) + + return + + try: + self._self_instance = weakref.ref(wrapped.__self__, _callback) + + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped.__func__, _callback)) + + except AttributeError: + self._self_instance = None + + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped, _callback)) + + def __call__(self, *args, **kwargs): + # We perform a boolean check here on the instance and wrapped + # function as that will trigger the reference error prior to + # calling if the reference had expired. + + instance = self._self_instance and self._self_instance() + function = self.__wrapped__ and self.__wrapped__ + + # If the wrapped function was originally a bound function, for + # which we retained a reference to the instance and the unbound + # function we need to rebind the function and then call it. If + # not just called the wrapped function. + + if instance is None: + return self.__wrapped__(*args, **kwargs) + + return function.__get__(instance, type(instance))(*args, **kwargs) diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg new file mode 100644 index 0000000..9f5cf86 --- /dev/null +++ b/venv/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/local/bin +include-system-site-packages = false +version = 3.7.3